[英]llvm naming policy for llvm-IR variables and assembler symbols
正如我所见,llvm 支持以空字符结尾的字符串,包括任何字符(0x01 到 0xff)作为 llvm-IR 变量和汇编器符号的有效名称。 在我看来,这样的决定可能会导致一些问题。
"AB"
是一个带有空格字符的名称。 从逻辑上讲,期望在特殊字符编码中使用类似 printf 的风格是合乎逻辑的。 我的意思是"\\n"
、 "\\t"
、 "\\xAB"
,但是 llvm-IR 和汇编程序不支持这种名称样式(但 llvm 支持 \\KL 用于初始值设定项)。"A\\n"
产生的不是"A"
和newline character
而是包含对象精灵文件中所有 3 个字节的名称"A\\n"
和"A\\\\n"
为 llvm 生成相同的名称(因此,即使 llvm 似乎也不以任何适当的方式支持特殊命名。)
@"A\n" = internal constant i32 1
@"A\\n" = internal constant i32 2
$ clang-9 test.ll -S
test.ll:3:1: error: redefinition of global '@A\n'
@"A\\n" = internal constant i32 2
@GOTOFF
或@plt
什么? 如何区分包括@GOTOFF
在内的@GOTOFF
与汇编@GOTOFF
定位规范? 为什么"AB@GOTOFF"
可以拼装,但"AB"@GOTOFF
不起作用?
Bug https://sourceware.org/bugzilla/show_bug.cgi?id=18581于 2015 年开放,但即使现在 gas 也不支持名称中的某些字符,而 llvm 支持。 例如"A,B"
和"A\\B"
不能通过气体组装。 所以llvm创建了汇编方言,不能通过gas进行汇编。
编程语言(C/C++、Rust、Go、Python、Java 等)在标识符中仅支持letters
、 digits
、 '_'
、 '$'
字符。 前端也使用'.'
, '$'
, '#'
字符,但它们以任何方式生成在汇编程序中有效的名称(没有任何双引号转义)。
可能只有 llvm 优化会生成带有特殊字符的名称。 但是这些名称仅为具有内部(C 术语中的静态)链接的全局变量创建。 那么为什么不为这样的全局变量使用像"__llvm_internal_global_Id_*"
这样的特殊模式(某些名称在所有情况下都是保留的)?
那么使用这种命名策略的原因是什么? 使用一组小而简单的有效字符进行命名是否更好?
我将尝试总结中期结果。
llvm 支持 llvm-IR 变量名称和 asm 符号名称作为任何字符的序列。 总的来说,它看起来是一个很好的解决方案。
但是当前的实现有一些特殊的时刻。
Llvm-parser 可以与 llvm-IR 一起使用,其中字符串初始值设定项和全局变量的名称都包含转义序列(使用“\\AB”模式,其中 0xAB 是十六进制代码)。 但是在汇编语言中,转义序列不使用或/和不起作用(还有 readelf、objdump、gdb 等)。 这一事实给文本编辑器的使用带来了问题。
汇编语言在符号名称后使用特殊的重定位@GOTOFF
,如@plt
、 @GOTOFF
等。 因此,现在当符号名称(双引号中)包含像"@plt"
这样的子字符串时,就会发生冲突。 我为汇编程序 lexic-parser 提出了一个简单的规则
A@plt - symbol with name 'A' and plt-relocation
"A@plt" - symbol with name 'A@plt'
"A@plt"@plt - symbol with name 'A@plt' and plt-relocation
(所以双引号中的所有内容都是名称的一部分,双引号之后或符号名称末尾的所有内容都是重定位修饰符)。
","
或"\\"
。 因此,gas 中的有效符号名称集少于 llvm-as。我希望这些时刻能在 llvm 和 gas 中得到修复(如果这是对当前情况的正确描述)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.