cmd/internal/goobj: store relocation type as uint16

Currently, relocation type is stored as uint8 in object files, as
Go relocations do not exceed 255. In the linker, however, it is
used as a 16-bit type, because external relocations can exceed
255. The linker has to store the extra byte in a side table. This
complicates many things.

Just store it as uint16 in object files. This simplifies things,
with a small cost of increasing the object file sizes.

               before      after
hello.o         1672        1678
runtime.a    7927784     8056194

Change-Id: I313cf44ad0b8b3b76e35055ae55d911ff35e3158
Reviewed-on: https://go-review.googlesource.com/c/go/+/268477
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2020-11-08 11:27:53 -05:00
parent 87d29939c8
commit f901ea701d
6 changed files with 40 additions and 64 deletions

View file

@ -51,30 +51,13 @@ type Reloc struct {
*goobj.Reloc
r *oReader
l *Loader
// External reloc types may not fit into a uint8 which the Go object file uses.
// Store it here, instead of in the byte of goobj.Reloc.
// For Go symbols this will always be zero.
// goobj.Reloc.Type() + typ is always the right type, for both Go and external
// symbols.
typ objabi.RelocType
}
func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) + rel.typ }
func (rel Reloc) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
func (rel Reloc) SetSym(s Sym) { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
func (rel Reloc) IsMarker() bool { return rel.Siz() == 0 }
func (rel Reloc) SetType(t objabi.RelocType) {
if t != objabi.RelocType(uint8(t)) {
panic("SetType: type doesn't fit into Reloc")
}
rel.Reloc.SetType(uint8(t))
if rel.typ != 0 {
// should use SymbolBuilder.SetRelocType
panic("wrong method to set reloc type")
}
}
func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) }
func (rel Reloc) SetType(t objabi.RelocType) { rel.Reloc.SetType(uint16(t)) }
func (rel Reloc) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
func (rel Reloc) SetSym(s Sym) { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
func (rel Reloc) IsMarker() bool { return rel.Siz() == 0 }
// Aux holds a "handle" to access an aux symbol record from an
// object file.
@ -307,15 +290,14 @@ type elfsetstringFunc func(str string, off int)
// extSymPayload holds the payload (data + relocations) for linker-synthesized
// external symbols (note that symbol value is stored in a separate slice).
type extSymPayload struct {
name string // TODO: would this be better as offset into str table?
size int64
ver int
kind sym.SymKind
objidx uint32 // index of original object if sym made by cloneToExternal
relocs []goobj.Reloc
reltypes []objabi.RelocType // relocation types
data []byte
auxs []goobj.Aux
name string // TODO: would this be better as offset into str table?
size int64
ver int
kind sym.SymKind
objidx uint32 // index of original object if sym made by cloneToExternal
relocs []goobj.Reloc
data []byte
auxs []goobj.Aux
}
const (
@ -1833,10 +1815,9 @@ func (relocs *Relocs) Count() int { return len(relocs.rs) }
// At 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 Reloc{&relocs.rs[j], relocs.r, relocs.l, pp.reltypes[j]}
return Reloc{&relocs.rs[j], relocs.r, relocs.l}
}
return Reloc{&relocs.rs[j], relocs.r, relocs.l, 0}
return Reloc{&relocs.rs[j], relocs.r, relocs.l}
}
// Relocs returns a Relocs object for the given global sym.
@ -2337,13 +2318,11 @@ func (l *Loader) cloneToExternal(symIdx Sym) {
// Copy relocations
relocs := l.Relocs(symIdx)
pp.relocs = make([]goobj.Reloc, 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.At(i)
pp.relocs[i].Set(rel.Off(), rel.Siz(), 0, rel.Add(), goobj.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
pp.reltypes[i] = rel.Type()
pp.relocs[i].Set(rel.Off(), rel.Siz(), uint16(rel.Type()), rel.Add(), goobj.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
}
// Copy data