GCC:如何告诉GCC放置';主要';函数在.text部分的开头?
我刚刚开始学习一些ARM编程,我遇到了一个稍微令人讨厌的问题。我用来编译源代码的工具链是Sourcery CodeBench Lite 2013.05-23(可以在这里找到:) 我需要的是告诉GCC、LD或OBJCOPY将“main”函数的编译字节码放在.text节的开头 有没有办法做到这一点?(可能通过链接器脚本?)GCC:如何告诉GCC放置';主要';函数在.text部分的开头?,gcc,main,ld,linker-scripts,objcopy,Gcc,Main,Ld,Linker Scripts,Objcopy,我刚刚开始学习一些ARM编程,我遇到了一个稍微令人讨厌的问题。我用来编译源代码的工具链是Sourcery CodeBench Lite 2013.05-23(可以在这里找到:) 我需要的是告诉GCC、LD或OBJCOPY将“main”函数的编译字节码放在.text节的开头 有没有办法做到这一点?(可能通过链接器脚本?) 谢谢解决了这个问题。无论谁面对它: 使用GCC编译时,在命令行中添加-ffunction sections选项。这将告诉GCC将每个函数放在一个单独的部分中。节名的格式将为.t
谢谢解决了这个问题。无论谁面对它:
- 使用GCC编译时,在命令行中添加-ffunction sections选项。这将告诉GCC将每个函数放在一个单独的部分中。节名的格式将为.text.#函数名#,不带#(即,如果函数属于.text节[默认情况下为true])
- 其次,使用链接器脚本将这些“函数部分”排序到最后的大文本部分。例如,将main函数放在.text部分的开头,将生成一个大致如下所示的LD脚本:
ENTRY(main) SECTIONS { .text : { *(.text.main); *(.text*); } }
\uuuu属性将“main”放在自己的部分中:
int main (void) __attribute__ ((section ("entry")));
然后在ld文件中:
ENTRY(main)
SECTIONS
{
.text :
{
*(main)
*(.text)
}
}
还有很多其他有趣的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu属性,请在此处阅读更多有关它们的信息:首先,通过将.text部分称为:
gcc -Wl,-verbose
这将打印出默认的链接器脚本。我的在.text部分显示了这一点:
/* text: Program code section */
.text :
{
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
}
因此,为了使“main”函数成为.text部分的第一个函数(其余函数是连续的),您必须为所有其他函数设置“section”属性。例如:
void main(void);
void funct1(....) __attribute__ ((section (".text.A")));
void funct2(....) __attribute__ ((section (".text.A")));
void funct3(....) __attribute__ ((section (".text.A")));
对函数原型进行“归因”就足够了。这样,当您现在编译时,“main”函数将是“.text”部分中的第一个函数,所有其他函数将紧跟在紧接着的连续地址之后
如果要将“.text”部分(即“main”函数)放置在特定地址(例如0x1000),请记住链接:
gcc .... -Wl,-Ttext=0x1000
main
的正确返回类型是int
,而不是void
。(void main(void)
可能是某些编译器允许的;int main(void)
对于托管实现是通用的。)只是使用\uuuu属性的一个示例-不知道他的main看起来是什么样子:),那么您应该为main
选择两个有效签名之一。clang拒绝编译void main()
@PeterCordes:这不是仅有的两个有效签名。如果有人在独立(非托管)环境中构建(这可能是这个问题的情况-很清楚)。如果使用-ffreestanding
@MichaelPetch:oh,我希望CLANG会允许它编译。是的,gcc和clang就是这样。(结果是gcc和clang rejectvoid main()
现在处于默认托管模式。我仍然认为这是一个很好的编辑,尽管这个问题很可能是关于独立代码的。虽然这会起作用,但向所有其他函数添加一个节远不是最简单的方法-请参阅接受的答案,以获得更简单的解决方案。您还可以使用:“int main”(int argc,char**argv)uuu属性(section(“.text.main”));”并将其余部分保留在默认部分。