mirror of
https://github.com/golang/go
synced 2024-11-19 14:54:43 -07:00
cmd/link: use peSection everywhere
Change-Id: I4d4e8452b9b9e628f3ea8b2b727ad63ec2a1dd31 Reviewed-on: https://go-review.googlesource.com/55259 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
2c2b172377
commit
babc5b1dd6
@ -65,19 +65,6 @@ type IMAGE_OPTIONAL_HEADER struct {
|
|||||||
DataDirectory [16]IMAGE_DATA_DIRECTORY
|
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 {
|
type IMAGE_IMPORT_DESCRIPTOR struct {
|
||||||
OriginalFirstThunk uint32
|
OriginalFirstThunk uint32
|
||||||
TimeDateStamp uint32
|
TimeDateStamp uint32
|
||||||
@ -353,8 +340,6 @@ var oh IMAGE_OPTIONAL_HEADER
|
|||||||
|
|
||||||
var oh64 PE64_IMAGE_OPTIONAL_HEADER
|
var oh64 PE64_IMAGE_OPTIONAL_HEADER
|
||||||
|
|
||||||
var sh [16]IMAGE_SECTION_HEADER
|
|
||||||
|
|
||||||
// shNames stores full names of PE sections stored in sh.
|
// shNames stores full names of PE sections stored in sh.
|
||||||
var shNames []string
|
var shNames []string
|
||||||
|
|
||||||
@ -465,52 +450,31 @@ func (f *peFile) addSection(name string, sectsize int, filesize int) *peSection
|
|||||||
}
|
}
|
||||||
f.sections = append(f.sections, sect)
|
f.sections = append(f.sections, sect)
|
||||||
pensect++
|
pensect++
|
||||||
|
shNames = append(shNames, name)
|
||||||
return sect
|
return sect
|
||||||
}
|
}
|
||||||
|
|
||||||
var pefile peFile
|
var pefile peFile
|
||||||
|
|
||||||
func addpesectionWithLongName(ctxt *Link, shortname, longname string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
|
func addpesection(ctxt *Link, name string, sectsize int, filesize int) *peSection {
|
||||||
if pensect == 16 {
|
return pefile.addSection(name, sectsize, filesize)
|
||||||
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 {
|
func chksectoff(ctxt *Link, h *peSection, off int64) {
|
||||||
return addpesectionWithLongName(ctxt, name, name, sectsize, filesize)
|
|
||||||
}
|
|
||||||
|
|
||||||
func chksectoff(ctxt *Link, h *IMAGE_SECTION_HEADER, off int64) {
|
|
||||||
if off != int64(h.PointerToRawData) {
|
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()
|
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) {
|
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()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Fileoff != uint64(h.PointerToRawData) {
|
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()
|
errorexit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,6 +502,7 @@ func Peinit(ctxt *Link) {
|
|||||||
PEFILEALIGN = 0
|
PEFILEALIGN = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sh [16]pe.SectionHeader32
|
||||||
PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN))
|
PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN))
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN))
|
PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN))
|
||||||
@ -582,12 +547,9 @@ func pewrite() {
|
|||||||
} else {
|
} else {
|
||||||
binary.Write(&coutbuf, binary.LittleEndian, &oh)
|
binary.Write(&coutbuf, binary.LittleEndian, &oh)
|
||||||
}
|
}
|
||||||
if Linkmode == LinkExternal {
|
for _, sect := range pefile.sections {
|
||||||
for i := range sh[:pensect] {
|
sect.write()
|
||||||
sh[i].VirtualAddress = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
binary.Write(&coutbuf, binary.LittleEndian, sh[:pensect])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func strput(s string) {
|
func strput(s string) {
|
||||||
@ -696,7 +658,7 @@ func peimporteddlls() []string {
|
|||||||
return dlls
|
return dlls
|
||||||
}
|
}
|
||||||
|
|
||||||
func addimports(ctxt *Link, datsect *IMAGE_SECTION_HEADER) {
|
func addimports(ctxt *Link, datsect *peSection) {
|
||||||
startoff := coutbuf.Offset()
|
startoff := coutbuf.Offset()
|
||||||
dynamic := ctxt.Syms.Lookup(".windynamic", 0)
|
dynamic := ctxt.Syms.Lookup(".windynamic", 0)
|
||||||
|
|
||||||
@ -947,7 +909,7 @@ func perelocsect(ctxt *Link, sect *Section, syms []*Symbol, base uint64) int {
|
|||||||
// The actual relocations are emitted by relocfn.
|
// The actual relocations are emitted by relocfn.
|
||||||
// This updates the corresponding PE section table entry
|
// This updates the corresponding PE section table entry
|
||||||
// with the relocation offset and count.
|
// 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())
|
sect.PointerToRelocations = uint32(coutbuf.Offset())
|
||||||
// first entry: extended relocs
|
// first entry: extended relocs
|
||||||
Lputl(0) // placeholder for number of relocation + 1
|
Lputl(0) // placeholder for number of relocation + 1
|
||||||
@ -970,7 +932,7 @@ func peemitsectreloc(sect *IMAGE_SECTION_HEADER, relocfn func() int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// peemitreloc emits relocation entries for go.o in external linking.
|
// 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 {
|
for coutbuf.Offset()&7 != 0 {
|
||||||
Cput(0)
|
Cput(0)
|
||||||
}
|
}
|
||||||
@ -995,7 +957,7 @@ dwarfLoop:
|
|||||||
for _, sect := range Segdwarf.Sections {
|
for _, sect := range Segdwarf.Sections {
|
||||||
for i, name := range shNames {
|
for i, name := range shNames {
|
||||||
if sect.Name == name {
|
if sect.Name == name {
|
||||||
peemitsectreloc(&sh[i], func() int {
|
peemitsectreloc(pefile.sections[i], func() int {
|
||||||
return perelocsect(ctxt, sect, dwarfp, sect.Vaddr)
|
return perelocsect(ctxt, sect, dwarfp, sect.Vaddr)
|
||||||
})
|
})
|
||||||
continue dwarfLoop
|
continue dwarfLoop
|
||||||
@ -1038,14 +1000,14 @@ func (ctxt *Link) dope() {
|
|||||||
* reference: pecoff_v8.docx Page 24.
|
* reference: pecoff_v8.docx Page 24.
|
||||||
* <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
|
* <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 {
|
if size == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
off := pefile.stringTable.add(name)
|
off := pefile.stringTable.add(name)
|
||||||
s := fmt.Sprintf("/%d", off)
|
h := pefile.addSection(name, int(size), int(size))
|
||||||
h := addpesectionWithLongName(ctxt, s, name, int(size), int(size))
|
h.shortName = fmt.Sprintf("/%d", off)
|
||||||
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
|
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
|
||||||
|
|
||||||
return h
|
return h
|
||||||
@ -1154,7 +1116,7 @@ func addpesymtable(ctxt *Link) {
|
|||||||
|
|
||||||
// update COFF file header and section table
|
// update COFF file header and section table
|
||||||
size := pefile.stringTable.size() + 18*symcnt
|
size := pefile.stringTable.size() + 18*symcnt
|
||||||
var h *IMAGE_SECTION_HEADER
|
var h *peSection
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
// We do not really need .symtab for go.o, and if we have one, ld
|
// 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.
|
// will also include it in the exe, and that will confuse windows.
|
||||||
@ -1215,7 +1177,7 @@ func addpersrc(ctxt *Link) {
|
|||||||
dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h.VirtualSize
|
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,
|
// The size below was determined by the specification for array relocations,
|
||||||
// and by observing what GCC writes here. If the initarray section grows to
|
// 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.
|
// contain more than one constructor entry, the size will need to be 8 * constructor_count.
|
||||||
@ -1271,8 +1233,8 @@ func Asmbpe(ctxt *Link) {
|
|||||||
chksectseg(ctxt, t, &Segtext)
|
chksectseg(ctxt, t, &Segtext)
|
||||||
textsect = pensect
|
textsect = pensect
|
||||||
|
|
||||||
var d *IMAGE_SECTION_HEADER
|
var d *peSection
|
||||||
var c *IMAGE_SECTION_HEADER
|
var c *peSection
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
d = addpesection(ctxt, ".data", int(Segdata.Length), int(Segdata.Filelen))
|
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
|
d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
|
||||||
|
Loading…
Reference in New Issue
Block a user