我注意到llvm.read_register()
可以读取堆栈指针的值,而llvm.write_register()
可以设置堆栈指针的值。我将主函数添加到stackpointer.ll
,可以在llvm src中找到:
;stackpointer.ll
define i32 @get_stack() nounwind {
%sp = call i32 @llvm.read_register.i32(metadata !0)
ret i32 %sp
}
declare i32 @llvm.read_register.i32(metadata) nounwind
!0 = metadata !{metadata !"sp\00"}
define i32 @main() {
%1 = call i32 @get_stack()
ret i32 %1
}
我在运行ubuntu 11.04的armv7板上测试过:
lli stackpointer.ll
然后,我得到一个堆栈转储:
ARMCodeEmitter::emitPseudoInstruction
UNREACHABLE executed at ARMCodeEmitter.cpp:847!
Stack dump:
0. Program arguments: lli stackpointer.ll
1. Running pass 'ARM Machine Code Emitter' on function '@main'
Aborted
我也试过了公司:
llc stackpointer.ll -o stackpointer.s
错误消息:
Can't get register for value!
UNREACHABLE executed at ARMCodeEmitter.cpp:1183!
Stack dump:
0. Program arguments: llc stackpointer.ll -o stackpointer.s
1. Running pass 'Function Pass Manager' on moulude 'stackpointer.ll'
2. Running pass 'ARM Instruction Selection' on function '@get_stack'
Aborted
我也在x86-64平台上试过,它没用。使用这些内在函数的正确方法是什么?
答案 0 :(得分:0)
我的lli不喜欢你的元数据定义。
我知道了你的
!0 = metadata !{metadata !"sp\00"}
到
!0 = !{!"sp\00"}
它有效。 (好吧,因为我在x86-64上,我在i32到i64和sp到rsp的所有地方也都改变了。)
另外,格式化中存在错误的空白符号,但我认为这可能是由于StackOverflow / html或其他原因造成的。