mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: new loader method for reading relocations in batch
Add a new loader.Relocs method that reads all of the relocations for a symbol into a slice. Handy in cases where the client knows in advance that it wants to visit all the relocations on a symbol (as opposed to just one or two). Change-Id: I1a420513e160c8bb4b90c9824ae8d5b5de060c15 Reviewed-on: https://go-review.googlesource.com/c/go/+/201721 Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jeremy Faller <jeremy@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
6ecaae0325
commit
b661547d94
1 changed files with 48 additions and 1 deletions
|
|
@ -442,6 +442,51 @@ func (relocs *Relocs) At(j int) Reloc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
if relocs.Count == 0 {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
if cap(dst) < relocs.Count {
|
||||||
|
dst = make([]Reloc, relocs.Count)
|
||||||
|
}
|
||||||
|
dst = dst[:0]
|
||||||
|
|
||||||
|
if relocs.ext != nil {
|
||||||
|
for i := 0; i < relocs.Count; i++ {
|
||||||
|
erel := &relocs.ext.R[i]
|
||||||
|
rel := Reloc{
|
||||||
|
Off: erel.Off,
|
||||||
|
Size: erel.Siz,
|
||||||
|
Type: erel.Type,
|
||||||
|
Add: erel.Add,
|
||||||
|
Sym: relocs.l.Lookup(erel.Sym.Name, int(erel.Sym.Version)),
|
||||||
|
}
|
||||||
|
dst = append(dst, rel)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
off := relocs.r.RelocOff(relocs.li, 0)
|
||||||
|
for i := 0; i < relocs.Count; i++ {
|
||||||
|
rel := goobj2.Reloc{}
|
||||||
|
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 {
|
||||||
if l.isExternal(i) {
|
if l.isExternal(i) {
|
||||||
|
|
@ -651,6 +696,7 @@ func loadObjFull(l *Loader, r *oReader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pcdataBase := r.PcdataBase()
|
pcdataBase := r.PcdataBase()
|
||||||
|
rslice := []Reloc{}
|
||||||
for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
|
for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
|
||||||
osym := goobj2.Sym{}
|
osym := goobj2.Sym{}
|
||||||
osym.Read(r.Reader, r.SymOff(i))
|
osym.Read(r.Reader, r.SymOff(i))
|
||||||
|
|
@ -692,9 +738,10 @@ func loadObjFull(l *Loader, r *oReader) {
|
||||||
|
|
||||||
// Relocs
|
// Relocs
|
||||||
relocs := l.relocs(r, i)
|
relocs := l.relocs(r, i)
|
||||||
|
rslice = relocs.ReadAll(rslice)
|
||||||
s.R = make([]sym.Reloc, relocs.Count)
|
s.R = make([]sym.Reloc, relocs.Count)
|
||||||
for j := range s.R {
|
for j := range s.R {
|
||||||
r := relocs.At(j)
|
r := rslice[j]
|
||||||
rs := r.Sym
|
rs := r.Sym
|
||||||
sz := r.Size
|
sz := r.Size
|
||||||
rt := r.Type
|
rt := r.Type
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue