同时使用objcopy的--rename-section与--add-symbol是否合法?llvm-objcopy是否异常?
关于objcopy节重命名与符号添加的问题
问题描述
我使用以下命令将二进制文件data.file转换为ELF文件elf.o:
echo 'SOME_DATA' > data.file \ && objcopy \ --input-target binary \ --output-target=elf64-x86-64 \ --rename-section .data=.my_data_section \ --add-symbol DATA_SECTION_START=.my_data_section:0 \ data.file \ elf.o \ && readelf -a elf.o
该命令先创建.data节并将其重命名为.my_data_section,同时添加指向.my_data_section起始位置的符号DATA_SECTION_START。现有两个疑问:
- 同时执行节重命名、添加符号并使用新节名的操作是否合法?
- 发现llvm-objcopy生成的
DATA_SECTION_START符号的Ndx为ABS(异常),而GCC的objcopy无此问题,能否判定llvm-objcopy的行为存在错误?
llvm-objcopy输出
Section Headers: [Nr] Name Type Address Offset ... [ 1] .my_data_section PROGBITS 0000000000000000 00000040 ... Symbol table '.symtab' contains 6 entries: Num: Value Size Type Bind Vis Ndx Name ... 5: 000000000000000a 0 NOTYPE GLOBAL DEFAULT ABS DATA_SECTION_START
GNU objcopy输出
Section Headers: [Nr] Name Type Address Offset ... [ 1] .my_data_section PROGBITS 0000000000000000 00000040 ... Symbol table '.symtab' contains 6 entries: Num: Value Size Type Bind Vis Ndx Name ... 5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 DATA_SECTION_START
回答
1. 操作合法性
这种同时执行节重命名和添加符号引用新节名的操作是合法的。objcopy的实际处理流程为:先完成二进制到ELF的转换(生成默认.data节),再执行节重命名,最后处理符号添加。此时.my_data_section已经存在,引用该节名添加符号符合逻辑,GNU objcopy的正确行为也验证了这一点。
2. llvm-objcopy的行为判定
可以认为llvm-objcopy的这个行为是不符合预期的错误:
Ndx为ABS表示符号是绝对地址符号,不关联任何节,但我们的需求是让符号关联到.my_data_section(对应GNU输出中的Ndx=1,即节的索引),这与预期不符。- llvm-objcopy生成的符号值
000000000000000a也不正确,应该是节的起始地址0,说明它没有正确解析.my_data_section的位置,错误地将符号处理为绝对地址。 - 这种差异是llvm-objcopy在命令参数处理顺序或节符号关联逻辑上的bug,因为GNU objcopy的行为符合用户预期,也契合objcopy命令参数的设计意图。
内容的提问来源于stack exchange,提问作者lol lol
相关产品推荐
相关产品推荐

