簡體   English   中英

為什么我需要使用-fPIC來編譯--unresolved-symbols = ignore-in-object-files?

[英]Why do I need -fPIC for compiling with --unresolved-symbols=ignore-in-object-files?

我有以下2個文件:

main.cpp中:

#include <iostream>
int f();
int main(){
  std::cout<<f();
}

functions.cpp:

int f(){
   return 42;
}

我使用以下命令將functions.cpp編譯為libfunctions.so:

g++ -fPIC -shared functions.cpp -o libfunctions.so

我使用以下命令將main.cpp編譯為a.out:

g++ main.cpp -Wl,--unresolved-symbols=ignore-in-object-files

當我使用此命令運行a.out時:

LD_PRELOAD=./libfunctions.so ./a.out

我遇到了細分錯誤。

但是,如果我使用以下命令將main.cpp編譯為a.out:

g++ -fPIC main.cpp -Wl,--unresolved-symbols=ignore-in-object-files

然后就可以了。

我理解為什么必須使用-fPIC編譯共享庫,因為一個共享庫不知道在加載時將其加載到的地址。 但是我不明白為什么main.cpp也必須編譯為PIC。 我以為,由於a.out的加載地址是在鏈接時知道的,因此肯定不需要使用-fPIC進行編譯。

我想念什么?

我假設您正在使用GNU工具鏈。 不幸的是,binutils ld有時會為無效輸入生成損壞的二進制文件,而不是失敗並顯示錯誤消息。

就您而言,我得到:

./a.out: error while loading shared libraries: unexpected PLT reloc type 0x00

此錯誤消息是正確的:

Relocation section '.rela.plt' at offset 0x628 contains 4 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
…
000000000000  000000000000 R_X86_64_NONE                        0

R_X86_64_NONE的值為零,如果遇到錯誤,有時ld會使用它而不是真正的重定位。

這是否是ld bug,仍有待商bat。 ld生成了您要求的二進制文件,而忽略了該錯誤。 它確實產生了無效的重定位。 使用-fno-plt編譯時,我什么都沒有重定位,但是程序仍然崩潰,因為已解析的符號相對於可執行文件或文本部分的偏移量為0。

我懷疑使用-fPIC ,它可能對您-fPIC ,因為ld為未知符號生成動態重定位。 (不過,我無法使binutils 2.30產生此重定位。)

通常, 不可能對未定義的符號生成正確的動態重定位。 沒有定義,在許多體系結構上,無法確定目標是函數還是對象。 如果使用副本重定位,則對對象的未定義引用需要准確的大小信息。 函數引用和對象引用都需要符號定義才能獲得正確的符號版本(如果有)。 欠鏈接極其成問題的原因有很多。

可能值得將其報告為binutils鏈接器錯誤,但我認為它將被視為非常低的優先級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM