yongzhi 发表于 2008-01-18 11:32

求助,关于一个ld的问题

powerpc平台Linux (none) 2.6.18.8
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(void)
{
      void *handle;
      void (*errfcn)(const char *fmt, ...);
      const char *errmsg;
      FILE *pf;

      handle = dlopen("./liberr.so", RTLD_NOW);
      if(handle == NULL) {
                fprintf(stderr, "Failed to load liberr.so: %s\n", dlerror());
                exit(EXIT_FAILURE);
      }

      dlerror();
      errfcn = dlsym(handle, "err_ret");
      if((errmsg = dlerror()) != NULL) {
                fprintf(stderr, "Didn't find err_ret(): %s\n", errmsg);
                exit(EXIT_FAILURE);
      }
      if((pf = fopen("foobar", "r")) == NULL)
                errfcn("couldn't open foobar");

      dlclose(handle);
      return EXIT_SUCCESS;
}

ppc_85xx-gcc hello3.c -g-o hello3.exe-ldl

#include <stdio.h>
void err_ret(void* str)
{printf("%s\n", str);}

ppc_85xx-gcc -shared liberr.c -o liberr.so

直接运行hello3.exe,能正常运行
如果:
/lib/ld-2.3.5.so ./hello3.exe
则:
# /lib/ld-2.3.5.so ./hello3.exe
Failed to load liberr.so: ./liberr.so: R_PPC_REL24 relocation at 0x07fdf6e0 for symbol `puts' out of range

如果我这样生成库:
ppc_85xx-gcc -shared -fPIC liberr.c -o liberr.so
就都没有问题了

请问这两种方式有什么区别吗,为何加了-fPIC就出现这种情况呢?
谢谢

by325 发表于 2008-01-19 00:06

-fpic
如果支持这种目标机,编译器就生成位置无关目标码.适用于共享库(shared library).
-fPIC
如果支持这种目标机,编译器就输出位置无关目标码.适用于动态连接(dynamic linking),即使分支需要大范围转移

这是GCC手册上关于这两个参数的说明,具体我也不太清楚

dxcnjupt 发表于 2008-01-21 19:35

PIC代码的生成,貌似是gcc的问题而不是ld的问题

gcc manul上面有说
-fpic      If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC and 32k on the m68k and RS/6000. The 386 has no such limit.)

-fPIC       If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC. Position-independent code requires special support, and therefore works only on certain machines.

关键在于GOT全局偏移量表里面的跳转项大小。
intel处理器应该是统一4字节,没有问题。
powerpc上由于汇编码或者机器码的特殊要求,所以跳转项分为短、长两种。

-fpic为了节约内存,在GOT里面预留了“短”长度。
而-fPIC则采用了更大的跳转项。

具体什么情况我也不了解了。
不知道楼主懂不懂powerpc的汇编,讲解一下powerpc的跳转指令??

jameszxj 发表于 2008-01-24 20:58

楼上正解,楼主的跳转已经超过了32M
加个-mlongcall 编译一下应该可以
页: [1]
查看完整版本: 求助,关于一个ld的问题