你能否在ld脚本中添加两个SECTION段落?

4

我有一个可执行文件,通过链接几个.o文件制作而成,并使用了复杂的链接脚本。如果设置了特定的环境标志,我希望会涉及另一个部分。因此,类似以下这样:

/* withfoo.ld */
SECTIONS {
 .foo 0x80000000 : {
    _start_foo = .;
    . += 0xfff;
    _end_foo = .;
 }
}

然后使用以下命令进行编译:

if [ $FOO_DEFINED ]; then
    gcc -Wl,-T normal.ld $(OBJS) foo.o foo.ld
else
    gcc -Wl,-T normal.ld $(OBJS)
fi

我希望不需要修改normal.ld文件。 normal.ld文件中有一个SECTIONS定义,这给了我两个SECTIONS…… 我收到了警告:

/usr/bin/ld: warning: foo.ld contains output sections; did you forget -T?

这是实际的问题还是仅仅是一个警告?此外,我是否不知道正确的做法呢?
1个回答

3

GNU链接脚本和LD不支持条件编译。您不能同时使用两个链接器脚本并使其按预期工作。您需要使用其他类型的宏语言(如m4)对链接器脚本进行预处理,甚至可以只使用GNU C预处理器cpp


不确定这是否是您正在寻找的解决方案。 C预处理器cpp可以处理任何类型文件的文本(甚至非C文件),并会盲目地解析预处理器指令和宏,就像处理C文件一样。您也可以通过cpp命令行传递C风格的定义,就像使用GCC一样。您可以创建一个包含所有C预处理器指令的链接脚本,并基于此生成特定的链接脚本。例如,创建以下特殊的链接脚本:

linker.ld.pp

SECTIONS {
#ifdef FOO
 .foo 0x80000000 : {
    _start_foo = .;
    . += 0xfff;
    _end_foo = .;
 }
#endif
}

这个使用了典型的C语言风格的#if/#ifdef/#endif来进行条件编译。如果你通过类似下面的命令将它运行在C预处理器中:

cpp -P -DFOO linker.ld.pp

你将会得到如下输出:
SECTIONS {
 .foo 0x80000000 : {
    _start_foo = .;
    . += 0xfff;
    _end_foo = .;
 }
}

如果不定义FOO,可以这样做:

cpp -P linker.ld.pp

输出结果将会是:
SECTIONS {
}

要重定向预处理器,您可以使用以下方法将输出输出到链接器脚本中:

cpp -P -DFOO linker.ld.pp >withfoo.ld
cpp -P linker.ld.pp >withoutfoo.ld

你可以在CPP命令行上指定多个-D指令来定义多个预处理器符号。这种方法的想法是,你只有一个链接脚本,但你创建一个shell脚本来生成所需的特殊脚本。

其他注意事项

通常,你可以使用-T选项在GCC命令行上指定链接脚本:
gcc -T withfoo.ld $(OBJS) foo.o

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接