Assembly 获取链接器脚本中的节长度
我有一个makefile,它将汇编程序中编写的模块编译成一个二进制文件,由另一个软件加载。makefile的有趣部分如下所示:Assembly 获取链接器脚本中的节长度,assembly,ld,powerpc,Assembly,Ld,Powerpc,我有一个makefile,它将汇编程序中编写的模块编译成一个二进制文件,由另一个软件加载。makefile的有趣部分如下所示: $(BUILD_ALL)/mod.elf.ld.inc: $(LOG) $Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" &g
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
...
$(BUILD_ALL)/mod.data.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .int addr; .int id ## _start; .int id ## _size; .int 0; " > $@
...
$(BUILD_ALL)/mod.text.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .text.id addr : { *(.text.id); } " > $@
...
$(BUILD_ALL)/mod.text.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .section .text.id; __VA_ARGS__" > $@
...
MOD(unique-id, 0x80001234,
li r3, 0;
li r4, 0;
...
)
.int 0x80001234
.int unique-id_start
.int unique-id_size
.int 0
.int 0x80003864
.int mod1_start
.int mod1_size
.int 0
.int 0x80003ea4
.int mod2_start
.int mod2_size
.int 0
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
$Qecho "#define IMOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = addr + SIZEOF(.rodata.id); }" >> $@
$Qecho "#define DMOD(id, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = last_size + SIZEOF(.rodata.id); }" >> $@
...
这样做的目的是让我定义一个如下所示的模块:
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
...
$(BUILD_ALL)/mod.data.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .int addr; .int id ## _start; .int id ## _size; .int 0; " > $@
...
$(BUILD_ALL)/mod.text.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .text.id addr : { *(.text.id); } " > $@
...
$(BUILD_ALL)/mod.text.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .section .text.id; __VA_ARGS__" > $@
...
MOD(unique-id, 0x80001234,
li r3, 0;
li r4, 0;
...
)
.int 0x80001234
.int unique-id_start
.int unique-id_size
.int 0
.int 0x80003864
.int mod1_start
.int mod1_size
.int 0
.int 0x80003ea4
.int mod2_start
.int mod2_size
.int 0
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
$Qecho "#define IMOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = addr + SIZEOF(.rodata.id); }" >> $@
$Qecho "#define DMOD(id, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = last_size + SIZEOF(.rodata.id); }" >> $@
...
然后将实际代码放入ELF文件的文本部分(参见mod.text.o.inc的规则),将告诉链接器将其加载到我输入的地址(mod.text.ELF.ld.inc的规则),将加载地址、大小、文件地址添加到ELF的数据部分(mod.data.o.inc),mod.elf.ld.inc负责确定代码的大小
数据部分的输出基本上如下所示:
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
...
$(BUILD_ALL)/mod.data.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .int addr; .int id ## _start; .int id ## _size; .int 0; " > $@
...
$(BUILD_ALL)/mod.text.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .text.id addr : { *(.text.id); } " > $@
...
$(BUILD_ALL)/mod.text.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .section .text.id; __VA_ARGS__" > $@
...
MOD(unique-id, 0x80001234,
li r3, 0;
li r4, 0;
...
)
.int 0x80001234
.int unique-id_start
.int unique-id_size
.int 0
.int 0x80003864
.int mod1_start
.int mod1_size
.int 0
.int 0x80003ea4
.int mod2_start
.int mod2_size
.int 0
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
$Qecho "#define IMOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = addr + SIZEOF(.rodata.id); }" >> $@
$Qecho "#define DMOD(id, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = last_size + SIZEOF(.rodata.id); }" >> $@
...
我现在正试图修改这个“构建环境”,因此我有另一个命令“IMOD”,我可以使用它“设置”目标地址,并使编译器将任何其他“DMOD”赋值放在我需要输入的地址(如我的示例中的0x80001234)之外,而是自动放在末尾
我试着像这样将MOD复制到IMOD和DMOD:
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
...
$(BUILD_ALL)/mod.data.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .int addr; .int id ## _start; .int id ## _size; .int 0; " > $@
...
$(BUILD_ALL)/mod.text.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .text.id addr : { *(.text.id); } " > $@
...
$(BUILD_ALL)/mod.text.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .section .text.id; __VA_ARGS__" > $@
...
MOD(unique-id, 0x80001234,
li r3, 0;
li r4, 0;
...
)
.int 0x80001234
.int unique-id_start
.int unique-id_size
.int 0
.int 0x80003864
.int mod1_start
.int mod1_size
.int 0
.int 0x80003ea4
.int mod2_start
.int mod2_size
.int 0
$(BUILD_ALL)/mod.elf.ld.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); }" > $@
$Qecho "#define IMOD(id, addr, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = addr + SIZEOF(.rodata.id); }" >> $@
$Qecho "#define DMOD(id, ...) . = ALIGN(4); .rodata.id : { id ## _start = .; *(.text.id); id ## _size = ABSOLUTE(. - id ## _start); last_size = last_size + SIZEOF(.rodata.id); }" >> $@
...
因此,它将节大小添加到计数器,然后添加以下内容:
$(BUILD_ALL)/mod.data.o.inc:
$(LOG)
$Qecho "#define MOD(id, addr, ...) .int addr; .int id ## _start; .int id ## _size; .int 0; " > $@
$Qecho "#define IMOD(id, addr, ...) .int addr; .int id ## _start; .int id ## _size; .int 0; " > $@
$Qecho "#define DMOD(id, ...) .int last_size; .int id ## _start; .int id ## _size; .int 0; " > $@
...
但是,结果部分(由mod.data.o.inc生成)没有“.int last_size”的递增地址,甚至没有错误的地址,而是整个ELF数据部分的(部分)长度,而不仅仅是我想要的一个部分
基本上,如果我调用IMOD(test,0x80001000,nop;),然后调用DMOD(test2,nop;),我希望将地址0x80001004写入ELF数据段。相反,我(试图)编写的代码改为写入ELF数据段长度
我很抱歉,如果我的解释是狗屎-英语不是我的母语,构建环境不是我写的(所以我不知道所有的东西都是做什么的),而且我对链接器的工作方式没有太多经验
我可以给出,但这是非常具体的系统/软件,所以我不知道这是否有用 anywa中不需要两个链接器兼容,你是说gnu的链接器ld吗?对不起,我忘了。是的,我正在使用GNU ld powerpc eabi ld 2.27。它可能对您没有多大帮助,因为您似乎正在使用现有的设置,但我只会使用
objcopy
的现有功能来嵌入文件。如果可能的话,我会尽量避免使用链接器脚本。如果我是从头开始写的/会从头开始写的,我也不会使用这些脚本。但是如果可能的话,我想使用现有的设置。我可以编写一个小型的C工具来检查编译后的二进制文件,手动累加部分长度并修复偏移量(如果我找不到这个问题的解决方案,我可能会这么做),但这看起来很混乱,不是一个干净的解决方案…在anywa中没有两个链接器是兼容的,你是说gnu的链接器ld吗?对不起,我忘了。是的,我正在使用GNU ld powerpc eabi ld 2.27。它可能对您没有多大帮助,因为您似乎正在使用现有的设置,但我只会使用objcopy
的现有功能来嵌入文件。如果可能的话,我会尽量避免使用链接器脚本。如果我是从头开始写的/会从头开始写的,我也不会使用这些脚本。但如果可能的话,我想使用现有的设置。我可以编写一个小型C工具,检查编译后的二进制文件,手动计算段长度并修复偏移量(如果找不到解决此问题的方法,我可能会这样做),但这看起来非常混乱,不是一个干净的解决方案。。。