全局变量,共享库和-fPIC效果 [英] Global variables, shared libraries and -fPIC effect
问题描述
我发了条code的其中包括在一个动态库( lib.c
)和主可执行文件(为主。 ç
)。
在这两个文件,我定义了一个名为一个全局变量: INT全球
。
不是很聪明,但它不是问题。
I made a piece of code which consists in a dynamic library (lib.c
), and a main executable (main.c
).
In both files I define a global variable named: int global
.
Not very smart but it's not the question.
当我编译动态库 -fPIC
选择似乎必需的:
When I compile the dynamic library the -fPIC
option seems mandatory:
gcc lib.c -fPIC -shared -o lib.so
否则我得到:
/usr/bin/ld: /tmp/ccpUvIPj.o: relocation R_X86_64_32 against '.rodata' can not be used when making a shared object; recompile with -fPIC
当我编译可执行事实并非如此。
When I compile the executable it is not.
gcc main.c -fPIC -ldl
gcc main.c -ldl
这两个工作,但有不同的行为,我无法解释,是吗?
Both work, but have different behaviours I can not explain, could you ? :
与-fPIC,main.c中全球和在全球lib.c是相同的变量:
with -fPIC, global in main.c and global in lib.c are the same variables:
global main: 23 (0x601050)
global lib: 23 (0x601050)
无-fPIC,全球在lib.c不相关的main.c全球:
without -fPIC, global in lib.c is not correlated to global in main.c:
global main: 23 (0x601048)
global lib: 0 (0x7f7742e64028)
下面是源:
lib.c
#include <stdio.h>
#include <stdlib.h>
int global;
int f_one() {
printf("global lib: %d (%p)\n", global, &global);
return EXIT_SUCCESS;
}
的main.c
main.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void * handle;
int global;
int main() {
int q = 7;
int (* f_one_p)(int a) = NULL;
global = 23;
handle = dlopen("./lib.so", RTLD_NOW);
if (handle == 0) {
return EXIT_FAILURE;
}
f_one_p = dlsym(handle, "f_one");
printf("global main: %d (%p)\n", global, &global);
f_one_p(q);
return EXIT_SUCCESS;
}
GCC --version:海湾合作委员会(Ubuntu的/ Linaro的4.5.2-8ubuntu4)4.5.2
gcc --version: gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
的uname -a:Linux的XXX 2.6.38-11泛型#48 Ubuntu的SMP周五07月29日19时02分55秒UTC 2011 x86_64的x86_64的x86_64的GNU / Linux的
uname -a: Linux xxx 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:02:55 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
修改:code在Sun / SPARC测试和x86 / Linux的架构与同类意外的共享全局变量(用-fPIC)的
edit: code tested under SUN/sparc and x86/Linux architectures with the same kind of unexpected shared global variables (with -fPIC).
推荐答案
在与 -fPIC
编译问题的对象将通过确定全局符号的地址全局偏移表的。会发生什么,虽然当code的一部分,是 -fPIC
和部分不就是一个你的 INT全球
s将会使用该表来确定该地址,而另一部分是不
When you compile with -fPIC
the object in question will determine the address of global symbols using the Global Offset Table. What happens though when part of the code is -fPIC
and part isn't is that one of your int global
s will be using this table to determine the address whilst the other part isn't.
如果你有两个共享对象, -fPIC
联系,但主程序没有,那么你仍然有两个地址 INT全球
,一个使用这只是本地的非PIC code。
If you had two shared object linked with -fPIC
, but your main program not then you would still have two addresses for int global
, one using the global offset table and one which was just local to the non-PIC code.
有一个关于PIC一个真正伟大的讨论VS PIC与非PIC 如果你要进一步阅读。
There's a really great discussion on PIC vs pic vs non PIC if you want to read further.
这篇关于全局变量,共享库和-fPIC效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!