diff options
| author | Cherry Zhang <cherryyz@google.com> | 2020-11-08 11:27:53 -0500 |
|---|---|---|
| committer | Cherry Zhang <cherryyz@google.com> | 2021-03-05 23:34:43 +0000 |
| commit | f901ea701ddac5a4d600d49007e54caa32b4c9b5 (patch) | |
| tree | 30fc1857082153506af456117a382a224302887c /src/cmd/link/internal/loader/loader.go | |
| parent | 87d29939c8f93799ce889d98e0e5579d1eb2ffe5 (diff) | |
| download | go-f901ea701ddac5a4d600d49007e54caa32b4c9b5.tar.xz | |
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>
Diffstat (limited to 'src/cmd/link/internal/loader/loader.go')
| -rw-r--r-- | src/cmd/link/internal/loader/loader.go | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index c05309a141..6d2e7dcabc 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -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 |
