mirror of
https://github.com/golang/go.git
synced 2025-05-19 14:24:46 +00:00
cmd/link: introduce and use peSection.emitRelocations
Change-Id: I2bebee5566ee07786695f147c27661e69337a0f7 Reviewed-on: https://go-review.googlesource.com/59418 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
88a1e85c70
commit
04d410d6cd
@ -439,6 +439,32 @@ func (sect *peSection) write() error {
|
|||||||
return binary.Write(&coutbuf, binary.LittleEndian, h)
|
return binary.Write(&coutbuf, binary.LittleEndian, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emitRelocations emits the relocation entries for the sect.
|
||||||
|
// The actual relocations are emitted by relocfn.
|
||||||
|
// This updates the corresponding PE section table entry
|
||||||
|
// with the relocation offset and count.
|
||||||
|
func (sect *peSection) emitRelocations(relocfn func() int) {
|
||||||
|
sect.PointerToRelocations = uint32(coutbuf.Offset())
|
||||||
|
// first entry: extended relocs
|
||||||
|
Lputl(0) // placeholder for number of relocation + 1
|
||||||
|
Lputl(0)
|
||||||
|
Wputl(0)
|
||||||
|
|
||||||
|
n := relocfn() + 1
|
||||||
|
|
||||||
|
cpos := coutbuf.Offset()
|
||||||
|
Cseek(int64(sect.PointerToRelocations))
|
||||||
|
Lputl(uint32(n))
|
||||||
|
Cseek(cpos)
|
||||||
|
if n > 0x10000 {
|
||||||
|
n = 0x10000
|
||||||
|
sect.Characteristics |= IMAGE_SCN_LNK_NRELOC_OVFL
|
||||||
|
} else {
|
||||||
|
sect.PointerToRelocations += 10 // skip the extend reloc entry
|
||||||
|
}
|
||||||
|
sect.NumberOfRelocations = uint16(n - 1)
|
||||||
|
}
|
||||||
|
|
||||||
// peFile is used to build COFF file.
|
// peFile is used to build COFF file.
|
||||||
type peFile struct {
|
type peFile struct {
|
||||||
sections []*peSection
|
sections []*peSection
|
||||||
@ -950,39 +976,13 @@ func perelocsect(ctxt *Link, sect *Section, syms []*Symbol, base uint64) int {
|
|||||||
return relocs
|
return relocs
|
||||||
}
|
}
|
||||||
|
|
||||||
// peemitsectreloc emits the relocation entries for sect.
|
|
||||||
// The actual relocations are emitted by relocfn.
|
|
||||||
// This updates the corresponding PE section table entry
|
|
||||||
// with the relocation offset and count.
|
|
||||||
func peemitsectreloc(sect *peSection, relocfn func() int) {
|
|
||||||
sect.PointerToRelocations = uint32(coutbuf.Offset())
|
|
||||||
// first entry: extended relocs
|
|
||||||
Lputl(0) // placeholder for number of relocation + 1
|
|
||||||
Lputl(0)
|
|
||||||
Wputl(0)
|
|
||||||
|
|
||||||
n := relocfn() + 1
|
|
||||||
|
|
||||||
cpos := coutbuf.Offset()
|
|
||||||
Cseek(int64(sect.PointerToRelocations))
|
|
||||||
Lputl(uint32(n))
|
|
||||||
Cseek(cpos)
|
|
||||||
if n > 0x10000 {
|
|
||||||
n = 0x10000
|
|
||||||
sect.Characteristics |= IMAGE_SCN_LNK_NRELOC_OVFL
|
|
||||||
} else {
|
|
||||||
sect.PointerToRelocations += 10 // skip the extend reloc entry
|
|
||||||
}
|
|
||||||
sect.NumberOfRelocations = uint16(n - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 *peSection) {
|
func peemitreloc(ctxt *Link, text, data, ctors *peSection) {
|
||||||
for coutbuf.Offset()&7 != 0 {
|
for coutbuf.Offset()&7 != 0 {
|
||||||
Cput(0)
|
Cput(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
peemitsectreloc(text, func() int {
|
text.emitRelocations(func() int {
|
||||||
n := perelocsect(ctxt, Segtext.Sections[0], ctxt.Textp, Segtext.Vaddr)
|
n := perelocsect(ctxt, Segtext.Sections[0], ctxt.Textp, Segtext.Vaddr)
|
||||||
for _, sect := range Segtext.Sections[1:] {
|
for _, sect := range Segtext.Sections[1:] {
|
||||||
n += perelocsect(ctxt, sect, datap, Segtext.Vaddr)
|
n += perelocsect(ctxt, sect, datap, Segtext.Vaddr)
|
||||||
@ -990,7 +990,7 @@ func peemitreloc(ctxt *Link, text, data, ctors *peSection) {
|
|||||||
return n
|
return n
|
||||||
})
|
})
|
||||||
|
|
||||||
peemitsectreloc(data, func() int {
|
data.emitRelocations(func() int {
|
||||||
var n int
|
var n int
|
||||||
for _, sect := range Segdata.Sections {
|
for _, sect := range Segdata.Sections {
|
||||||
n += perelocsect(ctxt, sect, datap, Segdata.Vaddr)
|
n += perelocsect(ctxt, sect, datap, Segdata.Vaddr)
|
||||||
@ -1002,16 +1002,16 @@ dwarfLoop:
|
|||||||
for _, sect := range Segdwarf.Sections {
|
for _, sect := range Segdwarf.Sections {
|
||||||
for _, pesect := range pefile.sections {
|
for _, pesect := range pefile.sections {
|
||||||
if sect.Name == pesect.name {
|
if sect.Name == pesect.name {
|
||||||
peemitsectreloc(pesect, func() int {
|
pesect.emitRelocations(func() int {
|
||||||
return perelocsect(ctxt, sect, dwarfp, sect.Vaddr)
|
return perelocsect(ctxt, sect, dwarfp, sect.Vaddr)
|
||||||
})
|
})
|
||||||
continue dwarfLoop
|
continue dwarfLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Errorf(nil, "peemitsectreloc: could not find %q section", sect.Name)
|
Errorf(nil, "peemitreloc: could not find %q section", sect.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
peemitsectreloc(ctors, func() int {
|
ctors.emitRelocations(func() int {
|
||||||
dottext := ctxt.Syms.Lookup(".text", 0)
|
dottext := ctxt.Syms.Lookup(".text", 0)
|
||||||
Lputl(0)
|
Lputl(0)
|
||||||
Lputl(uint32(dottext.Dynid))
|
Lputl(uint32(dottext.Dynid))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user