全局变量,共享库和-fPIC效果 [英] Global variables, shared libraries and -fPIC effect

查看:185
本文介绍了全局变量,共享库和-fPIC效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发了条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 globals 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆