Why does PLT exist in addition to GOT instead of just using GOT?

I understand that in a typical ELF binary, functions are called through a procedure binding table (PLT). The PLT record for a function usually includes a jump to the Global Offset Table (GOT) record. This entry first refers to some code to load the actual function address into the GOT and contains the actual function address after the first call (lazy binding).

To be precise, before lazily binding the GOT entry points back to the PLT to the instructions following the jump to the GOT. These instructions usually go to the PLT header, from where the binding procedure is called, which then updates the GOT record.

Now I wonder why there are two indirectities (calling in the PLT and then going to the address from the GOT) instead of just sparing the PLT and directly accessing the address from the GOT. It looks like it could save the jump and the full PLT. Of course, you still need the code that calls the binding procedure, but it may be outside the PLT.

Is there anything I can't see? What is / was the purpose of the additional PLT?


Update: As suggested in the comments, I created some (pseudo) ASCII art code to further explain what I mean:

This, as I understand it, is the situation in the current PLT scheme before lazy binding: (Some links between the PLT and are printfrepresented by "...".)

Program                PLT                                 printf
+---------------+      +------------------+                +-----+
| ...           |      | push [0x603008]  |<---+       +-->| ... |
| call j_printf |--+   | jmp [0x603010]   |----+--...--+   +-----+
| ...           |  |   | ...              |    |
+---------------+  +-->| jmp [printf@GOT] |-+  |
                       | push 0xf         |<+  |
                       | jmp 0x400da0     |----+
                       | ...              |
                       +------------------+

... and after lazy binding:

Program                PLT                       printf
+---------------+      +------------------+      +-----+
| ...           |      | push [0x603008]  |  +-->| ... |
| call j_printf |--+   | jmp [0x603010]   |  |   +-----+
| ...           |  |   | ...              |  |
+---------------+  +-->| jmp [printf@GOT] |--+
                       | push 0xf         |
                       | jmp 0x400da0     |
                       | ...              |
                       +------------------+

PLT : ( "Lazy Binding Table", , PLT. -, .)

Program                    Lazy Binding Table                printf
+-------------------+      +------------------+              +-----+
| ...               |      | push [0x603008]  |<-+       +-->| ... |
| call [printf@GOT] |--+   | jmp [0x603010]   |--+--...--+   +-----+
| ...               |  |   | ...              |  |
+-------------------+  +-->| push 0xf         |  |
                           | jmp 0x400da0     |--+
                           | ...              |
                           +------------------+

, , :

Program                   Lazy Binding Table        printf
+-------------------+     +------------------+      +-----+
| ...               |     | push [0x603008]  |  +-->| ... |
| call [printf@GOT] |--+  | jmp [0x603010]   |  |   +-----+
| ...               |  |  | ...              |  |
+-------------------+  |  | push 0xf         |  |
                       |  | jmp 0x400da0     |  |
                       |  | ...              |  |
                       |  +------------------+  |
                       +------------------------+
+6
2

, call printf@PLT call [printf@GOTPLT] , , printf , ( ). call printf call printf@PLT, jmp printf jmp printf@PLT mov eax, printf mov eax, printf@PLT printf printf@PLT. call printf call [printf@GOTPLT] , CALL JMP - . , CALL , , CALL CALL.

, , CALL, , 5 , 6 . , nop; call printf@CALL nop; call printf@CALL , . , , - NOP.

, 32- x86 PLT . jmp [xxx@GOTPLT] jmp [xxx@GOTPLT] PLT , CALL JMP, xxx@GOTPLT , , . JMP, .plt , . 4K , , , , , .

, 32- x86. , @GOTPLT, 64- x86 @GOTPLT RIP.

- GCC (6.1 ) -fno-plt. 64- x86 call printf@GOTPCREL[rip] call printf call printf. , , , . , , . , , . 32- -fno-plt x86 -fno-plt , , (-fpic -fpie), call printf@GOT[ebx]. , , GOT, .

, Windows , , "dllimport", , DLL. , , . , DLL, , , .

Drepper , ( Linux).

+10

, ( PLT, GOT),

, , ( PLT- ).

, PLT GOT.

, -fno-plt, PLT.

, , , . , , , PLT.

+1

Source: https://habr.com/ru/post/1673321/


All Articles