Assembly 获取链接器脚本中的节长度

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

我有一个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); }" > $@
    ...

$(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工具,检查编译后的二进制文件,手动计算段长度并修复偏移量(如果找不到解决此问题的方法,我可能会这样做),但这看起来非常混乱,不是一个干净的解决方案。。。