GCC:如何告诉GCC放置';主要';函数在.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

我刚刚开始学习一些ARM编程,我遇到了一个稍微令人讨厌的问题。我用来编译源代码的工具链是Sourcery CodeBench Lite 2013.05-23(可以在这里找到:)

我需要的是告诉GCC、LD或OBJCOPY将“main”函数的编译字节码放在.text节的开头

有没有办法做到这一点?(可能通过链接器脚本?)


谢谢

解决了这个问题。无论谁面对它:

  • 使用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 reject
void main()
现在处于默认托管模式。我仍然认为这是一个很好的编辑,尽管这个问题很可能是关于独立代码的。虽然这会起作用,但向所有其他函数添加一个节远不是最简单的方法-请参阅接受的答案,以获得更简单的解决方案。您还可以使用:“int main”(int argc,char**argv)uuu属性(section(“.text.main”));”并将其余部分保留在默认部分。