DataDirectory [16]IMAGE_DATA_DIRECTORY
}
-type IMAGE_SECTION_HEADER struct {
- Name [8]uint8
- VirtualSize uint32
- VirtualAddress uint32
- SizeOfRawData uint32
- PointerToRawData uint32
- PointerToRelocations uint32
- PointerToLineNumbers uint32
- NumberOfRelocations uint16
- NumberOfLineNumbers uint16
- Characteristics uint32
-}
-
type IMAGE_IMPORT_DESCRIPTOR struct {
OriginalFirstThunk uint32
TimeDateStamp uint32
var oh64 PE64_IMAGE_OPTIONAL_HEADER
-var sh [16]IMAGE_SECTION_HEADER
-
// shNames stores full names of PE sections stored in sh.
var shNames []string
}
f.sections = append(f.sections, sect)
pensect++
+ shNames = append(shNames, name)
return sect
}
var pefile peFile
-func addpesectionWithLongName(ctxt *Link, shortname, longname string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
- if pensect == 16 {
- Errorf(nil, "too many sections")
- errorexit()
- }
-
- h := &sh[pensect]
- pensect++
- copy(h.Name[:], shortname)
- shNames = append(shNames, longname)
- h.VirtualSize = uint32(sectsize)
- h.VirtualAddress = uint32(nextsectoff)
- nextsectoff = int(Rnd(int64(nextsectoff)+int64(sectsize), PESECTALIGN))
- h.PointerToRawData = uint32(nextfileoff)
- if filesize > 0 {
- h.SizeOfRawData = uint32(Rnd(int64(filesize), PEFILEALIGN))
- nextfileoff += int(h.SizeOfRawData)
- }
-
- return h
-}
-
-func addpesection(ctxt *Link, name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
- return addpesectionWithLongName(ctxt, name, name, sectsize, filesize)
+func addpesection(ctxt *Link, name string, sectsize int, filesize int) *peSection {
+ return pefile.addSection(name, sectsize, filesize)
}
-func chksectoff(ctxt *Link, h *IMAGE_SECTION_HEADER, off int64) {
+func chksectoff(ctxt *Link, h *peSection, off int64) {
if off != int64(h.PointerToRawData) {
- Errorf(nil, "%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(off))
+ Errorf(nil, "%s.PointerToRawData = %#x, want %#x", h.name, uint64(int64(h.PointerToRawData)), uint64(off))
errorexit()
}
}
-func chksectseg(ctxt *Link, h *IMAGE_SECTION_HEADER, s *Segment) {
+func chksectseg(ctxt *Link, h *peSection, s *Segment) {
if s.Vaddr-PEBASE != uint64(h.VirtualAddress) {
- Errorf(nil, "%s.VirtualAddress = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.VirtualAddress)), uint64(int64(s.Vaddr-PEBASE)))
+ Errorf(nil, "%s.VirtualAddress = %#x, want %#x", h.name, uint64(int64(h.VirtualAddress)), uint64(int64(s.Vaddr-PEBASE)))
errorexit()
}
if s.Fileoff != uint64(h.PointerToRawData) {
- Errorf(nil, "%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(int64(s.Fileoff)))
+ Errorf(nil, "%s.PointerToRawData = %#x, want %#x", h.name, uint64(int64(h.PointerToRawData)), uint64(int64(s.Fileoff)))
errorexit()
}
}
PEFILEALIGN = 0
}
+ var sh [16]pe.SectionHeader32
PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN))
if Linkmode != LinkExternal {
PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN))
} else {
binary.Write(&coutbuf, binary.LittleEndian, &oh)
}
- if Linkmode == LinkExternal {
- for i := range sh[:pensect] {
- sh[i].VirtualAddress = 0
- }
+ for _, sect := range pefile.sections {
+ sect.write()
}
- binary.Write(&coutbuf, binary.LittleEndian, sh[:pensect])
}
func strput(s string) {
return dlls
}
-func addimports(ctxt *Link, datsect *IMAGE_SECTION_HEADER) {
+func addimports(ctxt *Link, datsect *peSection) {
startoff := coutbuf.Offset()
dynamic := ctxt.Syms.Lookup(".windynamic", 0)
// The actual relocations are emitted by relocfn.
// This updates the corresponding PE section table entry
// with the relocation offset and count.
-func peemitsectreloc(sect *IMAGE_SECTION_HEADER, relocfn func() int) {
+func peemitsectreloc(sect *peSection, relocfn func() int) {
sect.PointerToRelocations = uint32(coutbuf.Offset())
// first entry: extended relocs
Lputl(0) // placeholder for number of relocation + 1
}
// peemitreloc emits relocation entries for go.o in external linking.
-func peemitreloc(ctxt *Link, text, data, ctors *IMAGE_SECTION_HEADER) {
+func peemitreloc(ctxt *Link, text, data, ctors *peSection) {
for coutbuf.Offset()&7 != 0 {
Cput(0)
}
for _, sect := range Segdwarf.Sections {
for i, name := range shNames {
if sect.Name == name {
- peemitsectreloc(&sh[i], func() int {
+ peemitsectreloc(pefile.sections[i], func() int {
return perelocsect(ctxt, sect, dwarfp, sect.Vaddr)
})
continue dwarfLoop
* reference: pecoff_v8.docx Page 24.
* <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
*/
-func newPEDWARFSection(ctxt *Link, name string, size int64) *IMAGE_SECTION_HEADER {
+func newPEDWARFSection(ctxt *Link, name string, size int64) *peSection {
if size == 0 {
return nil
}
off := pefile.stringTable.add(name)
- s := fmt.Sprintf("/%d", off)
- h := addpesectionWithLongName(ctxt, s, name, int(size), int(size))
+ h := pefile.addSection(name, int(size), int(size))
+ h.shortName = fmt.Sprintf("/%d", off)
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
return h
// update COFF file header and section table
size := pefile.stringTable.size() + 18*symcnt
- var h *IMAGE_SECTION_HEADER
+ var h *peSection
if Linkmode != LinkExternal {
// We do not really need .symtab for go.o, and if we have one, ld
// will also include it in the exe, and that will confuse windows.
dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h.VirtualSize
}
-func addinitarray(ctxt *Link) (c *IMAGE_SECTION_HEADER) {
+func addinitarray(ctxt *Link) (c *peSection) {
// The size below was determined by the specification for array relocations,
// and by observing what GCC writes here. If the initarray section grows to
// contain more than one constructor entry, the size will need to be 8 * constructor_count.
chksectseg(ctxt, t, &Segtext)
textsect = pensect
- var d *IMAGE_SECTION_HEADER
- var c *IMAGE_SECTION_HEADER
+ var d *peSection
+ var c *peSection
if Linkmode != LinkExternal {
d = addpesection(ctxt, ".data", int(Segdata.Length), int(Segdata.Filelen))
d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE