2014-11-22 32 views
6

Rekompiluję niektóre pliki wykonywalne dla systemu Android 5.0, ponieważ wymagają one, aby pliki wykonywalne miały numer PIE. Udało mi się skompilować go ARM z tylko dodanie kilku argumentów podczas konfigurowania (z autonomicznym toolchain):GCC: -static i -pie są niezgodne dla x86?

export CFLAGS="-I/softdev/arm-libs/include -fPIE" 
export CPPLAGS="$CPPFLAGS -fPIE" 
export CXXLAGS="$CXXFLAGS -fPIE" 
export LDFLAGS="-L/softdev/arm-libs/lib -static -fPIE -pie" 

Brak błędu dla ARM:

configure:3406: arm-linux-androideabi-gcc -o conftest -I/softdev/arm-libs/include -fPIE -L/softdev/arm-libs/lib -static -fPIE -pie conftest.c >&5 
configure:3410: $? = 0 

ale byłem w stanie zrobić to samo dla x86 jak ja dostaję błąd:

export CFLAGS="-I/softdev/x86-libs/include -fPIE" 
export CPPLAGS="$CPPFLAGS -fPIE" 
export CXXLAGS="$CXXFLAGS -fPIE" 
export LDFLAGS="-L/softdev/x86-libs/lib -static -fPIE -pie" 

błąd:

configure:3336: i686-linux-android-gcc -I/softdev/x86-libs/include -fPIE -L/softdev/x86-libs/lib -static -fPIE -pie conftest.c >&5 
/softdev/x86-toolchain-gcc4.8/bin/../lib/gcc/i686-linux-android/4.8/../../../../i686-linux-android/bin/ld: fatal error: -pie and -static are incompatible 
collect2: error: ld returned 1 exit status 
configure:3340: $? = 1 

Potrzebuję plików wykonywalnych do statycznego powiązania. Co jest nie tak i jak mogę to naprawić?

PS. Próbowałem też za pomocą autonomicznego x86 toolchain z Android R9d NDK i R10C:

./make-standalone-toolchain.sh --toolchain=x86-4.8 --arch=x86 --install-dir=/softdev/x86-toolchain-gcc4.8-r9d --ndk-dir=/softdev/android-ndk-r9d/ --system=darwin-x86_64 
+1

Ian, autor łącznikiem "złoto" mówi: https://sourceware.org/ml/binutils/2012-02/msg00247.html „* Na GNU/Linux a PIE to po prostu wykonywalna biblioteka współdzielona. W jaki sposób byś zaimplementował statycznie połączoną PIE? * "I https://sourceware.org/ml/binutils/2012-02/msg00249.html" * Ale łączenie z - ciasto naprawdę generuje wspólną bibliotekę, a wspólna biblioteka wymaga pliku ld.so. * ". Prawdopodobnie na ARM nie będziesz miał prawdziwego statycznego binarnego, ale binarnego z ld.so interpreter. Przetestuj także x86_64. Możesz połączyć swoje biblioteki statycznie, ale używaj dynamicznej biblioteki libc (nie używaj opcji '-static'). – osgx

+0

Nie jestem pewien, jak to działa wewnętrznie, ale przynajmniej mogę skompilować dla ARM z obu argumentów i nie można na X86. Skompilowany z "-static" plik jest 1,7mb i bez niego (test na x86) jest tylko 400KB. Więc czuję, że "-statyczny" działa, nawet jeśli ma "-pie" – 4ntoine

+0

Użyj 'file -k', aby sprawdzić typ binarny, i' readelf -l', aby sprawdzić sekcję INTERP ELF (jeśli ją posiadasz, nie jest prawdziwym statycznym plikiem binarnym), a 'ldd' sprawdza łączone biblioteki. Myślę, że twoje binarne ramię może nie być prawdziwym statycznym binarnym. – osgx

Odpowiedz

4

Właśnie zrobiłem szybki test z odłogowania w te.c:

int main(int argc, const char* argv[]) 
{ 
    return 0; 
} 

Running arm-linux-androideabi-gcc -o conftest -static -FPIE -pie te.c produkuje żadnego błędu. Jednakże file -k conftest wyjścia

conftest: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped 

readelf -l conftest wyjścia Elf typów plików DYN (Shared plik obiektu) Punkt wejścia 0x500 Istnieje 7 nagłówki program, zaczynający się od przesunięcia 52

Program Headers: 
    Type   Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 
    PHDR   0x000034 0x00000034 0x00000034 0x000e0 0x000e0 R 0x4 
    INTERP   0x000114 0x00000114 0x00000114 0x00013 0x00013 R 0x1 
     [Requesting program interpreter: /system/bin/linker] 
... 

obecność PHDR a nagłówki INTERP wskazują, że -pie cicho zastępuje -statyczne w kompilatorze ramienia. Dlaczego tak jest, nie wiem, ale uważam, że jest to błąd, który nie jest ostrzeżony, gdy -static i -pie są używane razem. Zamiast tego programistom takim jak ty pozostaje fałszywe wrażenie, że obie opcje mogą być użyte razem na ramieniu.

Tylko dla wyjaśnienia jedyną różnicą w zachowaniu jest to, że błędy kompilatora x86 po obejrzeniu zarówno --static, jak i --pie podczas gdy wersja ramienia po cichu ignoruje --static, jeśli --pie jest podana. Jeśli podano tylko jedno, zachowanie jest takie samo dla obu kompilatorów.

+0

ok, więc po prostu zalecamy usunięcie argumentu "-static"? Czy możesz potwierdzić, że działa także dla x86? – 4ntoine

+0

@ 4ntoine Byłem pod wrażeniem błędów wersji x86, i tylko wtedy, gdy oba zostały podane, ale sprawdzę to. Należy pamiętać, że wersja ramienia nie buduje statycznego pliku wykonywalnego, jeśli -pie lub -FPIE jest dostarczana, po prostu nie narzeka na to. – wheredidthatnamecomefrom

+0

@ 4ntoine właśnie zaktualizował odpowiedź, aby wyjaśnić różnicę, mam nadzieję, że odpowie na twoje pytanie. W przeciwnym razie nie jestem do końca pewien, o co pytają. – wheredidthatnamecomefrom

-1

Narzędzie Google NDK zawiera pewne informacje na temat wykorzystania PIE. Odwiedź build/core/build-binary.mk patrz linię 209. Mówi:

# enable PIE for executable beyond certain API level, unless "-static"

Chyba, że ​​jest granica Linux Dynamic Link zasada jest. Ponieważ interpreter Androida (/ system/bin/linker) określający, który plik elfa adresu, który ma zostać załadowany w statycznie połączonym pliku, nie ma interpretera, plik elfa zostanie zmapowany do pamięci na stały adres przez jądro Linux. Oto dyskusji na temat tej zmiany Google issue

Jeśli mam jakiś błąd proszę zrozumieć to :)

0

Jeśli -pie i -static podane są zarówno razem, gcc wyda nieoczekiwany błąd.

-pie

Produce pozycję niezależnego wykonywalnego na cele, które go obsługują. Aby można było przewidzieć wyniki, należy również określić ten sam zestaw opcji używanych do kompilacji (-fpie, -fPIE lub podopcje modelu), gdy zostanie określona opcja tego łącznika.

-pie faktycznie utworzyć typ DYN elf plik z interp z/system/bin/łącznikowej

executable compiled with -pie

-static

W systemach obsługujących dynamiczne linkowanie, co uniemożliwia łączenie z udostępnionego biblioteki. W innych systemach ta opcja nie ma zastosowania.

-static utworzyć plik elf typu EXEC bez interp

+0

zobacz także https://sourceware.org/ml/binutils/2012-02/msg00252.html – ysf