2014-11-22 21 views
6

Sto ricompilando alcuni eseguibili per Android 5.0 in quanto richiede che gli eseguibili siano PIE. Sono stato in grado di ricompilare per ARM con solo l'aggiunta di alcuni argomenti durante la configurazione (con standalone toolchain):GCC: -static e -pie non sono compatibili con 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" 

Nessun errore per 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 

ma non sono riuscito a fare lo stesso per x86 come sto ottenendo errore:

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" 

errore:

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 

Ho bisogno che gli eseguibili siano collegati staticamente. Cosa c'è che non va e come posso risolverlo?

PS. provato anche utilizzando x86 standalone toolchain da Android NDK r9d e 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, autore di linker "oro", dice: https://sourceware.org/ml/binutils/2012-02/msg00247.html "* On GNU/Linux a PIE è solo una libreria condivisa eseguibile. Come potreste implementare un PIE collegato staticamente? * "E https://sourceware.org/ml/binutils/2012-02/msg00249.html" * Ma collegarvi con - pie realmente genera solo una libreria condivisa e una libreria condivisa richiede ld.so. * ". Probabilmente, su ARM non avrai il vero binario statico, ma binario con l'interprete ld.so. Prova anche x86_64. È possibile collegare le librerie in modo statico, ma utilizzare la libc dinamica (non usare l'opzione '-static'). – osgx

+0

Non sono sicuro di come funzioni internamente, ma almeno posso compilare ARM con entrambi gli argomenti e non posso su X86. Compilato con il file "-static" è 1,7mb e senza di esso (test su x86) è solo 400Kb. Quindi mi fa sentire "-static" funziona anche se si ha "-pie" – 4ntoine

+0

Usa 'file -k' per verificare il tipo binario, e' readelf -l' per controllare la sezione INTERP di ELF (se ne hai uno, non è il vero binario statico), e 'ldd' per controllare le librerie collegate. Penso che il tuo braccio binario possa non essere un vero binario statico. – osgx

risposta

4

Ho appena fatto il test rapido con vuoto sanitario in te.c:

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

Esecuzione arm-linux-androideabi-gcc -o conftest -static -FPIE -pie te.c produce alcun errore. Tuttavia file -k conftest uscite

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

readelf -l conftest uscite tipo di file ELF è DYN (file oggetto condiviso) Punto di ingresso 0x500 Ci sono 7 intestazioni di programma, a partire all'offset 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] 
... 

La presenza del PHDR e le intestazioni INTERP indicano che -py sovrascrive in modo statico nel compilatore di braccia. Perché questo non lo so, ma lo considererei un bug che non viene emesso alcun avviso quando vengono usati insieme -statico e -pie. Invece ai programmatori come te viene lasciata la falsa impressione che le due opzioni possano essere usate insieme per il braccio.

Giusto per chiarire l'unica differenza comportamentale qui è che gli errori del compilatore x86 nel vedere sia --static che --pie mentre la versione arm ignora silenziosamente --static se --pie viene dato. Se viene dato solo uno di questi, il comportamento è lo stesso per entrambi i compilatori.

+0

ok, quindi consiglio di rimuovere l'argomento "-static"? Puoi confermare che funziona anche per x86? – 4ntoine

+0

@ 4ntoine Ho avuto l'impressione che gli errori della versione x86 se e solo se siano stati dati entrambi, vedrò di verificarlo. Tieni presente che la versione arm non sta effettivamente creando un eseguibile statico se -pie o -FPIE viene fornito, ma non si lamenta di ciò. – wheredidthatnamecomefrom

+0

@ 4ntoine ha appena aggiornato la risposta per chiarire la differenza, si spera che risponda alla tua domanda. Altrimenti non sono abbastanza sicuro di cosa viene chiesto. – wheredidthatnamecomefrom

-1

Lo strumento NDK di Google contiene alcune informazioni sull'utilizzo della PIE. Visita build/core/build-binary.mk, vedi la linea 209. Dice:

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

immagino, è limite di Linux di principio di collegamento dinamico. Poiché l'interprete Android (/ system/bin/linker) che determina quale indirizzo il file elf deve essere caricato in un file statico collegato non ha interprete, il file elf verrà mappato alla memoria in un indirizzo fisso dal kernel linux. Ecco una discutere di questo cambiamento Google issue

Se ho alcun errore si prega di capirlo :)

0

Se -pie e -static sono entrambi dato assieme, gcc emetterà errore imprevisto.

-pie

produrre una posizione eseguibile indipendente su obiettivi che lo supportano. Per risultati prevedibili, è necessario specificare lo stesso insieme di opzioni utilizzate per la compilazione (-fpie, -fPIE o sottoopzioni di modello) quando si specifica questa opzione di linker.

-pie effettivamente creare un file di tipo elfo DYN con INTERP con/system/bin/linker

executable compiled with -pie

-static

Su sistemi che supportano il collegamento dinamico, questo impedisce il collegamento con il comune librerie. Su altri sistemi, questa opzione non ha alcun effetto.

-static creare un file di tipo elfo EXEC senza INTERP

+0

vedere anche https://sourceware.org/ml/binutils/2012-02/msg00252.html – ysf