2016-12-24 4 views
2

ich das Thema GCC -fPIC optiong ++ -fPIC nicht Position unabhängigen Code produzieren

Ich habe so gelesen habe meine testlib.cpp erstellt.

int foo(int num) 
{ 
    int result; 

    if (num != 0) 
    { 
     result = 1; 
    } 
    else 
    { 
     result = 2; 
    } 

    return result; 
} 

Wenn ich kompilieren als g ++ -c -o testlib.o testlib.cpp und als g ++ -fPIC -c -o testlib.o testlib.cpp den entsprechenden objdumps von TestLib .o sind identisch:

objdump -d testlib.o -M Intel

testlib.o:  file format elf32-i386 

Disassembly of section .text: 

00000000 <_Z3fooi>: 
    0: 55      push ebp 
    1: 89 e5     mov ebp,esp 
    3: 83 ec 10    sub esp,0x10 
    6: 83 7d 08 00    cmp DWORD PTR [ebp+0x8],0x0 
    a: 74 09     je  15 <_Z3fooi+0x15> 
    c: c7 45 fc 01 00 00 00 mov DWORD PTR [ebp-0x4],0x1 
    13: eb 07     jmp 1c <_Z3fooi+0x1c> 
    15: c7 45 fc 02 00 00 00 mov DWORD PTR [ebp-0x4],0x2 
    1c: 8b 45 fc    mov eax,DWORD PTR [ebp-0x4] 
    1f: c9      leave 
    20: c3      ret 

Und ich habe erwartet, dass die Adressen der Argumente springen und je Befehle bei der Kompilierung mit -fPIC positionsunabhängig sein. Also sollten die beiden Objdumps anders sein. Was verstehe ich falsch?

+0

In x86 sind kurze Sprünge (<± 127 Bytes) immer positionsrelativ - ich meine, jeder Sprung im 32 Bit Modus * kann mit einer expliziten vollständigen Adresse geschrieben werden, aber dann sind es 5 Bytes statt 2, kein Assembler in seinem vernünftigen Verstand würde solch eine Anweisung ausstrahlen. –

+0

@MatteoItalia, danke für Ihren Kommentar! Entschuldigung, ich habe es gewählt, habe aber zufällig meine Abstimmung auf meinem Smartphone rückgängig gemacht und kann es nicht erneut aufladen, da es SO verbietet. : ((( – JenyaKh

+1

mach dir keine Sorgen, es passiert die ganze Zeit =) –

Antwort

2

-fPIC ist in den neueren Versionen gcc standardmäßig aktiviert. Der Code ist positionsunabhängig auch ohne die Option:

eb 07     jmp 1c <_Z3fooi+0x1c> 

diese Position unabhängig ist, Blick auf die 2-Byte-Opcode, auch wenn die Demontage druckt das Symbol und seine für Klarheit gegenüber.

Beachten Sie, dass es sehr wahrscheinlich ist, dass der Compiler unabhängig von den Optionen positionsunabhängigen Code für diese Art von kurzen Sprüngen erzeugen würde.

Also diese Flagge ist jetzt nicht sehr nützlich. ABER Sie können PIC mit -fno-PIC Schalter deaktivieren.

+1

Vielen Dank für die Antwort, jetzt verstehe ich, dass es die Position unabhängig Code: "74 09" bedeutet, 09 Bytes weiter und "eb 07" zu springen springe 07 Bytes weiter, richtig? Aber jetzt habe ich versucht, als g ++ -fno-pic -c -o testlib.o testlib.cpp zu kompilieren und habe immer noch den gleichen objdump. Warum funktioniert -fno-pic nicht? – JenyaKh

+0

right about asm. hast du '-fno-PIC' probiert? und vielleicht gilt das nicht für jumps. –

+0

@ Jean-FrançoisFabre" -fPIC ist standardmäßig in neueren gcc-versionen "- irgendein prooflink? – yugr

2

GCC-Compiler verfügt nicht über die Fähigkeit, absichtlich abhängige Code generieren. Eine solche Fähigkeit würde keinerlei praktischen Sinn ergeben.

Was GCC tun kann, erzeugt tatsächlich entweder positionsunabhängigen Code (mit -fPIC Option) oder "was auch immer" -Code (ohne -fPIC Option). Wenn Sie den "was auch immer" -Modus verwenden, ignoriert der Compiler einfach die Punkte der Positionsabhängigkeit und stützt seine Entscheidungen über die Codegenerierung auf andere Überlegungen. Das heißt, selbst wenn Sie nicht -fPIC anfordern, könnten Sie trotzdem leicht mit positionsunabhängigem Code "aus Versehen" enden: weil es einfach so passierte, dass positionsunabhängiger Code aus anderen Gründen am besten funktioniert (kompakter, schneller) usw.)

Wenn Sie einen Unterschied beobachten möchten, benötigen Sie ein repräsentativeres Beispiel. In Ihrem Beispiel sind alle Sprünge in der Nähe von Sprüngen. Sie werden natürlich durch relative (Offset-basierte) Sprungbefehle implementiert. Jeder vernünftige Compiler wird solche relativen Sprünge in solchen Situationen verwenden. Und der Nebeneffekt ist, dass Sie mit positionsunabhängigem Code enden, selbst wenn Sie ihn nicht explizit angefordert haben. Positionsunabhängigkeit kommt in diesem Fall "kostenlos".

Wenn Sie einen Unterschied beobachten möchten, benötigen Sie ein Beispiel, in dem die Positionsunabhängigkeit nicht "kostenlos" erfolgen würde. Sie benötigen etwas, das einen klaren Kompromiss zwischen Positionsunabhängigkeit und anderen wichtigen Faktoren wie Effizienz und/oder Größe erfordert. Wenn Sie mit solch einem Beispiel kommen, werden Sie den Unterschied sehen, den -fPIC macht.

+0

Vielen Dank für Ihre Antwort. Es ist sehr vernünftig. In der anderen Antwort wird jedoch vorgeschlagen, die Option -fno-PIC-Compiler zu verwenden, um positionsabhängigen Code zu erhalten. Ich habe es versucht, aber es hat nicht geholfen. Könnten Sie irgendetwas zu diesem Punkt kommentieren? Ich möchte nur einen Blick auf den positionsabhängigen Code werfen. – JenyaKh

+1

@JenyaKh: Wie ich oben sagte, ist es nicht möglich (für Ihr Beispiel). Sie können bei GCC nur eines von zwei Dingen beantragen: "Ich möchte positionsunabhängigen Code" ('-fpic',' -fPIC', Positionsunabhängigkeit garantiert), oder "I do not care" ('-fno-pic ',' -fno-PIC', Positionsunabhängigkeit nicht garantiert. Egal welche Optionen Sie verwenden, Sie wechseln nur zwischen diesen beiden Modi. Es gibt keine Möglichkeit, GCC dazu zu bringen, seinen generierten Code absichtlich so zu zwingen, dass er "positionsabhängig" ist. Eine solche Option würde überhaupt keinen Sinn ergeben. Wenn Sie einen Unterschied sehen wollen, brauchen Sie ein anderes Beispiel. – AnT

+0

Okay, danke für die Erklärung! – JenyaKh

Verwandte Themen