为什么不是所有代码编译位置都独立?

ojb*_*ass 72 c compilation

在gcc中编译共享库时,-fPIC选项将代码编译为与位置无关的代码.是否有任何原因(性能或其他原因)您不能编译所有代码位置独立?

wow*_*est 61

它增加了间接性.使用与位置无关的代码,您必须加载函数的地址,然后跳转到它.通常,函数的地址已经存在于指令流中.


Eli*_*sky 27

本文解释了PIC的工作原理,并将其与替代方案进行了比较 - 加载时间重定位.我认为这与你的问题有关.

  • @Nick:我不同意.如果它有助于提问者,那就是答案.指向相关的一两篇文章可以提供丰富的信息. (14认同)
  • 虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接.如果链接的页面发生更改,则仅链接的答案可能会无效. (8认同)
  • 相关帖子!=回答 (5认同)
  • 这篇文章没有结论,只是一篇文章的链接.甚至不知道由于性能问题,默认情况下不使用PIC. (4认同)
  • 这篇文章出现在"审查"下,要求我这样做,我做了.别人标记了它."抱怨评论"是由SO自动生成的,而不是我. (4认同)
  • @Rob:有成效的事情是建议编辑而不是使用评论来抱怨.这个答案是4岁.那时候SO对于答案的外观规则不那么严格 (3认同)

Unk*_*own 26

是的,有性能原因.一些访问实际上在另一层间接下,以获得内存中的绝对位置.

还有GOT(全局偏移表)存储全局变量的偏移量.对我来说,这看起来就像是一个IAT修正表,它被维基百科和其他一些来源归类为位置依​​赖.

http://en.wikipedia.org/wiki/Position_independent_code


Eva*_*ran 19

除了接受的答案.严重损害PIC代码性能的一件事是在x86上缺乏"IP相对寻址".使用"IP相对寻址",您可以从当前指令指针请求X字节的数据.这将使PIC代码更简单.

跳转和调用通常是EIP相对的,所以这些并不会造成问题.但是,访问数据需要一些额外的诡计.有时,寄存器将暂时保留为代码所需数据的"基指针".例如,一种常见的技术是滥用调用在x86上工作的方式:

call label_1
.dd 0xdeadbeef
.dd 0xfeedf00d
.dd 0x11223344
label_1:
pop ebp            ; now ebp holds the address of the first dataword
                   ; this works because the call pushes the **next**
                   ; instructions address
                   ; real code follows
mov eax, [ebp + 4] ; for example i'm accessing the '0xfeedf00d' in a PIC way
Run Code Online (Sandbox Code Playgroud)

这种技术和其他技术为数据访问添加了一层间接.例如,gcc编译器使用的GOT(全局偏移表).

X86-64新增了"相对RIP"模式,这使得事情很多简单.