我有一个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;
...
)
然后将实际代码放在ELF文件的文本部分中(参见mod.text.o.inc的规则),将告诉链接器将其加载到我输入的地址(mod.text.elf的规则) .ld.inc),将加载地址,大小,文件地址添加到ELF(mod.data.o.inc)的数据部分,mod.elf.ld.inc负责确定代码的大小。
“数据”部分的输出基本上如下所示:
.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
我现在正在尝试修改这个"构建环境"所以我有另一个命令" 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); }" > $@
$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(测试,0x80001000,nop;)然后调用DMOD(test2,nop;),我想将地址0x80001004写入ELF数据部分。相反,代码I(尝试)写入而不是写入ELF数据部分长度。
如果我的解释很糟糕,我很抱歉 - 英语不是我的母语,构建环境还没有由我编写(因此我并不完全知道所有内容是什么)而且我没有&#39 ; t对链接器的工作方式有很多经验。
我可以给a link to the build environment / code但是这个系统/软件非常具体,所以我不知道这是否有用。