Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3002828
  • 博文数量: 674
  • 博客积分: 17881
  • 博客等级: 上将
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 10:15
文章分类

全部博文(674)

文章存档

2013年(34)

2012年(146)

2011年(197)

2010年(297)

分类: LINUX

2011-03-30 22:56:05

加上-fPIC参数后,编译后的文件和没有加这个参数的文件,有什么区别呢,在代码里面做了什么修改能增强它的可重定位性,或者说位置无关性呢?
而且,用没有加这个参数的编译后的共享库,也可以使用,它和加了参数后的使用起来又有什么区别呢
谢谢
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2007-12-27 17:06    Length: 183 byte(s)
[][Print]
----
知之为知之,不知为不知,是知也!
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2007-12-28 10:12    Length: 684 byte(s)
[][Print]
邮件列表里面写的,好像position independent(位置无关)和relocate(可重定位)不是一个意思,是这样吗?
我猜想:
任何源代码编译后的二进制目标文件都是可重定位的,但是如果把它链接成可执行文件,那么如果这个目标文件在编译过程中不管有没有添加-fPIC,它都不存在可重定位的性质了。如果编译这些目标文件时候没有加-fPIC,然后链接成共享库,这时候这个库是没有位置无关性的,但是它具有可重定位的性质,所以照样可以被使用。
不知道我想的对不对

还有,如果我有一个静态库,可是我不想把它当静态库用,有什么办法把它转变成动态库呢(具有位置无关性的)

如果我的程序同时需要静态库和动态库,那么我就先链接静态库,然后再链接动态库,是这样吗?
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2007-12-29 22:45    Length: 79 byte(s)
[][Print]
不清楚。

gcc有一个选项是用于链接静态库的,-s,顺序是无所谓的
----
知之为知之,不知为不知,是知也!
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2007-12-30 13:30    Length: 637 byte(s)
[][Print]
位置无关代码主要是在访问全局变量和全局函数的时候采用了位置无关的重定位方法,既依赖GOT和PLT来重定位.
普通的重定位方法需要修改代码段,比如偏移地址0x100处需要重定位,loader就修改代码段的0x100处的内容,通过查找重定位信息得到具体的值.这种方法需要修改代码段的内容,对于动态连接库来说,其初衷是让多个进程共享代码段,若对其进行写操作,就回引起COW,从而失去共享.
-fPIC选项告诉编绎器使用GOT和PLT的方法重定位,这两个都是数据段,因此避免了COW,真正实现了共享.
如果不用-fPIC,动态连接库依然可以使用,但其重定位方法为一般方法,必然会引起COW.但也无所谓,除了性能在COW时稍微受些影响,其他也没啥啥.
嗯,以上只是我个人的粗浅理解.还望指正
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-01-05 20:30    Length: 12 byte(s)
[][Print]
果然是高手。
----
知之为知之,不知为不知,是知也!
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-01-08 13:24    Length: 171 byte(s)
[][Print]
请问一下你所指的GOT段是不是一定要在MAKEFILE或者是LINK-SCRIPT中进行指定,我在UCLINUX中发现有
GOT段好像其它没有见到,如果不指定的,那么GOT段由编译器自动采用默认的吗
----
诗圣曰:语不惊人死不休
我亦曰:技不动人死不休
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-01-09 12:57    Length: 367 byte(s)
[][Print]
这个我也不确定
我想ld自己应该能够创建所需要的段,而无须用户在makefile或者lds中定义。
我理解linkscript主要功能是定义内存布局,没有在linkscript中定义的段,我想连接器会采用默认方式排列布局,即一个挨一个连续排放。Makefile是定义编译规则,也应该与连接无关。
ucLinux好像不支持使用动态链接库,因此可能没有其他的段,我觉得使用动态链接必须有MMU支持。
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-01-10 00:04    Length: 179 byte(s)
[][Print]
> ucLinux好像不支持使用动态链接库,因此可能没有其他的段,我觉得使用动态链接必须有MMU支持。

你可以看一下没有 MMU 的 FRV 和 Blackfin 是怎么支持动态链接的。
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-01-10 00:15    Length: 562 byte(s)
[][Print]
> 加上-fPIC参数后,编译后的文件和没有加这个参数的文件,有什么区别呢,在代码里面做了什么修改能增强它的可重定位性,或者说位置无关性呢?

w_yzz, 你的这个问题很难回答清楚的。要回答清楚我想需要大概100多页的A4纸吧。好像有本linkers & loaders,你可以看看。


> 而且,用没有加这个参数的编译后的共享库,也可以使用,它和加了参数后的使用起来又有什么区别呢

显然你是用x86做这个测试的。如果你用别的arch,就必须要加-fPIC了。x86在这一点上有点特殊。具体可以看ld的代码。它是free software ;-)
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-07-02 09:42    Length: 1,732 byte(s)
[][Print]
-fPIC 的使用,会生成 PIC 代码,.so 要求为 PIC,以达到动态链接的目的,否则,无法实现动态链接。

non-PIC 与 PIC 代码的区别主要在于 access global data, jump label 的不同。
比如一条 access global data 的指令,
non-PIC 的形势是:ld r3, var1
PIC 的形式则是:ld r3,,意思是从 GOT 表的 index 为 var1-offset 的地方处
指示的地址处装载一个值,即处的4个 byte 其实就是 var1 的地址。这个地址只有在运行的时候才知道,
是由 dynamic-loader(ld-linux.so) 填进去的。

再比如 jump label 指令
non-PIC 的形势是:jump printf ,意思是调用 printf。
PIC 的形式则是:jump,意思是跳到 GOT 表的 index 为 printf-offset 的地方处
指示的地址去执行,这个地址处的代码摆放在 .plt section,每个外部函数对应一段这样的代码,其功能是呼叫
dynamic-loader(ld-linux.so) 来查找函数的地址(本例中是 printf),然后将其地址写到 GOT 表的 index 为 printf-offset 的地方,
同时执行这个函数。这样,第2次呼叫 printf 的时候,就会直接跳到 printf 的地址,而不必再查找了。

GOT 是 data section, 是一个 table, 除专用的几个 entry,每个 entry 的内容可以再执行的时候修改;
PLT 是 text section, 是一段一段的 code,执行中不需要修改。
每个 target 实现 PIC 的机制不同,但大同小异。比如 MIPS 没有 .plt, 而是叫 .stub,功能和 .plt 一样。

可见,动态链接执行很复杂,比静态链接执行时间长;但是,极大的节省了 size,PIC 和动态链接技术是计算机发展史上非常重要的一个
里程碑。

[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-07-02 12:27    Length: 62 byte(s)
[][Print]
我的是MIPS平台,有MMU的,编译so文件时 没加这个参数。
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-07-02 15:02    Length: 368 byte(s)
[][Print]
MIPS 的 ABI 在这一点上比较奇特。它 default 生成的代码就是 PIC 的,即使你不加 -fpic/-fPIC,你可以看一下在 GCC 手册里 mips 的 -mshared和-mno-shared 两个选项。这看上去不错,但是导致了在一些不需要PIC的地方效率比较低。就这几天,GCC的开发人员试图给 MIPS GCC 加入 non-PIC 的支持。一旦这个特性加入后,MIPS 有可能会和大多数平台保持一致,也就是 shared library 需要 -fpic/-fPIC。
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-07-02 17:07    Length: 57 byte(s)
[][Print]
MIPS 控制 PIC 的 option 不是 -fpic/-fPIC, 而是 -mabicalls
[][Print]
Subject: Re: 请问gcc里的参数-fPIC的一些问题
Author:    Posted: 2008-07-02 17:56    Length: 430 byte(s)
[][Print]
MIPS 在链接一些 .o 和 .so 时,确实要求这些 .o 和 .so 都是 PIC 的,否则会报错。
这是因为 MIPS 独特的 PIC 实现机制导致的,在 PIC 时,它会在每个 function 的
开始处重新装载 GP 的值到 global pointer register,用来寻址本文件(每个 .so 或 .exe)的 GOT,但是 non-PIC 的代码不会重新装载 GP 的值到 global pointer register, 一旦从 .so 里回到 .exe 里,global pointer register 已经被破坏了,所以要求这些 .o 和 .so 都是 PIC。
阅读(1070) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~