这是gcc错误吗?

时间:2018-11-29 10:50:38

标签: c gcc linker

基本上,我已经发布了一些有关我的问题的问题。但是,我确实相信这是一个不同的问题。

简单来说,带有某些buildmode选项集的Go工具会创建一个非PIC .o文件(例如app.o)和一个PIC共享库(例如libmain.so)。顾名思义,libmain.so的内部确实具有THE main函数。

然后,Go工具调用编译器驱动程序gcc来链接.o和.so以创建可执行文件,而不一定是PIE。为简化起见,Go工具调用的链接器命令如下:

$ gcc -o app.x -L. -lmain -Wl,-rpath=$PWD -fuse-ld=gold app.o

问题是这个。至少三位专家确认,必须使用Scrt1.o链接它们,因为main位于PIC共享库中。但是,gcc会撤出crt1.o。

我的问题是这是gcc错误还是用户的错误。当然,如果用户在上面的链接命令中添加了“ -pie”选项,则gcc将改用Scrt1.o。但是,用户可能会声称,由于他们可能不需要位置独立的可执行文件,因此添加“ -pie”可能没有太大意义。

我试图在gcc手册中找到适当的信息,但未成功。在这种情况下,用户应该指定“ -pie”吗?或者,是否允许用户制作非PIE可执行文件,以便此问题是gcc错误?

为方便起见,这是一个简单的示例:

$ cat app.c 
int foo(int x, int y)
{
  volatile int z = x;
  return z + y;
}
$ cat main.c 
extern int foo(int, int);
int main(int argc, char* argv[])
{
  return foo(argc, 4);
}
$ gcc -o app.o -c app.c
$ gcc -o main.o -c -fPIC main.c
$ gcc -o libmain.so -shared main.o
$ gcc -o app.x -L. -lmain -fuse-ld=gold -Wl,-v,-rpath=$PWD app.o
collect2 version 4.8.5 20150623 (Red Hat 4.8.5-36.0.2)
/usr/bin/ld.gold --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -dynamic-linker /lib/ld-linux-aarch64.so.1 -X -o app.x /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtbegin.o -L. -L/usr/lib/gcc/aarch64-redhat-linux/4.8.5 -L/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../.. -lmain -v -rpath=/home/aion1223/workspace/shared app.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crtn.o
GNU gold (version 2.27-34.base.0.2.el7) 1.12

1 个答案:

答案 0 :(得分:0)

此问题已在此处讨论:

the gcc bug report

我想gcc很清楚,给crt1.o是正确的行为,因为最终的可执行文件是非PIE。似乎根据最终的可执行文件选择crt1.o。

Andrew Pinski's comment 18

根据评论,gcc这样做是为了给crt1.o。因此,这不是gcc错误。然后,这应该是黄金问题或glibc问题。