GNU Info

Info Node: (nasm.info)Section 8.2.1

(nasm.info)Section 8.2.1


Next: Section 8.2.2 Prev: Section 8.2 Up: Section 8.2
Enter node , (file) or (file)node

8.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