loadpe

Imports

Imports #

"bytes"
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/loader"
"cmd/link/internal/sym"
"debug/pe"
"encoding/binary"
"errors"
"fmt"
"io"
"strings"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/loader"
"cmd/link/internal/sym"
"fmt"
"sort"

Constants & Variables

CreateImportStubPltToken const #

When stored into the PLT value for a symbol, this token tells windynrelocsym to redirect direct references to this symbol to a stub that loads from the corresponding import symbol and then does a jump to the loaded value.

const CreateImportStubPltToken = *ast.UnaryExpr

IMAGE_REL_AMD64_ABSOLUTE const #

const IMAGE_REL_AMD64_ABSOLUTE = 0x0000

IMAGE_REL_AMD64_ADDR32 const #

const IMAGE_REL_AMD64_ADDR32 = 0x0002

IMAGE_REL_AMD64_ADDR32NB const #

const IMAGE_REL_AMD64_ADDR32NB = 0x0003

IMAGE_REL_AMD64_ADDR64 const #

const IMAGE_REL_AMD64_ADDR64 = 0x0001

IMAGE_REL_AMD64_PAIR const #

const IMAGE_REL_AMD64_PAIR = 0x000F

IMAGE_REL_AMD64_REL32 const #

const IMAGE_REL_AMD64_REL32 = 0x0004

IMAGE_REL_AMD64_REL32_1 const #

const IMAGE_REL_AMD64_REL32_1 = 0x0005

IMAGE_REL_AMD64_REL32_2 const #

const IMAGE_REL_AMD64_REL32_2 = 0x0006

IMAGE_REL_AMD64_REL32_3 const #

const IMAGE_REL_AMD64_REL32_3 = 0x0007

IMAGE_REL_AMD64_REL32_4 const #

const IMAGE_REL_AMD64_REL32_4 = 0x0008

IMAGE_REL_AMD64_REL32_5 const #

const IMAGE_REL_AMD64_REL32_5 = 0x0009

IMAGE_REL_AMD64_SECREL const #

const IMAGE_REL_AMD64_SECREL = 0x000B

IMAGE_REL_AMD64_SECREL7 const #

const IMAGE_REL_AMD64_SECREL7 = 0x000C

IMAGE_REL_AMD64_SECTION const #

const IMAGE_REL_AMD64_SECTION = 0x000A

IMAGE_REL_AMD64_SREL32 const #

const IMAGE_REL_AMD64_SREL32 = 0x000E

IMAGE_REL_AMD64_SSPAN32 const #

const IMAGE_REL_AMD64_SSPAN32 = 0x0010

IMAGE_REL_AMD64_TOKEN const #

const IMAGE_REL_AMD64_TOKEN = 0x000D

IMAGE_REL_ARM64_ABSOLUTE const #

const IMAGE_REL_ARM64_ABSOLUTE = 0x0000

IMAGE_REL_ARM64_ADDR32 const #

const IMAGE_REL_ARM64_ADDR32 = 0x0001

IMAGE_REL_ARM64_ADDR32NB const #

const IMAGE_REL_ARM64_ADDR32NB = 0x0002

IMAGE_REL_ARM64_ADDR64 const #

const IMAGE_REL_ARM64_ADDR64 = 0x000E

IMAGE_REL_ARM64_BRANCH14 const #

const IMAGE_REL_ARM64_BRANCH14 = 0x0010

IMAGE_REL_ARM64_BRANCH19 const #

const IMAGE_REL_ARM64_BRANCH19 = 0x000F

IMAGE_REL_ARM64_BRANCH26 const #

const IMAGE_REL_ARM64_BRANCH26 = 0x0003

IMAGE_REL_ARM64_PAGEBASE_REL21 const #

const IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004

IMAGE_REL_ARM64_PAGEOFFSET_12A const #

const IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006

IMAGE_REL_ARM64_PAGEOFFSET_12L const #

const IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007

IMAGE_REL_ARM64_REL21 const #

const IMAGE_REL_ARM64_REL21 = 0x0005

IMAGE_REL_ARM64_REL32 const #

const IMAGE_REL_ARM64_REL32 = 0x0011

IMAGE_REL_ARM64_SECREL const #

const IMAGE_REL_ARM64_SECREL = 0x0008

IMAGE_REL_ARM64_SECREL_HIGH12A const #

const IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A

IMAGE_REL_ARM64_SECREL_LOW12A const #

const IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009

IMAGE_REL_ARM64_SECREL_LOW12L const #

const IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B

IMAGE_REL_ARM64_SECTION const #

const IMAGE_REL_ARM64_SECTION = 0x000D

IMAGE_REL_ARM64_TOKEN const #

const IMAGE_REL_ARM64_TOKEN = 0x000C

IMAGE_REL_ARM_ABSOLUTE const #

const IMAGE_REL_ARM_ABSOLUTE = 0x0000

IMAGE_REL_ARM_ADDR32 const #

const IMAGE_REL_ARM_ADDR32 = 0x0001

IMAGE_REL_ARM_ADDR32NB const #

const IMAGE_REL_ARM_ADDR32NB = 0x0002

IMAGE_REL_ARM_BRANCH11 const #

const IMAGE_REL_ARM_BRANCH11 = 0x0004

IMAGE_REL_ARM_BRANCH24 const #

const IMAGE_REL_ARM_BRANCH24 = 0x0003

IMAGE_REL_ARM_MOV32 const #

const IMAGE_REL_ARM_MOV32 = 0x0010

IMAGE_REL_ARM_PAIR const #

const IMAGE_REL_ARM_PAIR = 0x0016

IMAGE_REL_ARM_SECREL const #

const IMAGE_REL_ARM_SECREL = 0x000F

IMAGE_REL_ARM_SECTION const #

const IMAGE_REL_ARM_SECTION = 0x000E

IMAGE_REL_I386_ABSOLUTE const #

const IMAGE_REL_I386_ABSOLUTE = 0x0000

IMAGE_REL_I386_DIR16 const #

const IMAGE_REL_I386_DIR16 = 0x0001

IMAGE_REL_I386_DIR32 const #

const IMAGE_REL_I386_DIR32 = 0x0006

IMAGE_REL_I386_DIR32NB const #

const IMAGE_REL_I386_DIR32NB = 0x0007

IMAGE_REL_I386_REL16 const #

const IMAGE_REL_I386_REL16 = 0x0002

IMAGE_REL_I386_REL32 const #

const IMAGE_REL_I386_REL32 = 0x0014

IMAGE_REL_I386_SECREL const #

const IMAGE_REL_I386_SECREL = 0x000B

IMAGE_REL_I386_SECREL7 const #

const IMAGE_REL_I386_SECREL7 = 0x000D

IMAGE_REL_I386_SECTION const #

const IMAGE_REL_I386_SECTION = 0x000A

IMAGE_REL_I386_SEG12 const #

const IMAGE_REL_I386_SEG12 = 0x0009

IMAGE_REL_I386_TOKEN const #

const IMAGE_REL_I386_TOKEN = 0x000C

IMAGE_REL_THUMB_BLX23 const #

const IMAGE_REL_THUMB_BLX23 = 0x0015

IMAGE_REL_THUMB_BRANCH20 const #

const IMAGE_REL_THUMB_BRANCH20 = 0x0012

IMAGE_REL_THUMB_BRANCH24 const #

const IMAGE_REL_THUMB_BRANCH24 = 0x0014

IMAGE_REL_THUMB_MOV32 const #

const IMAGE_REL_THUMB_MOV32 = 0x0011

IMAGE_SYM_ABSOLUTE const #

const IMAGE_SYM_ABSOLUTE = *ast.UnaryExpr

IMAGE_SYM_CLASS_ARGUMENT const #

const IMAGE_SYM_CLASS_ARGUMENT = 9

IMAGE_SYM_CLASS_AUTOMATIC const #

const IMAGE_SYM_CLASS_AUTOMATIC = 1

IMAGE_SYM_CLASS_BIT_FIELD const #

const IMAGE_SYM_CLASS_BIT_FIELD = 18

IMAGE_SYM_CLASS_BLOCK const #

const IMAGE_SYM_CLASS_BLOCK = 100

IMAGE_SYM_CLASS_CLR_TOKEN const #

const IMAGE_SYM_CLASS_CLR_TOKEN = 107

IMAGE_SYM_CLASS_END_OF_FUNCTION const #

const IMAGE_SYM_CLASS_END_OF_FUNCTION = *ast.UnaryExpr

IMAGE_SYM_CLASS_END_OF_STRUCT const #

const IMAGE_SYM_CLASS_END_OF_STRUCT = 102

IMAGE_SYM_CLASS_ENUM_TAG const #

const IMAGE_SYM_CLASS_ENUM_TAG = 15

IMAGE_SYM_CLASS_EXTERNAL const #

const IMAGE_SYM_CLASS_EXTERNAL = 2

IMAGE_SYM_CLASS_EXTERNAL_DEF const #

const IMAGE_SYM_CLASS_EXTERNAL_DEF = 5

IMAGE_SYM_CLASS_FAR_EXTERNAL const #

const IMAGE_SYM_CLASS_FAR_EXTERNAL = 68

IMAGE_SYM_CLASS_FILE const #

const IMAGE_SYM_CLASS_FILE = 103

IMAGE_SYM_CLASS_FUNCTION const #

const IMAGE_SYM_CLASS_FUNCTION = 101

IMAGE_SYM_CLASS_LABEL const #

const IMAGE_SYM_CLASS_LABEL = 6

IMAGE_SYM_CLASS_MEMBER_OF_ENUM const #

const IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16

IMAGE_SYM_CLASS_MEMBER_OF_STRUCT const #

const IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8

IMAGE_SYM_CLASS_MEMBER_OF_UNION const #

const IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11

IMAGE_SYM_CLASS_NULL const #

const IMAGE_SYM_CLASS_NULL = 0

IMAGE_SYM_CLASS_REGISTER const #

const IMAGE_SYM_CLASS_REGISTER = 4

IMAGE_SYM_CLASS_REGISTER_PARAM const #

const IMAGE_SYM_CLASS_REGISTER_PARAM = 17

IMAGE_SYM_CLASS_SECTION const #

const IMAGE_SYM_CLASS_SECTION = 104

IMAGE_SYM_CLASS_STATIC const #

const IMAGE_SYM_CLASS_STATIC = 3

IMAGE_SYM_CLASS_STRUCT_TAG const #

const IMAGE_SYM_CLASS_STRUCT_TAG = 10

IMAGE_SYM_CLASS_TYPE_DEFINITION const #

const IMAGE_SYM_CLASS_TYPE_DEFINITION = 13

IMAGE_SYM_CLASS_UNDEFINED_LABEL const #

const IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7

IMAGE_SYM_CLASS_UNDEFINED_STATIC const #

const IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14

IMAGE_SYM_CLASS_UNION_TAG const #

const IMAGE_SYM_CLASS_UNION_TAG = 12

IMAGE_SYM_CLASS_WEAK_EXTERNAL const #

const IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105

IMAGE_SYM_DEBUG const #

const IMAGE_SYM_DEBUG = *ast.UnaryExpr

IMAGE_SYM_DTYPE_ARRAY const #

const IMAGE_SYM_DTYPE_ARRAY = 3

IMAGE_SYM_DTYPE_FUNCTION const #

const IMAGE_SYM_DTYPE_FUNCTION = 2

IMAGE_SYM_DTYPE_NULL const #

const IMAGE_SYM_DTYPE_NULL = 0

IMAGE_SYM_DTYPE_POINTER const #

const IMAGE_SYM_DTYPE_POINTER = 1

IMAGE_SYM_TYPE_BYTE const #

const IMAGE_SYM_TYPE_BYTE = 12

IMAGE_SYM_TYPE_CHAR const #

const IMAGE_SYM_TYPE_CHAR = 2

IMAGE_SYM_TYPE_DOUBLE const #

const IMAGE_SYM_TYPE_DOUBLE = 7

IMAGE_SYM_TYPE_DWORD const #

const IMAGE_SYM_TYPE_DWORD = 15

IMAGE_SYM_TYPE_ENUM const #

const IMAGE_SYM_TYPE_ENUM = 10

IMAGE_SYM_TYPE_FLOAT const #

const IMAGE_SYM_TYPE_FLOAT = 6

IMAGE_SYM_TYPE_INT const #

const IMAGE_SYM_TYPE_INT = 4

IMAGE_SYM_TYPE_LONG const #

const IMAGE_SYM_TYPE_LONG = 5

IMAGE_SYM_TYPE_MOE const #

const IMAGE_SYM_TYPE_MOE = 11

IMAGE_SYM_TYPE_NULL const #

const IMAGE_SYM_TYPE_NULL = 0

IMAGE_SYM_TYPE_PCODE const #

const IMAGE_SYM_TYPE_PCODE = 32768

IMAGE_SYM_TYPE_SHORT const #

const IMAGE_SYM_TYPE_SHORT = 3

IMAGE_SYM_TYPE_STRUCT const #

const IMAGE_SYM_TYPE_STRUCT = 8

IMAGE_SYM_TYPE_UINT const #

const IMAGE_SYM_TYPE_UINT = 14

IMAGE_SYM_TYPE_UNION const #

const IMAGE_SYM_TYPE_UNION = 9

IMAGE_SYM_TYPE_VOID const #

const IMAGE_SYM_TYPE_VOID = 1

IMAGE_SYM_TYPE_WORD const #

const IMAGE_SYM_TYPE_WORD = 13

IMAGE_SYM_UNDEFINED const #

const IMAGE_SYM_UNDEFINED = 0

RedirectToDynImportGotToken const #

When stored into the GOT value for an import symbol __imp_X this token tells windynrelocsym to redirect references to the underlying DYNIMPORT symbol X.

const RedirectToDynImportGotToken = *ast.UnaryExpr

UNW_FLAG_CHAININFO const #

const UNW_FLAG_CHAININFO = *ast.BinaryExpr

UNW_FLAG_EHANDLER const #

const UNW_FLAG_EHANDLER = *ast.BinaryExpr

UNW_FLAG_UHANDLER const #

const UNW_FLAG_UHANDLER = *ast.BinaryExpr

comdatDefinitions var #

comdatDefinitions records the names of symbols for which we've previously seen a definition in COMDAT. Key is symbol name, value is symbol size (or -1 if we're using the "any" strategy).

var comdatDefinitions map[string]int64

importSymsState var #

var importSymsState *peImportSymsState

unwCodeSize const #

const unwCodeSize = 2

unwStaticDataSize const #

const unwStaticDataSize = 4

Type Aliases

peBiobuf type #

peBiobuf makes bio.Reader look like io.ReaderAt.

type peBiobuf bio.Reader

Structs

Symbols struct #

Symbols contains the symbols that can be loaded from a PE file.

type Symbols struct {
Textp []loader.Sym
Resources []loader.Sym
PData loader.Sym
XData loader.Sym
}

peImportSymsState struct #

peImportSymsState tracks the set of DLL import symbols we've seen while reading host objects. We create a singleton instance of this type, which will persist across multiple host objects.

type peImportSymsState struct {
secSyms []loader.Sym
l *loader.Loader
arch *sys.Arch
}

peLoaderState struct #

peLoaderState holds various bits of useful state information needed while loading a single PE object file.

type peLoaderState struct {
l *loader.Loader
arch *sys.Arch
f *pe.File
pn string
sectsyms map[*pe.Section]loader.Sym
comdats map[uint16]int64
sectdata map[*pe.Section][]byte
localSymVersion int
}

Functions

Load function #

Load loads the PE file pn from input. Symbols from the object file are created via the loader 'l'.

func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (*Symbols, error)

LookupBaseFromImport function #

LookupBaseFromImport examines the symbol "s" to see if it corresponds to an import symbol (name of the form "__imp_XYZ") and if so, it looks up the underlying target of the import symbol and returns it. An error is returned if the symbol is of the form "__imp_XYZ" but no XYZ can be found.

func LookupBaseFromImport(s loader.Sym, ldr *loader.Loader, arch *sys.Arch) (loader.Sym, error)

PostProcessImports function #

PostProcessImports works to resolve inconsistencies with DLL import symbols; it is needed when building with more "modern" C compilers with internal linkage. Background: DLL import symbols are data (SNOPTRDATA) symbols whose name is of the form "__imp_XXX", which contain a pointer/reference to symbol XXX. It's possible to have import symbols for both data symbols ("__imp__fmode") and text symbols ("__imp_CreateEventA"). In some case import symbols are just references to some external thing, and in other cases we see actual definitions of import symbols when reading host objects. Previous versions of the linker would in most cases immediately "forward" import symbol references, e.g. treat a references to "__imp_XXX" a references to "XXX", however this doesn't work well with more modern compilers, where you can sometimes see import symbols that are defs (as opposed to external refs). The main actions taken below are to search for references to SDYNIMPORT symbols in host object text/data sections and flag the symbols for later fixup. When we see a reference to an import symbol __imp_XYZ where XYZ corresponds to some SDYNIMPORT symbol, we flag the symbol (via GOT setting) so that it can be redirected to XYZ later in windynrelocsym. When we see a direct reference to an SDYNIMPORT symbol XYZ, we also flag the symbol (via PLT setting) to indicated that the reference will need to be redirected to a stub.

func PostProcessImports() error

ReadAt method #

func (f *peBiobuf) ReadAt(p []byte, off int64) (int, error)

createImportSymsState function #

func createImportSymsState(l *loader.Loader, arch *sys.Arch)

findHandlerInXDataAMD64 function #

findHandlerInXDataAMD64 finds the symbol in the .xdata section that corresponds to the exception handler. Reference: https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-unwind_info

func findHandlerInXDataAMD64(ldr *loader.Loader, xsym sym.LoaderSym, add int64) loader.Sym

issect function #

func issect(s *pe.COFFSymbol) bool

issehsect function #

func issehsect(arch *sys.Arch, s *pe.Section) bool

makeUpdater function #

makeUpdater creates a loader.SymbolBuilder if one hasn't been created previously. We use this to lazily make SymbolBuilders as we don't always need a builder, and creating them for all symbols might be an error.

func makeUpdater(l *loader.Loader, bld *loader.SymbolBuilder, s loader.Sym) *loader.SymbolBuilder

preprocessSymbols method #

preprocessSymbols walks the COFF symbols for the PE file we're reading and looks for cases where we have both a symbol definition for "XXX" and an "__imp_XXX" symbol, recording these cases in a map in the state struct. This information will be used in readpesym() above to give such symbols special treatment. This function also gathers information about COMDAT sections/symbols for later use in readpesym().

func (state *peLoaderState) preprocessSymbols() error

processSEH function #

processSEH walks all pdata relocations looking for exception handler function symbols. We want to mark these as reachable if the function that they protect is reachable in the final binary.

func processSEH(ldr *loader.Loader, arch *sys.Arch, pdata sym.LoaderSym, xdata sym.LoaderSym) error

processSEHAMD64 function #

func processSEHAMD64(ldr *loader.Loader, pdata sym.LoaderSym) error

readpesym method #

func (state *peLoaderState) readpesym(pesym *pe.COFFSymbol) (*loader.SymbolBuilder, loader.Sym, error)

Generated with Arrow