From ac9be2020b3d57c4b23e83432d732c1d0b308316 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Mon, 28 Aug 2017 13:45:56 +1000 Subject: [PATCH] cmd/link: introduce and use peFile.writeFileHeader Change-Id: I1324b69ab9edb870589197fa601b5764634d42a4 Reviewed-on: https://go-review.googlesource.com/59427 Reviewed-by: Ian Lance Taylor --- src/cmd/link/internal/ld/pe.go | 82 +++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index 128f0c9319..06b3b0193c 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go @@ -15,16 +15,6 @@ import ( "strings" ) -type IMAGE_FILE_HEADER struct { - Machine uint16 - NumberOfSections uint16 - TimeDateStamp uint32 - PointerToSymbolTable uint32 - NumberOfSymbols uint32 - SizeOfOptionalHeader uint16 - Characteristics uint16 -} - type IMAGE_DATA_DIRECTORY struct { VirtualAddress uint32 Size uint32 @@ -321,8 +311,6 @@ var PEFILEHEADR int32 var pe64 int -var fh IMAGE_FILE_HEADER - var oh IMAGE_OPTIONAL_HEADER var oh64 PE64_IMAGE_OPTIONAL_HEADER @@ -475,7 +463,8 @@ type peFile struct { ctorsSect *peSection nextSectOffset uint32 nextFileOffset uint32 - symbolCount int // number of symbol table records written + symtabOffset int64 // offset to the start of symbol table + symbolCount int // number of symbol table records written } // addSection adds section to the COFF file f. @@ -756,7 +745,7 @@ func (f *peFile) writeSymbols(ctxt *Link) { // writeSymbolTableAndStringTable writes out symbol and string tables for peFile f. func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) { - symtabStartPos := coutbuf.Offset() + f.symtabOffset = coutbuf.Offset() // write COFF symbol table if !*FlagS || Linkmode == LinkExternal { @@ -771,10 +760,8 @@ func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) { // will also include it in the exe, and that will confuse windows. h = f.addSection(".symtab", size, size) h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE - h.checkOffset(symtabStartPos) + h.checkOffset(f.symtabOffset) } - fh.PointerToSymbolTable = uint32(symtabStartPos) - fh.NumberOfSymbols = uint32(f.symbolCount) // write COFF string table f.stringTable.write() @@ -783,6 +770,44 @@ func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) { } } +// writeFileHeader writes COFF file header for peFile f. +func (f *peFile) writeFileHeader() { + var fh pe.FileHeader + + switch SysArch.Family { + default: + Exitf("unknown PE architecture: %v", SysArch.Family) + case sys.AMD64: + fh.Machine = IMAGE_FILE_MACHINE_AMD64 + case sys.I386: + fh.Machine = IMAGE_FILE_MACHINE_I386 + } + + fh.NumberOfSections = uint16(len(f.sections)) + + // Being able to produce identical output for identical input is + // much more beneficial than having build timestamp in the header. + fh.TimeDateStamp = 0 + + if Linkmode == LinkExternal { + fh.Characteristics = IMAGE_FILE_LINE_NUMS_STRIPPED + } else { + fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DEBUG_STRIPPED + } + if pe64 != 0 { + fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64)) + fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE + } else { + fh.SizeOfOptionalHeader = uint16(binary.Size(&oh)) + fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE + } + + fh.PointerToSymbolTable = uint32(f.symtabOffset) + fh.NumberOfSymbols = uint32(f.symbolCount) + + binary.Write(&coutbuf, binary.LittleEndian, &fh) +} + var pefile peFile func Peinit(ctxt *Link) { @@ -809,6 +834,7 @@ func Peinit(ctxt *Link) { } var sh [16]pe.SectionHeader32 + var fh pe.FileHeader PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN)) if Linkmode != LinkExternal { PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN)) @@ -846,7 +872,7 @@ func pewrite() { strnput("PE", 4) } - binary.Write(&coutbuf, binary.LittleEndian, &fh) + pefile.writeFileHeader() if pe64 != 0 { binary.Write(&coutbuf, binary.LittleEndian, &oh64) @@ -1214,10 +1240,7 @@ func Asmbpe(ctxt *Link) { switch SysArch.Family { default: Exitf("unknown PE architecture: %v", SysArch.Family) - case sys.AMD64: - fh.Machine = IMAGE_FILE_MACHINE_AMD64 - case sys.I386: - fh.Machine = IMAGE_FILE_MACHINE_I386 + case sys.AMD64, sys.I386: } t := pefile.addSection(".text", int(Segtext.Length), int(Segtext.Length)) @@ -1267,24 +1290,9 @@ func Asmbpe(ctxt *Link) { pefile.emitRelocations(ctxt) } - fh.NumberOfSections = uint16(len(pefile.sections)) - - // Being able to produce identical output for identical input is - // much more beneficial than having build timestamp in the header. - fh.TimeDateStamp = 0 - - if Linkmode == LinkExternal { - fh.Characteristics = IMAGE_FILE_LINE_NUMS_STRIPPED - } else { - fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DEBUG_STRIPPED - } if pe64 != 0 { - fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64)) - fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE oh64.Magic = 0x20b // PE32+ } else { - fh.SizeOfOptionalHeader = uint16(binary.Size(&oh)) - fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE oh.Magic = 0x10b // PE32 oh.BaseOfData = d.VirtualAddress } -- 2.48.1