2010-05-04 31 views
5

我編譯在Fedora Core 12 PHP擴展,但是當我把它發送給某人使用CentOS的,他們得到了錯誤:「ELF文件OS ABI無效」如何在Linux上進行編譯以與所有發行版共享?

我不知道是什麼原因導致運行文件提供以下信息: ELF 64位LSB的共享對象,AMD X86-64,版本1(GNU/Linux的),而不是汽提

加載精細提供了從文件中的以下一個分機: ELF 64位LSB的共享對象, AMD x86-64,版本1(SYSV),沒有剝離

所以看來我需要爲某些發行版產生一個SYSV類型文件,而不是GNU/LINUX文件,但不知道如何。任何指針?

也應該靜態鏈接?

回答

8

聲明:「ELF文件OS ABI無效」,意味着該Application Binary Interface是使用二進制之間不兼容的(即一個人試圖混合主機和目標二進制文件,其中預期可能無法正常工作)。 ELF標題的e_ident[EI_OSABI]字節包含操作系統/ ABI標識。您的Fedora系統將此設置爲ELFOSABI_LINUX3),而您朋友的CentOS系統將其設置爲ELFOSABI_SYSVELFOSABI_NONE0)。

可能能夠編譯FreeBSD的brandelf實用程序(brandelf.c),並用它來OSABI設置爲ELFOSABI_SYSVbrandelf -f 0 <file>brandelf -t SVR4 <file>

,我不知道有任何的gcc標誌在指定此值編譯/鏈接時間,我相信你的Fedora系統中gcc使用的binutils版本負責將OSABI設置爲Linux。我的理解是,如果STT_GNU_IFUNC符號在輸出文件中結束,鏈接器只指定ABI(有關STT_GNU_IFUNC的詳細信息,請參閱ifunc.txt,地址爲http://groups.google.com/group/generic-abi


readelf(1)命令可用於檢索和顯示存儲在ELF頭(readelf -h <file>)的ABI信息。


similar question也可能是感興趣。

+0

哇,非常感謝對於所有的信息,我能夠編譯brandelf並更改操作系統標題。我發送了修改後的二進制文件,希望它能夠運行。我會試着找到一種擺脫STT_GNU_IFUNC符號的方式,不確定我會怎麼做;似乎不是一件簡單的事情。 – 2010-05-05 12:29:32

+0

您可以嘗試搜索'attribute((ifunc))'的源代碼''。我可以將OSABI從'ELFOSABI_LINUX'上更改爲'prog.C(具有ifunc屬性的C++程序)的* static * Linux/ia32二進制文件從'ELFOSABI_LINUX'更改爲'ELFOSABI_SYSV',並且仍然執行它,沒有任何明顯的副作用。這個二進制文件是靜態鏈接的,它*可以*解釋缺乏副作用。 - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40528 – jschmier 2010-05-05 16:39:49

-1

這很可能是你的朋友沒有運行64位系統。 ELF是Linux可執行文件的標準格式,但32位系統無法運行64位可執行文件。

從您的朋友獲取uname -a的輸出。如果輸出不包含「x86_64」,那麼他是在32位版本的CentOS上。

如果是這樣,你需要建立一個交叉編譯環境,或者一個用於編譯32位二進制文​​件的虛擬機,或者只是給你的朋友提供源代碼,以便他自己編譯它。

+0

他實際上是在64位上運行,我以前給他發過一個32位的文件,他從那裏得到一個錯誤。所以我不得不安裝一個64位的操作系統來重新編譯。我注意到我發送的PHP擴展與他編譯的PHP擴展之間唯一的區別是他說'SYSV'與我的'GNU/Linux'相對。 – 2010-05-04 11:33:46

+0

您是否在同一個系統上的兩個二進制文件上運行'file'命令? – jschmier 2010-05-04 19:46:25

+0

是的,他們都是由他在CentOS上運行的 – 2010-05-04 23:01:08

1

編譯目標文件通常不會在不同的linux發行版之間傳輸良好。不同的分佈通常對圖書館有不同的政策,他們在那裏存儲,如何加載。

他們之間有很多不同(是的,即使在Fedora & RedHat/CentOS)。他們可能會在各個級別(內核,PHP,庫位置)爲組件提供自己的修補程序。如果他們使用發行版PHP包,那麼發行版可能會更好地將它修補到他們的系統中。

您可能遇到的主要問題是分發使用了不同的庫/編譯器設置。查看他的計算機上有哪些vercc gcc,並將其與您的計算機進行比較。 (Fedora 12有比CentOS更新的庫)。這就是你的問題所在。

另一個可能的問題是你的二進制文件很好,但它與它使用的所有庫不兼容。我不確定是否有一種很好的方法可以在沒有編譯目標分佈(或變量)的情況下解決這個問題。您可以使用lld <file>命令查看每個共享對象/可執行文件使用的庫。

另外,有錯誤ELF file OS ABI invalid之前有任何輸出?大部分地方我看到它被引用的信息比這更多。

+0

我知道IonCube(一個php擴展)有適用於所有發行版的linux的二進制文件,我用文件檢查了它們中的一個,並輸出「ELF 64位LSB共享對象,x86-64,版本1(SYSV),動態鏈接,剝離「。 雖然我編譯而不是GNU/LINUX,但我找不到任何選項來將操作系統標題更改爲SYSV,這似乎是問題所在。 ldd在他的CentOS上顯示「不是動態的可執行文件」。 – 2010-05-05 02:51:09

+0

您可能想查看Linux標準基礎(LSB)。我個人沒有這方面的經驗,但它可能會提供您需要的二進制兼容性。開發一個可以跨分佈工作的PHP庫的Ioncube不是一件小小的工作,或許它只是一個簡單的庫,而不是像Firefox這樣的完整應用程序(在某些發行版中與Firefox的可下載的Linux客戶端發生衝突) – Reece45 2010-05-05 03:21:50

相關問題