Import Address Table 和 Global Offset Table 有什么区别?

What is the difference between Import Address Table and Global Offset Table?

我试着分别用谷歌搜索它们,但最突出的是一件事。难道只是IAT是PE文件而GoT是ELF?

在 Linux 上,可以使用 nm 命令查看必须从共享库导入的所有符号。我编译了一个叫"main"的小程序。使用 nm 命令,我可以看到对象的偏移量。以 'T' 为前缀的符号是可以在 "main" 代码中找到的函数,以及逻辑偏移量(全局偏移量 Table)。以 'U' 为前缀的符号未定义,必须导入(导入地址 Table)。

$ nm main
0000000100000d70 T _AddAlbum
                 U ___error
                 U ___stderrp
0000000100000000 T __mh_execute_header
                 U _fprintf
0000000100000e40 T _main
                 U _malloc
                 U _printf
                 U _realloc
                 U _strerror
                 U dyld_stub_binder

有关更多详细信息,请使用带有 -x 选项的 objdump:

$ objdump -x main

main:   file format Mach-O 64-bit x86-64

Sections:
Idx Name          Size      Address          Type
  0 __text        0000018a 0000000100000d70 TEXT 
  1 __stubs       00000024 0000000100000efa TEXT 
  2 __stub_helper 0000004c 0000000100000f20 TEXT 
  3 __cstring     00000042 0000000100000f6c DATA 
  4 __unwind_info 00000048 0000000100000fb0 DATA 
  5 __nl_symbol_ptr 00000008 0000000100001000 DATA 
  6 __got         00000010 0000000100001008 DATA 
  7 __la_symbol_ptr 00000030 0000000100001018 DATA 

SYMBOL TABLE:
0000000100000d70 g     F __TEXT,__text  _AddAlbum
0000000100000000 g     F __TEXT,__text  __mh_execute_header
0000000100000e40 g     F __TEXT,__text  _main
0000000000000000         *UND*  ___error
0000000000000000         *UND*  ___stderrp
0000000000000000         *UND*  _fprintf
0000000000000000         *UND*  _malloc
0000000000000000         *UND*  _printf
0000000000000000         *UND*  _realloc
0000000000000000         *UND*  _strerror
0000000000000000         *UND*  dyld_stub_binder
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    15       1296   NOUNDEFS DYLDLINK TWOLEVEL PIE
Load command 0
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __PAGEZERO
   vmaddr 0x0000000000000000
   vmsize 0x0000000100000000
  fileoff 0
 filesize 0
  maxprot ---
 initprot ---
   nsects 0
    flags (none)
Load command 1
      cmd LC_SEGMENT_64
  cmdsize 472
  segname __TEXT
   vmaddr 0x0000000100000000
   vmsize 0x0000000000001000
  fileoff 0
 filesize 4096
  maxprot r-x
 initprot r-x
   nsects 5
    flags (none)
Section
  sectname __text
   segname __TEXT
      addr 0x0000000100000d70
      size 0x000000000000018a
    offset 3440
     align 2^4 (16)
    reloff 0
    nreloc 0
      type S_REGULAR
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
 reserved1 0
 reserved2 0
Section
  sectname __stubs
   segname __TEXT
      addr 0x0000000100000efa
      size 0x0000000000000024
    offset 3834
     align 2^1 (2)
    reloff 0
    nreloc 0
      type S_SYMBOL_STUBS
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
 reserved1 0 (index into indirect symbol table)
 reserved2 6 (size of stubs)
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x0000000100000f20
      size 0x000000000000004c
    offset 3872
     align 2^2 (4)
    reloff 0
    nreloc 0
      type S_REGULAR
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
 reserved1 0
 reserved2 0
Section
  sectname __cstring
   segname __TEXT
      addr 0x0000000100000f6c
      size 0x0000000000000042
    offset 3948
     align 2^0 (1)
    reloff 0
    nreloc 0
      type S_CSTRING_LITERALS
attributes (none)
 reserved1 0
 reserved2 0
Section
  sectname __unwind_info
   segname __TEXT
      addr 0x0000000100000fb0
      size 0x0000000000000048
    offset 4016
     align 2^2 (4)
    reloff 0
    nreloc 0
      type S_REGULAR
attributes (none)
 reserved1 0
 reserved2 0
Load command 2
      cmd LC_SEGMENT_64
  cmdsize 312
  segname __DATA
   vmaddr 0x0000000100001000
   vmsize 0x0000000000001000
  fileoff 4096
 filesize 4096
  maxprot rw-
 initprot rw-
   nsects 3
    flags (none)
Section
  sectname __nl_symbol_ptr
   segname __DATA
      addr 0x0000000100001000
      size 0x0000000000000008
    offset 4096
     align 2^3 (8)
    reloff 0
    nreloc 0
      type S_NON_LAZY_SYMBOL_POINTERS
attributes (none)
 reserved1 6 (index into indirect symbol table)
 reserved2 0
Section
  sectname __got
   segname __DATA
      addr 0x0000000100001008
      size 0x0000000000000010
    offset 4104
     align 2^3 (8)
    reloff 0
    nreloc 0
      type S_NON_LAZY_SYMBOL_POINTERS
attributes (none)
 reserved1 7 (index into indirect symbol table)
 reserved2 0
Section
  sectname __la_symbol_ptr
   segname __DATA
      addr 0x0000000100001018
      size 0x0000000000000030
    offset 4120
     align 2^3 (8)
    reloff 0
    nreloc 0
      type S_LAZY_SYMBOL_POINTERS
attributes (none)
 reserved1 9 (index into indirect symbol table)
 reserved2 0
Load command 3
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __LINKEDIT
   vmaddr 0x0000000100002000
   vmsize 0x0000000000001000
  fileoff 8192
 filesize 572
  maxprot r--
 initprot r--
   nsects 0
    flags (none)
Load command 4
            cmd LC_DYLD_INFO_ONLY
        cmdsize 48
     rebase_off 8192
    rebase_size 8
       bind_off 8200
      bind_size 40
  weak_bind_off 0
 weak_bind_size 0
  lazy_bind_off 8240
 lazy_bind_size 96
     export_off 8336
    export_size 64
Load command 5
     cmd LC_SYMTAB
 cmdsize 24
  symoff 8408
   nsyms 11
  stroff 8644
 strsize 120
Load command 6
            cmd LC_DYSYMTAB
        cmdsize 80
      ilocalsym 0
      nlocalsym 0
     iextdefsym 0
     nextdefsym 3
      iundefsym 3
      nundefsym 8
         tocoff 0
           ntoc 0
      modtaboff 0
        nmodtab 0
   extrefsymoff 0
    nextrefsyms 0
 indirectsymoff 8584
  nindirectsyms 15
      extreloff 0
        nextrel 0
      locreloff 0
        nlocrel 0
Load command 7
          cmd LC_LOAD_DYLINKER
      cmdsize 32
         name /usr/lib/dyld (offset 12)
Load command 8
     cmd LC_UUID
 cmdsize 24
    uuid 55558635-5195-3609-B115-706912ED1DA7
Load command 9
       cmd LC_BUILD_VERSION
   cmdsize 32
  platform macos
       sdk 10.14
     minos 10.14
    ntools 1
      tool ld
   version 520.0
Load command 10
      cmd LC_SOURCE_VERSION
  cmdsize 16
  version 0.0
Load command 11
       cmd LC_MAIN
   cmdsize 24
  entryoff 3648
 stacksize 0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Wed Dec 31 17:00:02 1969
      current version 1281.0.0
compatibility version 1.0.0
Load command 13
      cmd LC_FUNCTION_STARTS
  cmdsize 16
  dataoff 8400
 datasize 8
Load command 14
      cmd LC_DATA_IN_CODE
  cmdsize 16
  dataoff 8408
 datasize 0

Is it just that IAT is for PE files and GoT is for ELF?

这是主要区别。

另一个区别是 ELF 文件中的 GOT 也可能包含描述 ELF 文件本身定义的符号的条目。这是典型的 32 位共享库。

PE 文件中的 IAT 仅包含描述其他 DLL 文件中定义的符号的条目。