3

I used readelf to read the information of the ELF file. I found the address of .got section in the section header is different from the GOT entry point address read from the dynamic section. Is the data which stored between .got address and the entry point of GOT like garbage? The follow is apart of information got from readelf.


ELF Header - This ELF is run on ARMv7A.

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          52 (bytes into file)
  Start of section headers:          38412 (bytes into file)
  Flags:                             0x5000200, Version5 EABI, soft-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         8
  Size of section headers:           40 (bytes)
  Number of section headers:         26
  Section header string table index: 25

Section Headers - The address of .got section is at 0x00008eac

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .note.gnu.build-i NOTE            00000134 000134 000024 00   A  0   0  4
  [ 2] .dynsym           DYNSYM          00000158 000158 0006a0 10   A  3   1  4
  [ 3] .dynstr           STRTAB          000007f8 0007f8 000704 00   A  0   0  1
  [ 4] .hash             HASH            00000efc 000efc 000334 04   A  2   0  4
  [ 5] .gnu.version      VERSYM          00001230 001230 0000d4 02   A  2   0  2
  [ 6] .gnu.version_d    VERDEF          00001304 001304 00001c 00   A  3   1  4
  [ 7] .gnu.version_r    VERNEED         00001320 001320 000020 00   A  3   1  4
  [ 8] .rel.dyn          REL             00001340 001340 000178 08   A  2   0  4
  [ 9] .rel.plt          REL             000014b8 0014b8 000250 08  AI  2  10  4
  [10] .plt              PROGBITS        00001708 001708 00038c 00  AX  0   0  4
  [11] .text             PROGBITS        00001a94 001a94 0053d4 00  AX  0   0  4
  [12] .ARM.extab        PROGBITS        00006e68 006e68 000078 00   A  0   0  4
  [13] .ARM.exidx        ARM_EXIDX       00006ee0 006ee0 000178 08  AL 11   0  4
  [14] .rodata           PROGBITS        00007058 007058 000038 00  AM  0   0  4
  [15] .fini_array       FINI_ARRAY      00008cf8 007cf8 000008 00  WA  0   0  4
  [16] .data.rel.ro      PROGBITS        00008d00 007d00 00007c 00  WA  0   0  4
  [17] .init_array       INIT_ARRAY      00008d7c 007d7c 000008 00  WA  0   0  4
  [18] .dynamic          DYNAMIC         00008d84 007d84 000128 08  WA  3   0  4
  [19] .got              PROGBITS        00008eac 007eac 000154 00  WA  0   0  4
  [20] .data             PROGBITS        00009000 008000 001450 00  WA  0   0  4
  [21] .bss              NOBITS          0000a450 009450 000004 00  WA  0   0  4
  [22] .comment          PROGBITS        00000000 009450 000065 01  MS  0   0  1
  [23] .note.gnu.gold-ve NOTE            00000000 0094b8 00001c 00      0   0  4
  [24] .ARM.attributes   ARM_ATTRIBUTES  00000000 0094d4 000034 00      0   0  1
  [25] .shstrtab         STRTAB          00000000 009508 000103 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

A Part of Dynamic Section

Dynamic section at offset 0x7d84 contains 32 entries:
  Tag        Type                         Name/Value
 0x00000003 (PLTGOT)                     0x8ecc
 0x00000002 (PLTRELSZ)                   592 (bytes)
 0x00000017 (JMPREL)                     0x14b8
 0x00000014 (PLTREL)                     REL
 0x00000011 (REL)                        0x1340
 0x00000012 (RELSZ)                      376 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffa (RELCOUNT)                   41
 0x00000006 (SYMTAB)                     0x158
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000005 (STRTAB)                     0x7f8
 0x0000000a (STRSZ)                      1796 (bytes)
 0x00000004 (HASH)                       0xefc
 ...

Tail of .dynamic and Head of .got

...
0x8e84:   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   |................|
0x8e94:   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   |................|
0x8ea4:   00 00 00 00 00 00 00 00  00                        |.........       |
; section: .got
0x8eac:   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   |................|
0x8ebc:   00 00 00 00 58 70 00 00  e0 6e 00 00 00 00 00 00   |....Xp...n......|
0x8ecc:   00 00 00 00 00 00 00 00  00 00 00 00 08 17 00 00   |................|
0x8edc:   08 17 00 00 08 17 00 00  08 17 00 00 08 17 00 00   |................|
...

The Oracle's specification mentioned:

The symbol _GLOBAL_OFFSET_TABLE_ can be used to access the table. This symbol can reside in the middle of the .got section, allowing both negative and nonnegative subscripts into the array of addresses.

But the data before the entry of GOT are quietly different from others. All of the other data points to the very first PLT address(0x1708). Is the space before the entry point of GOT used to store the address of external functions as the same as others, or there are other ways to use them, or they are just unuseful garbage?


Update

I found there are two numbers in the block 0x8eac to 0x8ecb, the block before the entry point of the GOT. At 0x8ec0, 0x7058 is the address of .rodata section. And at 0x8ec4, 0x6ee0 is the address of .ARM.exidx section. Is it that filling these two address in .got a specific feature of the chain tools and compilers for ARM?

I have not seen any specification of ELF mentions this.

  • Well, in fact, it is normal that a fresh GOT (without resolution of addresses) is filled of pointers linking the start of the PLT. This is needed for the first initialization of the GOT (remember, the first time you encounter the function@plt, you need to execute the program which is located at the very beginning of the PLT). So, this explain why you have the PLT address repeatedly stored in the GOT (one address per library function that is used in the binary). – perror Sep 19 '18 at 6:56
  • I know why PLT address repeatedly stored in the GOT. Each of the addresses stores the address of its corresponding external function or external variable. I am curious about the usage of the block before the entry point of the GOT. – IvanaGyro Sep 19 '18 at 7:50
  • Okay, I better understand your question. But, you should try to look at the .dynamic section at runtime. It may change a lot of things... As the name suggest, it must be initialized only at start time (when the linker has performed his job). My guess is that you will see the addresses of all the listed variables set once at runtime. – perror Sep 19 '18 at 8:06
  • what do you mean by "entry point of GOT"? AFAIK there is no such term – Igor Skochinsky Sep 19 '18 at 9:14
  • 1
    @IgorSkochinsky Sorry, I have not explained it clearly. The term, "entry point of GOT", means the address follows the tag, PLTGOT, in the .dynamic section. The address is also as the same as the address of GOT[0] in most of the specifications of the ELF. – IvanaGyro Sep 20 '18 at 9:27
2

It's difficult to say without the sample, but you need to keep in mind that the dynamic loader does not care about sections. It only uses information from the program headers, including the PT_DYNAMIC entry (it may well be different from the .dynamic section in which case the section's contents is simply ignored).

While customarily the GOT starts at the beginning of the .got section, it is not a requirement for the loader to do its job. It only uses the dynamic tags and dynamic relocation info (DT_JMPREL, DT_PLTREL, DT_REL, plus DT_SYMTAB,DT_STRTAB and DT_HASH and for symbol resolution). In fact, you can remove the section table completely and the file will still run (but some tools may have difficulties parsing it).

Possibly some other section got merged with .got, although I don't know what it could be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.