]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link/internal/objfile: new loader method for reloc queries
authorThan McIntosh <thanm@google.com>
Fri, 11 Oct 2019 12:56:19 +0000 (08:56 -0400)
committerThan McIntosh <thanm@google.com>
Fri, 11 Oct 2019 15:06:34 +0000 (15:06 +0000)
Second change of several to update the loader API to reflect the final
consensus version of the loader API as described in Cherry's doc.
This piece:

 - define new loader.Relocs() method that returns a struct
   encapsulating a set of relocations on a global symbol

Old way of examining relocations:

  nreloc := loader.NReloc(someGlobalSymbolIndex)
  for i := 0; i < nreloc; i++ {
    tgtIdx := loader.RelocSym(someGlobalSymbolIndex, i))
    ... <do something with tgtIdx>
  }

New way of examining relocations:

  relocs := d.loader.Relocs(someGlobalSymbolIndex)
  for i := 0; i < relocs.Count; i++ {
    r := relocs.At(i).Sym
    ... <do something with r.Sym>
  }

Change-Id: I5bead1d729655ea13b3396647e53aafcd3e60f97
Reviewed-on: https://go-review.googlesource.com/c/go/+/200717
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/link/internal/objfile/objfile2.go

index 96d9ad1bd7207a2bdac726bea8dea2c811f4d57a..b68c07b65cdab2142732ef97e9b4a0daf73cf273 100644 (file)
@@ -27,6 +27,27 @@ var _ = fmt.Print
 // Go symbol. The 0-valued Sym is corresponds to an invalid symbol.
 type Sym int
 
+// Relocs encapsulates the set of relocations on a given symbol; an
+// instance of this type is returned by the Loader Relocs() method.
+type Relocs struct {
+       Count int // number of relocs
+
+       li int      // local index of symbol whose relocs we're examining
+       r  *oReader // object reader for containing package
+       l  *Loader  // loader
+}
+
+// Reloc contains the payload for a specific relocation.
+// TODO: replace this with sym.Reloc, once we change the
+// relocation target from "*sym.Symbol" to "loader.Sym" in sym.Reloc.
+type Reloc struct {
+       Off  int32            // offset to rewrite
+       Size uint8            // number of bytes to rewrite: 0, 1, 2, or 4
+       Type objabi.RelocType // the relocation type
+       Add  int64            // addend
+       Sym  Sym              // global index of symbol the reloc addresses
+}
+
 // oReader is a wrapper type of obj.Reader, along with some
 // extra information.
 // TODO: rename to objReader once the old one is gone?
@@ -295,6 +316,39 @@ func (l *Loader) InitReachable() {
        l.Reachable = makeBitmap(l.NSym())
 }
 
+// At method returns the j-th reloc for a global symbol.
+func (relocs *Relocs) At(j int) Reloc {
+       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,
+       }
+}
+
+// Relocs returns a Relocs object for the given global sym.
+func (l *Loader) Relocs(i Sym) Relocs {
+       r, li := l.ToLocal(i)
+       if r == nil {
+               return Relocs{}
+       }
+       return l.relocs(r, li)
+}
+
+// Relocs returns a Relocs object given a local sym index and reader.
+func (l *Loader) relocs(r *oReader, li int) Relocs {
+       return Relocs{
+               Count: r.NReloc(li),
+               li:    li,
+               r:     r,
+               l:     l,
+       }
+}
+
 // Preload a package: add autolibs, add symbols to the symbol table.
 // Does not read symbol data yet.
 func LoadNew(l *Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64, pn string, flags int) {
@@ -473,15 +527,14 @@ func loadObjReloc(l *Loader, r *oReader) {
                s.Type = t
                s.Unit = r.unit
 
-               // Reloc
-               nreloc := r.NReloc(i)
-               s.R = make([]sym.Reloc, nreloc)
+               // Relocs
+               relocs := l.relocs(r, i)
+               s.R = make([]sym.Reloc, relocs.Count)
                for j := range s.R {
-                       rel := goobj2.Reloc{}
-                       rel.Read(r.Reader, r.RelocOff(i, j))
-                       rs := l.Resolve(r, rel.Sym)
-                       rt := objabi.RelocType(rel.Type)
-                       sz := rel.Siz
+                       r := relocs.At(j)
+                       rs := r.Sym
+                       sz := r.Size
+                       rt := r.Type
                        if rt == objabi.R_METHODOFF {
                                if l.Reachable.Has(rs) {
                                        rt = objabi.R_ADDROFF
@@ -495,13 +548,14 @@ func loadObjReloc(l *Loader, r *oReader) {
                                sz = 0
                        }
                        if rs != 0 && l.SymType(rs) == sym.SABIALIAS {
-                               rs = l.RelocSym(rs, 0)
+                               rsrelocs := l.Relocs(rs)
+                               rs = rsrelocs.At(0).Sym
                        }
                        s.R[j] = sym.Reloc{
-                               Off:  rel.Off,
+                               Off:  r.Off,
                                Siz:  sz,
                                Type: rt,
-                               Add:  rel.Add,
+                               Add:  r.Add,
                                Sym:  l.Syms[rs],
                        }
                }