Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 共享库中的重定位项_Linux_Assembly_Linker_Elf_Relocation - Fatal编程技术网

Linux 共享库中的重定位项

Linux 共享库中的重定位项,linux,assembly,linker,elf,relocation,Linux,Assembly,Linker,Elf,Relocation,我正在调查共享库的迁移,遇到了一些奇怪的事情。考虑这个代码: int myglob; int ml_util_func(int p) { return p + 2; } int ml_func2(int a, int b) { int c = ml_util_func(a); return c + b + myglob; } 我用gcc-shared将它编译成一个非PIC共享库。我在x86上运行的32位Ubuntu上执行此操作 由此产生的.so在ml\u func2

我正在调查共享库的迁移,遇到了一些奇怪的事情。考虑这个代码:

int myglob;

int ml_util_func(int p)
{
    return p + 2;
}

int ml_func2(int a, int b)
{
    int c = ml_util_func(a);
    return c + b + myglob;
}
我用
gcc-shared
将它编译成一个非PIC共享库。我在x86上运行的32位Ubuntu上执行此操作

由此产生的
.so
ml\u func2
中为调用
ml\u util\u func
提供了一个重定位条目。下面是
ml_func2
上的
objdump-dR-Mintel
的输出:

0000050d <ml_func2>:
 50d:   55                      push   ebp
 50e:   89 e5                   mov    ebp,esp
 510:   83 ec 14                sub    esp,0x14
 513:   8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
 516:   89 04 24                mov    DWORD PTR [esp],eax
 519:   e8 fc ff ff ff          call   51a <ml_func2+0xd>
                        51a: R_386_PC32 ml_util_func
 51e:   89 45 fc                mov    DWORD PTR [ebp-0x4],eax
 521:   8b 45 0c                mov    eax,DWORD PTR [ebp+0xc]
 524:   8b 55 fc                mov    edx,DWORD PTR [ebp-0x4]
 527:   01 c2                   add    edx,eax
 529:   a1 00 00 00 00          mov    eax,ds:0x0
                        52a: R_386_32   myglob
 52e:   8d 04 02                lea    eax,[edx+eax*1]
 531:   c9                      leave  
 532:   c3                      ret    
 533:   90                      nop
0000050d:
50d:55推式ebp
50e:89 e5 mov ebp,esp
510:83 ec 14子esp,0x14
513:8b 45 08 mov eax,DWORD PTR[ebp+0x8]
516:89 04 24 mov DWORD PTR[esp],eax
519:e8 fc ff呼叫51a
51a:R_386_PC32 ml_util_func
51e:89 45 fc mov DWORD PTR[ebp-0x4],eax
521:8b 45 0c mov eax,DWORD PTR[ebp+0xc]
524:8b 55 fc mov edx,DWORD PTR[ebp-0x4]
527:01 c2添加edx、eax
529:a1 00 mov eax,ds:0x0
52a:R_386_32 myglob
52e:8d 04 02 lea eax[edx+eax*1]
531:c9离开
532:c3 ret
533:90不
注意
call
指令中的
R\u 386\u PC32
重新定位

现在,我的问题是,为什么需要搬迁
e8
在x86上是“相对调用…”,而且由于
ml_util_func
是在同一个对象中定义的,链接器肯定可以计算它与调用之间的相对偏移量,而不必将它留给动态加载程序

有趣的是,如果
ml_util_func
声明为
static
,则重新定位将消失,链接器将正确计算并插入偏移量。同样导出的
ml\u util\u func
是什么让链接器懒惰的


注意:我故意玩非PIC代码,以了解加载时间重新定位。

找不到原因,但这是binutils对此的评论:

binutils-2.11.90-20010705-src.tar.gz/bfd/elf32-i386.c:679

      /* If we are creating a shared library, and this is a reloc
         against a global symbol, or a non PC relative reloc
         against a local symbol, then we need to copy the reloc
         into the shared library.  However, if we are linking with
         -Bsymbolic, we do not need to copy a reloc against a
         global symbol which is defined in an object we are
我认为,这种重新定位允许用户重载库中的任何全局符号。而且,似乎
-Bsymbolic
禁用了此功能,并且不会从库本身为符号生成重定位

-b符号的 此选项将导致输出中的所有符号引用都被删除 已在此链接编辑会话中解析。剩下的唯一运行时 重新安置要求是基础相对重新安置,即。 相对于加载地址的转换。未能解决 任何符号引用都会导致报告错误

关于各种-B模式和限制(C++)的详细描述如下:

-捆绑


请注意,对象不一定是整体链接的块。有几种方法可以将符号放在单独的部分中,这些部分可以放在final.exe中,具体取决于代码是否引用了它。(搜索-gc节链接器选项和相关节生成gcc选项)


当没有使用节时,这可能根本不是微优化。

为什么要编译
。所以没有-fPIC的
。@osgx:因为,正如我的问题在第一句话中所述,我对加载时重新定位特别感兴趣。我现在添加了一个P.S.来澄清你能用另一个库(LD_PRELOAD)在一个库中重载全局符号吗?Eli,还有一个地方可以精确控制任何符号的绑定顺序。有趣的是,还有这个页面:它解释了Bsymbolic。我将对此进行研究,感谢您的建议。我认为Bsymbolic只是一个相关的标志,这里真正的问题是符号的搜索顺序——首先是在可执行文件中,然后是共享库,以及使用此搜索顺序覆盖全局符号的能力。LD_预加载是另一种方式。
           Specifies whether a library binding for linking is
           symbolic, dynamic (shared), or static (nonshared).

           -Bdynamic is the default.  You can use the -B
           option several times on a command line.

           For more information on the -Bbinding option, see
           the ld(1) man page and the Solaris documentation.


           -Bdynamic directs the link editor to look for
           liblib.so files. Use this option if you want
           shared library bindings for linking.  If the
           liblib.so files are not found, it looks for
           liblib.a files.

           -Bstatic directs the link editor to look only for
           liblib.a files. The .a suffix indicates that the
           file is static, that is, nonshared.  Use this
           option if you want nonshared library bindings for
           linking.

           -Bsymbolic forces symbols to be resolved within a
           shared library if possible, even when a symbol is
           already defined elsewhere. For an explanation of
           -Bsymbolic, see the ld(1) man page.

           This option and its arguments are passed to the
           linker, ld.  If you compile and link in separate
           steps and are using the -Bbinding option, you must
           include the option in the link step.

           Warning:

           Never use -Bsymbolic with programs containing C++
           code, use linker scoping instead. See the C++
           User's Guide for more information on linker scop-
           ing. See also the -xldscope option.

           With -Bsymbolic, references in different modules
           can bind to different copies of what is supposed
           to be one global object.

           The exception mechanism relies on comparing
           addresses. If you have two copies of something,
           their addresses won't compare equal, and the
           exception mechanism can fail because the exception
           mechanism relies on comparing what are supposed to
           be unique addresses.