我是否必须使用-lgcc链接文件?

时间:2015-02-11 13:48:42

标签: c gcc osdev

如果你曾经将内核与gcc链接起来,你可能知道参数-lgcc。 这个参数重要吗?它有什么作用 ?

1 个答案:

答案 0 :(得分:1)

如果你做了一些驱动程序/内核开发,你可以使用-nostdlib从膨胀的stdlib中删除你的模块。但是,您还要删除GCC所具有的所有内部攻击,以便在整个硬件范围内保持一致的行为。

http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Link-Options.html

  

-nostdlib

     

链接时请勿使用标准系统启动文件或库。没有启动文件,只有您指定的库   传递给链接器,选项指定系统的链接   库,例如-static-libgcc或-shared-libgcc,将被忽略。   编译器可能会生成对memcmp,memset,memcpy和memmove的调用。   这些条目通常由libc中的条目解析。这些条目   这个点应该通过其他机制提供   选项已指定。

     

-nostdlib和-nodefaultlibs绕过的标准库之一是libgcc.a,它是一个内部子程序库,GCC用它来克服特定机器的缺点或特殊需求   对于某些语言。 (有关更多信息,请参阅与GCC输出的接口   关于libgcc.a的讨论。)在大多数情况下,即使在什么时候你也需要libgcc.a   你想避免使用其他标准库。换句话说,当你   指定-nostdlib或-nodefaultlibs通常应指定-lgcc   同样。这可确保您没有未解析的引用   内部GCC库子例程。 (例如,`__main',用于   确保将调用C ++构造函数;见collect2。)

https://gcc.gnu.org/onlinedocs/gcc-4.6.1/gccint/Interface.html#Interface

  

3与GCC输出的接口

     

GCC通常配置为使用相同的函数调用约定   通常在目标系统上使用。这是通过   所描述的机器描述宏(参见目标宏)。

     

但是,返回结构和联合值的方式不同   在一些目标机器上。结果,用PCC编译了函数   返回这样的类型不能从用GCC编译的代码中调用,并且   反之亦然。这不会造成麻烦,因为很少有Unix库   例程返回结构或联合。

     

GCC代码返回1,2,4或8字节的结构和联合   long在用于int或double返回值的相同寄存器中。 (GCC   通常也会在寄存器中分配这些类型的变量。)   其他尺寸的结构和结合通过存储进入返回   调用者传递的地址(通常在寄存器中)。目标   hook TARGET_STRUCT_VALUE_RTX告诉GCC在哪里传递这个地址。

     

相比之下,大多数目标机器上的PCC返回结构和联合   通过将数据复制到静态存储区域中的任何大小   然后返回该存储的地址,就像它是一个指针一样   值。调用者必须将该内存区域的数据复制到   想要价值的地方。这比使用的方法慢   海湾合作委员会,并且不能重新进入。

     

在某些目标计算机上,例如RISC计算机和80386,   标准系统约定是传递给子程序的地址   在哪里返回值。在这些机器上,已配置GCC   与此标准编译器兼容时,使用此方法。   它可能与1,2,4或8字节的结构不兼容。

     

GCC使用系统的标准约定来传递参数。上   一些机器,前几个参数在寄存器中传递;在   其他人都在堆栈上传递。可以使用   注册在任何机器上传递的参数,这很可能   导致显着的加速。但结果将是完整的   与遵循标准约定的代码不兼容。所以   只有当您转换为GCC作为唯一时,此更改才是实用的   系统的C编译器。我们可以实现寄存器参数传递   在某些机器上,一旦我们拥有一个完整的GNU系统,我们就可以   用GCC编译库。

     

在某些机器(特别是SPARC)上,某些类型的参数   通过“看不见的参考”传递。这意味着价值是   存储在内存中,并将内存位置的地址传递给   子程序。

     

如果您使用longjmp,请注意自动变量。 ISO C说   未声明为volatile的自动变量未定义   longjmp之后的值。这是海湾合作委员会所做的所有承诺,因为它   很难正确恢复寄存器变量,其中之一   GCC的特点是它可以将变量放在寄存器中而不需要你的   问它。