mirror of
https://github.com/golang/go.git
synced 2025-05-29 03:11:26 +00:00
[dev.link] cmd/link: store external relocations in Reloc2 format
Store external relocations in (almost) the same format as the Go objects, so we can handle them more uniformly. There is a small speedup: (linking cmd/compile) Deadcode 67.8ms ± 3% 61.1ms ± 3% -9.94% (p=0.008 n=5+5) Dostkcheck 41.2ms ± 2% 38.8ms ± 3% -5.99% (p=0.008 n=5+5) Change-Id: I8616e10b26235904201d6c9465f5ae32a49c9949 Reviewed-on: https://go-review.googlesource.com/c/go/+/226365 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
aef23f5be9
commit
6e3bde5f30
@ -321,13 +321,21 @@ func (r *Reloc2) Sym() SymRef {
|
|||||||
return SymRef{binary.LittleEndian.Uint32(r[14:]), binary.LittleEndian.Uint32(r[18:])}
|
return SymRef{binary.LittleEndian.Uint32(r[14:]), binary.LittleEndian.Uint32(r[18:])}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Reloc2) SetOff(x int32) { binary.LittleEndian.PutUint32(r[:], uint32(x)) }
|
||||||
|
func (r *Reloc2) SetSiz(x uint8) { r[4] = x }
|
||||||
|
func (r *Reloc2) SetType(x uint8) { r[5] = x }
|
||||||
|
func (r *Reloc2) SetAdd(x int64) { binary.LittleEndian.PutUint64(r[6:], uint64(x)) }
|
||||||
|
func (r *Reloc2) SetSym(x SymRef) {
|
||||||
|
binary.LittleEndian.PutUint32(r[14:], x.PkgIdx)
|
||||||
|
binary.LittleEndian.PutUint32(r[18:], x.SymIdx)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Reloc2) Set(off int32, size uint8, typ uint8, add int64, sym SymRef) {
|
func (r *Reloc2) Set(off int32, size uint8, typ uint8, add int64, sym SymRef) {
|
||||||
binary.LittleEndian.PutUint32(r[:], uint32(off))
|
r.SetOff(off)
|
||||||
r[4] = size
|
r.SetSiz(size)
|
||||||
r[5] = typ
|
r.SetType(typ)
|
||||||
binary.LittleEndian.PutUint64(r[6:], uint64(add))
|
r.SetAdd(add)
|
||||||
binary.LittleEndian.PutUint32(r[14:], sym.PkgIdx)
|
r.SetSym(sym)
|
||||||
binary.LittleEndian.PutUint32(r[18:], sym.SymIdx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aux symbol info.
|
// Aux symbol info.
|
||||||
|
@ -602,7 +602,6 @@ func (ctxt *Link) reloc() {
|
|||||||
|
|
||||||
func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) {
|
func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) {
|
||||||
var su *loader.SymbolBuilder
|
var su *loader.SymbolBuilder
|
||||||
var rslice []loader.Reloc
|
|
||||||
relocs := ctxt.loader.Relocs(s)
|
relocs := ctxt.loader.Relocs(s)
|
||||||
for ri := 0; ri < relocs.Count; ri++ {
|
for ri := 0; ri < relocs.Count; ri++ {
|
||||||
r := relocs.At2(ri)
|
r := relocs.At2(ri)
|
||||||
@ -627,11 +626,9 @@ func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) {
|
|||||||
|
|
||||||
if su == nil {
|
if su == nil {
|
||||||
su = ctxt.loader.MakeSymbolUpdater(s)
|
su = ctxt.loader.MakeSymbolUpdater(s)
|
||||||
rslice = su.Relocs()
|
|
||||||
}
|
}
|
||||||
r := &rslice[ri]
|
r.SetSym(rel.Sym())
|
||||||
r.Sym = rel.Sym()
|
r.SetAdd(int64(tplt))
|
||||||
r.Add = int64(tplt)
|
|
||||||
|
|
||||||
// jmp *addr
|
// jmp *addr
|
||||||
switch ctxt.Arch.Family {
|
switch ctxt.Arch.Family {
|
||||||
@ -654,11 +651,9 @@ func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) {
|
|||||||
} else if tplt >= 0 {
|
} else if tplt >= 0 {
|
||||||
if su == nil {
|
if su == nil {
|
||||||
su = ctxt.loader.MakeSymbolUpdater(s)
|
su = ctxt.loader.MakeSymbolUpdater(s)
|
||||||
rslice = su.Relocs()
|
|
||||||
}
|
}
|
||||||
r := &rslice[ri]
|
r.SetSym(rel.Sym())
|
||||||
r.Sym = rel.Sym()
|
r.SetAdd(int64(tplt))
|
||||||
r.Add = int64(tplt)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,16 +132,9 @@ func (c dwctxt2) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int6
|
|||||||
switch size {
|
switch size {
|
||||||
default:
|
default:
|
||||||
c.linkctxt.Errorf(ds, "invalid size %d in adddwarfref\n", size)
|
c.linkctxt.Errorf(ds, "invalid size %d in adddwarfref\n", size)
|
||||||
fallthrough
|
case c.arch.PtrSize, 4:
|
||||||
case c.arch.PtrSize:
|
|
||||||
dsu.AddAddrPlus(c.arch, tds, 0)
|
|
||||||
case 4:
|
|
||||||
dsu.AddAddrPlus4(c.arch, tds, 0)
|
|
||||||
}
|
}
|
||||||
rsl := dsu.Relocs()
|
dsu.AddSymRef(c.arch, tds, ofs, objabi.R_ADDROFF, size)
|
||||||
r := &rsl[len(rsl)-1]
|
|
||||||
r.Type = objabi.R_ADDROFF
|
|
||||||
r.Add = ofs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c dwctxt2) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
|
func (c dwctxt2) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
|
||||||
@ -149,14 +142,15 @@ func (c dwctxt2) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64
|
|||||||
if isDwarf64(c.linkctxt) {
|
if isDwarf64(c.linkctxt) {
|
||||||
size = 8
|
size = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
c.AddSectionOffset(s, size, t, ofs)
|
|
||||||
|
|
||||||
ds := loader.Sym(s.(dwSym))
|
ds := loader.Sym(s.(dwSym))
|
||||||
dsu := c.ldr.MakeSymbolUpdater(ds)
|
dsu := c.ldr.MakeSymbolUpdater(ds)
|
||||||
rsl := dsu.Relocs()
|
tds := loader.Sym(t.(dwSym))
|
||||||
r := &rsl[len(rsl)-1]
|
switch size {
|
||||||
r.Type = objabi.R_DWARFSECREF
|
default:
|
||||||
|
c.linkctxt.Errorf(ds, "invalid size %d in adddwarfref\n", size)
|
||||||
|
case c.arch.PtrSize, 4:
|
||||||
|
}
|
||||||
|
dsu.AddSymRef(c.arch, tds, ofs, objabi.R_DWARFSECREF, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c dwctxt2) Logf(format string, args ...interface{}) {
|
func (c dwctxt2) Logf(format string, args ...interface{}) {
|
||||||
@ -345,15 +339,9 @@ func (d *dwctxt2) adddwarfref(sb *loader.SymbolBuilder, t loader.Sym, size int)
|
|||||||
switch size {
|
switch size {
|
||||||
default:
|
default:
|
||||||
d.linkctxt.Errorf(sb.Sym(), "invalid size %d in adddwarfref\n", size)
|
d.linkctxt.Errorf(sb.Sym(), "invalid size %d in adddwarfref\n", size)
|
||||||
fallthrough
|
case d.arch.PtrSize, 4:
|
||||||
case d.arch.PtrSize:
|
|
||||||
result = sb.AddAddrPlus(d.arch, t, 0)
|
|
||||||
case 4:
|
|
||||||
result = sb.AddAddrPlus4(d.arch, t, 0)
|
|
||||||
}
|
}
|
||||||
rsl := sb.Relocs()
|
result = sb.AddSymRef(d.arch, t, 0, objabi.R_DWARFSECREF, size)
|
||||||
r := &rsl[len(rsl)-1]
|
|
||||||
r.Type = objabi.R_DWARFSECREF
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,14 @@ type Reloc2 struct {
|
|||||||
|
|
||||||
func (rel Reloc2) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc2.Type()) + rel.typ }
|
func (rel Reloc2) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc2.Type()) + rel.typ }
|
||||||
func (rel Reloc2) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc2.Sym()) }
|
func (rel Reloc2) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc2.Sym()) }
|
||||||
|
func (rel Reloc2) SetSym(s Sym) { rel.Reloc2.SetSym(goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
|
||||||
|
|
||||||
|
func (rel Reloc2) SetType(t objabi.RelocType) {
|
||||||
|
if t != objabi.RelocType(uint8(t)) {
|
||||||
|
panic("SetType: type doesn't fit into Reloc2")
|
||||||
|
}
|
||||||
|
rel.Reloc2.SetType(uint8(t))
|
||||||
|
}
|
||||||
|
|
||||||
// Aux2 holds a "handle" to access an aux symbol record from an
|
// Aux2 holds a "handle" to access an aux symbol record from an
|
||||||
// object file.
|
// object file.
|
||||||
@ -269,14 +277,15 @@ type elfsetstringFunc func(s *sym.Symbol, str string, off int)
|
|||||||
// extSymPayload holds the payload (data + relocations) for linker-synthesized
|
// extSymPayload holds the payload (data + relocations) for linker-synthesized
|
||||||
// external symbols (note that symbol value is stored in a separate slice).
|
// external symbols (note that symbol value is stored in a separate slice).
|
||||||
type extSymPayload struct {
|
type extSymPayload struct {
|
||||||
name string // TODO: would this be better as offset into str table?
|
name string // TODO: would this be better as offset into str table?
|
||||||
size int64
|
size int64
|
||||||
ver int
|
ver int
|
||||||
kind sym.SymKind
|
kind sym.SymKind
|
||||||
objidx uint32 // index of original object if sym made by cloneToExternal
|
objidx uint32 // index of original object if sym made by cloneToExternal
|
||||||
gotype Sym // Gotype (0 if not present)
|
gotype Sym // Gotype (0 if not present)
|
||||||
relocs []Reloc
|
relocs []goobj2.Reloc2
|
||||||
data []byte
|
reltypes []objabi.RelocType // relocation types
|
||||||
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -1468,91 +1477,15 @@ func (l *Loader) growExtAttrBitmaps() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// At method returns the j-th reloc for a global symbol.
|
// At2 returns the j-th reloc for a global symbol.
|
||||||
func (relocs *Relocs) At(j int) Reloc {
|
|
||||||
if relocs.l.isExtReader(relocs.r) {
|
|
||||||
pp := relocs.l.payloads[relocs.li]
|
|
||||||
return pp.relocs[j]
|
|
||||||
}
|
|
||||||
rel := goobj2.Reloc{}
|
|
||||||
rel.Read(relocs.r.Reader, relocs.r.RelocOff(relocs.li, j))
|
|
||||||
target := relocs.l.resolve(relocs.r, rel.Sym)
|
|
||||||
return Reloc{
|
|
||||||
Off: rel.Off,
|
|
||||||
Size: rel.Siz,
|
|
||||||
Type: objabi.RelocType(rel.Type),
|
|
||||||
Add: rel.Add,
|
|
||||||
Sym: target,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (relocs *Relocs) At2(j int) Reloc2 {
|
func (relocs *Relocs) At2(j int) Reloc2 {
|
||||||
if relocs.l.isExtReader(relocs.r) {
|
if relocs.l.isExtReader(relocs.r) {
|
||||||
pp := relocs.l.payloads[relocs.li]
|
pp := relocs.l.payloads[relocs.li]
|
||||||
r := pp.relocs[j]
|
return Reloc2{&relocs.rs[j], relocs.r, relocs.l, pp.reltypes[j]}
|
||||||
// XXX populate a goobj2.Reloc from external reloc record.
|
|
||||||
// Ugly. Maybe we just want to use this format to store the
|
|
||||||
// reloc record in the first place?
|
|
||||||
// Also there is more speedup if we could remove the
|
|
||||||
// conditional here.
|
|
||||||
var b goobj2.Reloc2
|
|
||||||
b.Set(r.Off, r.Size, 0, r.Add, goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(r.Sym)})
|
|
||||||
return Reloc2{&b, relocs.r, relocs.l, r.Type}
|
|
||||||
}
|
}
|
||||||
return Reloc2{&relocs.rs[j], relocs.r, relocs.l, 0}
|
return Reloc2{&relocs.rs[j], relocs.r, relocs.l, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAll method reads all relocations for a symbol into the
|
|
||||||
// specified slice. If the slice capacity is not large enough, a new
|
|
||||||
// larger slice will be allocated. Final slice is returned.
|
|
||||||
func (relocs *Relocs) ReadAll(dst []Reloc) []Reloc {
|
|
||||||
return relocs.readAll(dst, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadSyms method reads all relocation target symbols and reloc types
|
|
||||||
// for a symbol into the specified slice. It is like ReadAll but only
|
|
||||||
// fill in the Sym and Type fields.
|
|
||||||
func (relocs *Relocs) ReadSyms(dst []Reloc) []Reloc {
|
|
||||||
return relocs.readAll(dst, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (relocs *Relocs) readAll(dst []Reloc, onlySymType bool) []Reloc {
|
|
||||||
if relocs.Count == 0 {
|
|
||||||
return dst[:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if cap(dst) < relocs.Count {
|
|
||||||
dst = make([]Reloc, relocs.Count)
|
|
||||||
}
|
|
||||||
dst = dst[:0]
|
|
||||||
|
|
||||||
if relocs.l.isExtReader(relocs.r) {
|
|
||||||
pp := relocs.l.payloads[relocs.li]
|
|
||||||
dst = append(dst, pp.relocs...)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
off := relocs.r.RelocOff(relocs.li, 0)
|
|
||||||
rel := goobj2.Reloc{}
|
|
||||||
for i := 0; i < relocs.Count; i++ {
|
|
||||||
if onlySymType {
|
|
||||||
rel.ReadSymType(relocs.r.Reader, off)
|
|
||||||
} else {
|
|
||||||
rel.Read(relocs.r.Reader, off)
|
|
||||||
}
|
|
||||||
off += uint32(rel.Size())
|
|
||||||
target := relocs.l.resolve(relocs.r, rel.Sym)
|
|
||||||
dst = append(dst, Reloc{
|
|
||||||
Off: rel.Off,
|
|
||||||
Size: rel.Siz,
|
|
||||||
Type: objabi.RelocType(rel.Type),
|
|
||||||
Add: rel.Add,
|
|
||||||
Sym: target,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Relocs returns a Relocs object for the given global sym.
|
// Relocs returns a Relocs object for the given global sym.
|
||||||
func (l *Loader) Relocs(i Sym) Relocs {
|
func (l *Loader) Relocs(i Sym) Relocs {
|
||||||
r, li := l.toLocal(i)
|
r, li := l.toLocal(i)
|
||||||
@ -1569,6 +1502,7 @@ func (l *Loader) relocs(r *oReader, li int) Relocs {
|
|||||||
if l.isExtReader(r) {
|
if l.isExtReader(r) {
|
||||||
pp := l.payloads[li]
|
pp := l.payloads[li]
|
||||||
n = len(pp.relocs)
|
n = len(pp.relocs)
|
||||||
|
rs = pp.relocs
|
||||||
} else {
|
} else {
|
||||||
rs = r.Relocs2(li)
|
rs = r.Relocs2(li)
|
||||||
n = len(rs)
|
n = len(rs)
|
||||||
@ -2237,7 +2171,15 @@ func (l *Loader) cloneToExternal(symIdx Sym) {
|
|||||||
|
|
||||||
// Copy relocations
|
// Copy relocations
|
||||||
relocs := l.Relocs(symIdx)
|
relocs := l.Relocs(symIdx)
|
||||||
pp.relocs = relocs.ReadAll(nil)
|
pp.relocs = make([]goobj2.Reloc2, relocs.Count)
|
||||||
|
pp.reltypes = make([]objabi.RelocType, relocs.Count)
|
||||||
|
for i := range pp.relocs {
|
||||||
|
// Copy the relocs slice.
|
||||||
|
// Convert local reference to global reference.
|
||||||
|
rel := relocs.At2(i)
|
||||||
|
pp.relocs[i].Set(rel.Off(), rel.Siz(), 0, rel.Add(), goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
|
||||||
|
pp.reltypes[i] = rel.Type()
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data
|
// Copy data
|
||||||
pp.data = r.Data(li)
|
pp.data = r.Data(li)
|
||||||
@ -2634,7 +2576,7 @@ func (l *Loader) convertRelocations(src *Relocs, dst *sym.Symbol, strict bool) {
|
|||||||
}
|
}
|
||||||
if rs != 0 && l.Syms[rs] != nil && l.Syms[rs].Type == sym.SABIALIAS {
|
if rs != 0 && l.Syms[rs] != nil && l.Syms[rs].Type == sym.SABIALIAS {
|
||||||
rsrelocs := l.Relocs(rs)
|
rsrelocs := l.Relocs(rs)
|
||||||
rs = rsrelocs.At(0).Sym
|
rs = rsrelocs.At2(0).Sym()
|
||||||
}
|
}
|
||||||
if strict && rs != 0 && l.Syms[rs] == nil && rt != objabi.R_USETYPE {
|
if strict && rs != 0 && l.Syms[rs] == nil && rt != objabi.R_USETYPE {
|
||||||
panic("nil reloc target in convertRelocations")
|
panic("nil reloc target in convertRelocations")
|
||||||
@ -2659,14 +2601,13 @@ func (l *Loader) convertRelocations(src *Relocs, dst *sym.Symbol, strict bool) {
|
|||||||
// results returned; if "limit" is -1, then all undefs are returned.
|
// results returned; if "limit" is -1, then all undefs are returned.
|
||||||
func (l *Loader) UndefinedRelocTargets(limit int) []Sym {
|
func (l *Loader) UndefinedRelocTargets(limit int) []Sym {
|
||||||
result := []Sym{}
|
result := []Sym{}
|
||||||
rslice := []Reloc{}
|
|
||||||
for si := Sym(1); si < Sym(len(l.objSyms)); si++ {
|
for si := Sym(1); si < Sym(len(l.objSyms)); si++ {
|
||||||
relocs := l.Relocs(si)
|
relocs := l.Relocs(si)
|
||||||
rslice = relocs.ReadSyms(rslice)
|
|
||||||
for ri := 0; ri < relocs.Count; ri++ {
|
for ri := 0; ri < relocs.Count; ri++ {
|
||||||
r := &rslice[ri]
|
r := relocs.At2(ri)
|
||||||
if r.Sym != 0 && l.SymType(r.Sym) == sym.SXREF && l.RawSymName(r.Sym) != ".got" {
|
rs := r.Sym()
|
||||||
result = append(result, r.Sym)
|
if rs != 0 && l.SymType(rs) == sym.SXREF && l.RawSymName(rs) != ".got" {
|
||||||
|
result = append(result, rs)
|
||||||
if limit != -1 && len(result) >= limit {
|
if limit != -1 && len(result) >= limit {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -173,14 +173,9 @@ func TestAddMaterializedSymbol(t *testing.T) {
|
|||||||
for k, sb := range []*SymbolBuilder{sb1, sb2} {
|
for k, sb := range []*SymbolBuilder{sb1, sb2} {
|
||||||
rsl := sb.Relocs()
|
rsl := sb.Relocs()
|
||||||
exp := expRel[k]
|
exp := expRel[k]
|
||||||
if !sameRelocSlice(rsl, exp) {
|
if !sameRelocSlice(&rsl, exp) {
|
||||||
t.Errorf("expected relocs %v, got %v", exp, rsl)
|
t.Errorf("expected relocs %v, got %v", exp, rsl)
|
||||||
}
|
}
|
||||||
relocs := ldr.Relocs(sb.Sym())
|
|
||||||
r0 := relocs.At(0)
|
|
||||||
if r0 != exp[0] {
|
|
||||||
t.Errorf("expected reloc %v, got %v", exp[0], r0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... then data.
|
// ... then data.
|
||||||
@ -213,12 +208,18 @@ func TestAddMaterializedSymbol(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sameRelocSlice(s1 []Reloc, s2 []Reloc) bool {
|
func sameRelocSlice(s1 *Relocs, s2 []Reloc) bool {
|
||||||
if len(s1) != len(s2) {
|
if s1.Count != len(s2) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for i := 0; i < len(s1); i++ {
|
for i := 0; i < s1.Count; i++ {
|
||||||
if s1[i] != s2[i] {
|
r1 := s1.At2(i)
|
||||||
|
r2 := &s2[i]
|
||||||
|
if r1.Sym() != r2.Sym ||
|
||||||
|
r1.Type() != r2.Type ||
|
||||||
|
r1.Off() != r2.Off ||
|
||||||
|
r1.Add() != r2.Add ||
|
||||||
|
r1.Siz() != r2.Size {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,10 +343,9 @@ func TestAddDataMethods(t *testing.T) {
|
|||||||
t.Fatalf("testing Loader.%s: sym updated should be reachable", tp.which)
|
t.Fatalf("testing Loader.%s: sym updated should be reachable", tp.which)
|
||||||
}
|
}
|
||||||
relocs := ldr.Relocs(mi)
|
relocs := ldr.Relocs(mi)
|
||||||
rsl := relocs.ReadAll(nil)
|
if !sameRelocSlice(&relocs, tp.expRel) {
|
||||||
if !sameRelocSlice(rsl, tp.expRel) {
|
|
||||||
t.Fatalf("testing Loader.%s: got relocslice %+v wanted %+v",
|
t.Fatalf("testing Loader.%s: got relocslice %+v wanted %+v",
|
||||||
tp.which, rsl, tp.expRel)
|
tp.which, relocs, tp.expRel)
|
||||||
}
|
}
|
||||||
pmi = mi
|
pmi = mi
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package loader
|
package loader
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/internal/goobj2"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
@ -121,23 +122,37 @@ func (sb *SymbolBuilder) AddBytes(data []byte) {
|
|||||||
sb.size = int64(len(sb.data))
|
sb.size = int64(len(sb.data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SymbolBuilder) Relocs() []Reloc {
|
func (sb *SymbolBuilder) Relocs() Relocs {
|
||||||
return sb.relocs
|
return sb.l.Relocs(sb.symIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SymbolBuilder) SetRelocs(rslice []Reloc) {
|
func (sb *SymbolBuilder) SetRelocs(rslice []Reloc) {
|
||||||
sb.relocs = rslice
|
n := len(rslice)
|
||||||
}
|
if cap(sb.relocs) < n {
|
||||||
|
sb.relocs = make([]goobj2.Reloc2, n)
|
||||||
func (sb *SymbolBuilder) WriteRelocs(rslice []Reloc) {
|
sb.reltypes = make([]objabi.RelocType, n)
|
||||||
if len(sb.relocs) != len(rslice) {
|
} else {
|
||||||
panic("src/dest length mismatch")
|
sb.relocs = sb.relocs[:n]
|
||||||
|
sb.reltypes = sb.reltypes[:n]
|
||||||
|
}
|
||||||
|
for i := range rslice {
|
||||||
|
sb.SetReloc(i, rslice[i])
|
||||||
}
|
}
|
||||||
copy(sb.relocs, rslice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SymbolBuilder) AddReloc(r Reloc) {
|
func (sb *SymbolBuilder) AddReloc(r Reloc) {
|
||||||
sb.relocs = append(sb.relocs, r)
|
// Populate a goobj2.Reloc from external reloc record.
|
||||||
|
var b goobj2.Reloc2
|
||||||
|
b.Set(r.Off, r.Size, 0, r.Add, goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(r.Sym)})
|
||||||
|
sb.relocs = append(sb.relocs, b)
|
||||||
|
sb.reltypes = append(sb.reltypes, r.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the j-th relocation in place.
|
||||||
|
func (sb *SymbolBuilder) SetReloc(j int, r Reloc) {
|
||||||
|
// Populate a goobj2.Reloc from external reloc record.
|
||||||
|
sb.relocs[j].Set(r.Off, r.Size, 0, r.Add, goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(r.Sym)})
|
||||||
|
sb.reltypes[j] = r.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SymbolBuilder) Reachable() bool {
|
func (sb *SymbolBuilder) Reachable() bool {
|
||||||
@ -277,11 +292,6 @@ func (sb *SymbolBuilder) Addstring(str string) int64 {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SymbolBuilder) addRel() *Reloc {
|
|
||||||
sb.relocs = append(sb.relocs, Reloc{})
|
|
||||||
return &sb.relocs[len(sb.relocs)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
||||||
if sb.kind == 0 {
|
if sb.kind == 0 {
|
||||||
sb.kind = sym.SDATA
|
sb.kind = sym.SDATA
|
||||||
@ -291,12 +301,13 @@ func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsi
|
|||||||
sb.size += int64(rsize)
|
sb.size += int64(rsize)
|
||||||
sb.Grow(sb.size)
|
sb.Grow(sb.size)
|
||||||
|
|
||||||
r := sb.addRel()
|
var r Reloc
|
||||||
r.Sym = tgt
|
r.Sym = tgt
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Size = uint8(rsize)
|
r.Size = uint8(rsize)
|
||||||
r.Type = typ
|
r.Type = typ
|
||||||
r.Add = add
|
r.Add = add
|
||||||
|
sb.AddReloc(r)
|
||||||
|
|
||||||
return i + int64(r.Size)
|
return i + int64(r.Size)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user