github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/link/internal/loadpe/ldpe.go (about)

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package loadpe implements a PE/COFF file reader.
     6  package loadpe
     7  
     8  import (
     9  	"github.com/shogo82148/std/cmd/internal/bio"
    10  	"github.com/shogo82148/std/cmd/internal/sys"
    11  	"github.com/shogo82148/std/cmd/link/internal/loader"
    12  )
    13  
    14  const (
    15  	IMAGE_SYM_UNDEFINED              = 0
    16  	IMAGE_SYM_ABSOLUTE               = -1
    17  	IMAGE_SYM_DEBUG                  = -2
    18  	IMAGE_SYM_TYPE_NULL              = 0
    19  	IMAGE_SYM_TYPE_VOID              = 1
    20  	IMAGE_SYM_TYPE_CHAR              = 2
    21  	IMAGE_SYM_TYPE_SHORT             = 3
    22  	IMAGE_SYM_TYPE_INT               = 4
    23  	IMAGE_SYM_TYPE_LONG              = 5
    24  	IMAGE_SYM_TYPE_FLOAT             = 6
    25  	IMAGE_SYM_TYPE_DOUBLE            = 7
    26  	IMAGE_SYM_TYPE_STRUCT            = 8
    27  	IMAGE_SYM_TYPE_UNION             = 9
    28  	IMAGE_SYM_TYPE_ENUM              = 10
    29  	IMAGE_SYM_TYPE_MOE               = 11
    30  	IMAGE_SYM_TYPE_BYTE              = 12
    31  	IMAGE_SYM_TYPE_WORD              = 13
    32  	IMAGE_SYM_TYPE_UINT              = 14
    33  	IMAGE_SYM_TYPE_DWORD             = 15
    34  	IMAGE_SYM_TYPE_PCODE             = 32768
    35  	IMAGE_SYM_DTYPE_NULL             = 0
    36  	IMAGE_SYM_DTYPE_POINTER          = 1
    37  	IMAGE_SYM_DTYPE_FUNCTION         = 2
    38  	IMAGE_SYM_DTYPE_ARRAY            = 3
    39  	IMAGE_SYM_CLASS_END_OF_FUNCTION  = -1
    40  	IMAGE_SYM_CLASS_NULL             = 0
    41  	IMAGE_SYM_CLASS_AUTOMATIC        = 1
    42  	IMAGE_SYM_CLASS_EXTERNAL         = 2
    43  	IMAGE_SYM_CLASS_STATIC           = 3
    44  	IMAGE_SYM_CLASS_REGISTER         = 4
    45  	IMAGE_SYM_CLASS_EXTERNAL_DEF     = 5
    46  	IMAGE_SYM_CLASS_LABEL            = 6
    47  	IMAGE_SYM_CLASS_UNDEFINED_LABEL  = 7
    48  	IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8
    49  	IMAGE_SYM_CLASS_ARGUMENT         = 9
    50  	IMAGE_SYM_CLASS_STRUCT_TAG       = 10
    51  	IMAGE_SYM_CLASS_MEMBER_OF_UNION  = 11
    52  	IMAGE_SYM_CLASS_UNION_TAG        = 12
    53  	IMAGE_SYM_CLASS_TYPE_DEFINITION  = 13
    54  	IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14
    55  	IMAGE_SYM_CLASS_ENUM_TAG         = 15
    56  	IMAGE_SYM_CLASS_MEMBER_OF_ENUM   = 16
    57  	IMAGE_SYM_CLASS_REGISTER_PARAM   = 17
    58  	IMAGE_SYM_CLASS_BIT_FIELD        = 18
    59  	IMAGE_SYM_CLASS_FAR_EXTERNAL     = 68
    60  	IMAGE_SYM_CLASS_BLOCK            = 100
    61  	IMAGE_SYM_CLASS_FUNCTION         = 101
    62  	IMAGE_SYM_CLASS_END_OF_STRUCT    = 102
    63  	IMAGE_SYM_CLASS_FILE             = 103
    64  	IMAGE_SYM_CLASS_SECTION          = 104
    65  	IMAGE_SYM_CLASS_WEAK_EXTERNAL    = 105
    66  	IMAGE_SYM_CLASS_CLR_TOKEN        = 107
    67  	IMAGE_REL_I386_ABSOLUTE          = 0x0000
    68  	IMAGE_REL_I386_DIR16             = 0x0001
    69  	IMAGE_REL_I386_REL16             = 0x0002
    70  	IMAGE_REL_I386_DIR32             = 0x0006
    71  	IMAGE_REL_I386_DIR32NB           = 0x0007
    72  	IMAGE_REL_I386_SEG12             = 0x0009
    73  	IMAGE_REL_I386_SECTION           = 0x000A
    74  	IMAGE_REL_I386_SECREL            = 0x000B
    75  	IMAGE_REL_I386_TOKEN             = 0x000C
    76  	IMAGE_REL_I386_SECREL7           = 0x000D
    77  	IMAGE_REL_I386_REL32             = 0x0014
    78  	IMAGE_REL_AMD64_ABSOLUTE         = 0x0000
    79  	IMAGE_REL_AMD64_ADDR64           = 0x0001
    80  	IMAGE_REL_AMD64_ADDR32           = 0x0002
    81  	IMAGE_REL_AMD64_ADDR32NB         = 0x0003
    82  	IMAGE_REL_AMD64_REL32            = 0x0004
    83  	IMAGE_REL_AMD64_REL32_1          = 0x0005
    84  	IMAGE_REL_AMD64_REL32_2          = 0x0006
    85  	IMAGE_REL_AMD64_REL32_3          = 0x0007
    86  	IMAGE_REL_AMD64_REL32_4          = 0x0008
    87  	IMAGE_REL_AMD64_REL32_5          = 0x0009
    88  	IMAGE_REL_AMD64_SECTION          = 0x000A
    89  	IMAGE_REL_AMD64_SECREL           = 0x000B
    90  	IMAGE_REL_AMD64_SECREL7          = 0x000C
    91  	IMAGE_REL_AMD64_TOKEN            = 0x000D
    92  	IMAGE_REL_AMD64_SREL32           = 0x000E
    93  	IMAGE_REL_AMD64_PAIR             = 0x000F
    94  	IMAGE_REL_AMD64_SSPAN32          = 0x0010
    95  	IMAGE_REL_ARM_ABSOLUTE           = 0x0000
    96  	IMAGE_REL_ARM_ADDR32             = 0x0001
    97  	IMAGE_REL_ARM_ADDR32NB           = 0x0002
    98  	IMAGE_REL_ARM_BRANCH24           = 0x0003
    99  	IMAGE_REL_ARM_BRANCH11           = 0x0004
   100  	IMAGE_REL_ARM_SECTION            = 0x000E
   101  	IMAGE_REL_ARM_SECREL             = 0x000F
   102  	IMAGE_REL_ARM_MOV32              = 0x0010
   103  	IMAGE_REL_THUMB_MOV32            = 0x0011
   104  	IMAGE_REL_THUMB_BRANCH20         = 0x0012
   105  	IMAGE_REL_THUMB_BRANCH24         = 0x0014
   106  	IMAGE_REL_THUMB_BLX23            = 0x0015
   107  	IMAGE_REL_ARM_PAIR               = 0x0016
   108  	IMAGE_REL_ARM64_ABSOLUTE         = 0x0000
   109  	IMAGE_REL_ARM64_ADDR32           = 0x0001
   110  	IMAGE_REL_ARM64_ADDR32NB         = 0x0002
   111  	IMAGE_REL_ARM64_BRANCH26         = 0x0003
   112  	IMAGE_REL_ARM64_PAGEBASE_REL21   = 0x0004
   113  	IMAGE_REL_ARM64_REL21            = 0x0005
   114  	IMAGE_REL_ARM64_PAGEOFFSET_12A   = 0x0006
   115  	IMAGE_REL_ARM64_PAGEOFFSET_12L   = 0x0007
   116  	IMAGE_REL_ARM64_SECREL           = 0x0008
   117  	IMAGE_REL_ARM64_SECREL_LOW12A    = 0x0009
   118  	IMAGE_REL_ARM64_SECREL_HIGH12A   = 0x000A
   119  	IMAGE_REL_ARM64_SECREL_LOW12L    = 0x000B
   120  	IMAGE_REL_ARM64_TOKEN            = 0x000C
   121  	IMAGE_REL_ARM64_SECTION          = 0x000D
   122  	IMAGE_REL_ARM64_ADDR64           = 0x000E
   123  	IMAGE_REL_ARM64_BRANCH19         = 0x000F
   124  	IMAGE_REL_ARM64_BRANCH14         = 0x0010
   125  	IMAGE_REL_ARM64_REL32            = 0x0011
   126  )
   127  
   128  const (
   129  	// When stored into the PLT value for a symbol, this token tells
   130  	// windynrelocsym to redirect direct references to this symbol to a stub
   131  	// that loads from the corresponding import symbol and then does
   132  	// a jump to the loaded value.
   133  	CreateImportStubPltToken = -2
   134  
   135  	// When stored into the GOT value for an import symbol __imp_X this
   136  	// token tells windynrelocsym to redirect references to the
   137  	// underlying DYNIMPORT symbol X.
   138  	RedirectToDynImportGotToken = -2
   139  )
   140  
   141  // Symbols contains the symbols that can be loaded from a PE file.
   142  type Symbols struct {
   143  	Textp     []loader.Sym
   144  	Resources []loader.Sym
   145  	PData     loader.Sym
   146  	XData     loader.Sym
   147  }
   148  
   149  // Load loads the PE file pn from input.
   150  // Symbols from the object file are created via the loader 'l'.
   151  func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (*Symbols, error)
   152  
   153  // PostProcessImports works to resolve inconsistencies with DLL import
   154  // symbols; it is needed when building with more "modern" C compilers
   155  // with internal linkage.
   156  //
   157  // Background: DLL import symbols are data (SNOPTRDATA) symbols whose
   158  // name is of the form "__imp_XXX", which contain a pointer/reference
   159  // to symbol XXX. It's possible to have import symbols for both data
   160  // symbols ("__imp__fmode") and text symbols ("__imp_CreateEventA").
   161  // In some case import symbols are just references to some external
   162  // thing, and in other cases we see actual definitions of import
   163  // symbols when reading host objects.
   164  //
   165  // Previous versions of the linker would in most cases immediately
   166  // "forward" import symbol references, e.g. treat a references to
   167  // "__imp_XXX" a references to "XXX", however this doesn't work well
   168  // with more modern compilers, where you can sometimes see import
   169  // symbols that are defs (as opposed to external refs).
   170  //
   171  // The main actions taken below are to search for references to
   172  // SDYNIMPORT symbols in host object text/data sections and flag the
   173  // symbols for later fixup. When we see a reference to an import
   174  // symbol __imp_XYZ where XYZ corresponds to some SDYNIMPORT symbol,
   175  // we flag the symbol (via GOT setting) so that it can be redirected
   176  // to XYZ later in windynrelocsym. When we see a direct reference to
   177  // an SDYNIMPORT symbol XYZ, we also flag the symbol (via PLT setting)
   178  // to indicated that the reference will need to be redirected to a
   179  // stub.
   180  func PostProcessImports() error
   181  
   182  // LookupBaseFromImport examines the symbol "s" to see if it
   183  // corresponds to an import symbol (name of the form "__imp_XYZ") and
   184  // if so, it looks up the underlying target of the import symbol and
   185  // returns it. An error is returned if the symbol is of the form
   186  // "__imp_XYZ" but no XYZ can be found.
   187  func LookupBaseFromImport(s loader.Sym, ldr *loader.Loader, arch *sys.Arch) (loader.Sym, error)