Copyright (C) 2000-2012 |
GNU Info (nasm.info)Section 8.2.18.2.1. Obtaining the Address of the GOT --------------------------------------- Each code module in your shared library should define the GOT as an external symbol: extern _GLOBAL_OFFSET_TABLE_ ; in ELF extern __GLOBAL_OFFSET_TABLE_ ; in BSD a.out At the beginning of any function in your shared library which plans to access your data or BSS sections, you must first calculate the address of the GOT. This is typically done by writing the function in this form: func: push ebp mov ebp,esp push ebx call .get_GOT .get_GOT: pop ebx add ebx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc ; the function body comes here mov ebx,[ebp-4] mov esp,ebp pop ebp ret (For BSD, again, the symbol `_GLOBAL_OFFSET_TABLE' requires a second leading underscore.) The first two lines of this function are simply the standard C prologue to set up a stack frame, and the last three lines are standard C function epilogue. The third line, and the fourth to last line, save and restore the `EBX' register, because PIC shared libraries use this register to store the address of the GOT. The interesting bit is the `CALL' instruction and the following two lines. The `CALL' and `POP' combination obtains the address of the label `.get_GOT', without having to know in advance where the program was loaded (since the `CALL' instruction is encoded relative to the current position). The `ADD' instruction makes use of one of the special PIC relocation types: GOTPC relocation. With the `WRT ..gotpc' qualifier specified, the symbol referenced (here `_GLOBAL_OFFSET_TABLE_', the special symbol assigned to the GOT) is given as an offset from the beginning of the section. (Actually, `ELF' encodes it as the offset from the operand field of the `ADD' instruction, but NASM simplifies this deliberately, so you do things the same way for both `ELF' and `BSD'.) So the instruction then _adds_ the beginning of the section, to get the real address of the GOT, and subtracts the value of `.get_GOT' which it knows is in `EBX'. Therefore, by the time that instruction has finished, `EBX' contains the address of the GOT. If you didn't follow that, don't worry: it's never necessary to obtain the address of the GOT by any other means, so you can put those three instructions into a macro and safely ignore them: %macro get_GOT 0 call %%getgot %%getgot: pop ebx add ebx,_GLOBAL_OFFSET_TABLE_+$$-%%getgot wrt ..gotpc %endmacro automatically generated by info2www version 1.2.2.9 |