2011-09-04 22 views
12

ダイナミックライブラリ(lib.c)と実行可能ファイル(main.c)で構成されるコードを作成しました。 どちらのファイルでも、私はint globalという名前のグローバル変数を定義します。 スマートではありませんが、それは問題ではありません。グローバル変数、共有ライブラリ、-fPICエフェクト

私は動的ライブラリをコンパイルすると-fPICオプションが必須と思われる:

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 

私はそれがない実行可能ファイルをコンパイルするとき。

gcc main.c -fPIC -ldl 
gcc main.c -ldl 

どちらも動作しますが、説明できない動作がありますか? :main.cの中のグローバルとlib.cのグローバル-fPICと

が同じ変数である。

global main: 23 (0x601050) 
global lib: 23 (0x601050) 

-fPICことなく、lib.cのグローバルは、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の

#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:GCC(Ubuntuの/リナロ4.5.2-8ubuntu4)4.5.2

のuname -a:LinuxのXXX 2.6.38-11-ジェネリック# 48 - UbuntuのSMP金7月29日午後07時02分55秒UTC 2011 x86_64のx86_64でのx86_64のGNU/Linuxの

編集:コードは予期しない共有グローバル変数の同じ種類のSUN/SPARCおよびx86/Linuxのアーキテクチャの下でテスト(と-fPIC)。

+0

関連:http://stackoverflow.com/q/7216244/168175 – Flexo

答えて

7

-fPICでコンパイルすると、グローバルオフセットテーブルを使用して、問題のオブジェクトがグローバルシンボルのアドレスを決定します。コードの一部が-fPICであり、一部がそうでない場合、あなたのint globalのうちの1人が、このテーブルを使用してアドレスを決定し、他の部分はそうでないということです。

-fPICにリンクされた2つの共有オブジェクトがある場合でも、メインプログラムにはまだint globalという2つのアドレスがあります。グローバルオフセットテーブルを使用するアドレスと、PIC以外のコードのローカルアドレスだけです。

さらに詳しくお知りになりたい場合は、really great discussion on PIC vs pic vs non PICがあります。

1

デフォルトでは、実行可能ファイルへの参照は固定オフセットと再配置なしで内部的に実行されます。

しかし、あなたは-fPICを渡しており、グローバルデータへのアクセスはGOT経由でのアクセスに変換され、GOT再配置が追加されます。

関連する問題