interp: ignore inline assembly in markExternal
The markExternal function is used when a global (function or global variable) is somehow run at runtime. All the other globals it refers to are from then on no longer known at compile time, so can't be used by the interp package anymore. This can also include inline assembly. While it is possible to modify globals that way, it is only possible to modify exported globals: similar to calling an undefined function (in C for example).
Этот коммит содержится в:
родитель
841f19f49e
коммит
95e4dcfb53
3 изменённых файлов: 22 добавлений и 0 удалений
|
@ -178,6 +178,9 @@ func (mv *memoryView) markExternal(llvmValue llvm.Value, mark uint8) {
|
|||
default:
|
||||
panic("interp: unknown constant expression")
|
||||
}
|
||||
} else if !llvmValue.IsAInlineAsm().IsNil() {
|
||||
// Inline assembly can modify globals but only exported globals. Let's
|
||||
// hope the author knows what they're doing.
|
||||
} else {
|
||||
llvmType := llvmValue.Type()
|
||||
switch llvmType.TypeKind() {
|
||||
|
|
12
interp/testdata/basic.ll
предоставленный
12
interp/testdata/basic.ll
предоставленный
|
@ -66,6 +66,9 @@ entry:
|
|||
call void @modifyExternal(i32* bitcast (void ()* @willModifyGlobal to i32*))
|
||||
store i16 7, i16* @main.exposedValue2
|
||||
|
||||
; Test that inline assembly is ignored.
|
||||
call void @modifyExternal(i32* bitcast (void ()* @hasInlineAsm to i32*))
|
||||
|
||||
; Test switch statement.
|
||||
%switch1 = call i64 @testSwitch(i64 1) ; 1 returns 6
|
||||
%switch2 = call i64 @testSwitch(i64 9) ; 9 returns the default value -1
|
||||
|
@ -102,6 +105,15 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
; Inline assembly should be ignored in the interp package. While it is possible
|
||||
; to modify other globals that way, usually that's not the case and there is no
|
||||
; real way to check.
|
||||
define void @hasInlineAsm() {
|
||||
entry:
|
||||
call void asm sideeffect "", ""()
|
||||
ret void
|
||||
}
|
||||
|
||||
define i64 @testSwitch(i64 %val) {
|
||||
entry:
|
||||
; Test switch statement.
|
||||
|
|
7
interp/testdata/basic.out.ll
предоставленный
7
interp/testdata/basic.out.ll
предоставленный
|
@ -26,6 +26,7 @@ entry:
|
|||
store i16 5, i16* @main.exposedValue1
|
||||
call void @modifyExternal(i32* bitcast (void ()* @willModifyGlobal to i32*))
|
||||
store i16 7, i16* @main.exposedValue2
|
||||
call void @modifyExternal(i32* bitcast (void ()* @hasInlineAsm to i32*))
|
||||
call void @runtime.printint64(i64 6)
|
||||
call void @runtime.printint64(i64 -1)
|
||||
%agg = call { i8, i32, { float, { i64, i16 } } } @nestedStruct()
|
||||
|
@ -59,6 +60,12 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
define void @hasInlineAsm() {
|
||||
entry:
|
||||
call void asm sideeffect "", ""()
|
||||
ret void
|
||||
}
|
||||
|
||||
define i64 @testSwitch(i64 %val) local_unnamed_addr {
|
||||
entry:
|
||||
switch i64 %val, label %otherwise [
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче