aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/loader
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2020-11-08 11:27:53 -0500
committerCherry Zhang <cherryyz@google.com>2021-03-05 23:34:43 +0000
commitf901ea701ddac5a4d600d49007e54caa32b4c9b5 (patch)
tree30fc1857082153506af456117a382a224302887c /src/cmd/link/internal/loader
parent87d29939c8f93799ce889d98e0e5579d1eb2ffe5 (diff)
downloadgo-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')
-rw-r--r--src/cmd/link/internal/loader/loader.go53
-rw-r--r--src/cmd/link/internal/loader/loader_test.go3
-rw-r--r--src/cmd/link/internal/loader/symbolbuilder.go8
3 files changed, 20 insertions, 44 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
diff --git a/src/cmd/link/internal/loader/loader_test.go b/src/cmd/link/internal/loader/loader_test.go
index 1371c2a541..15ae830dc9 100644
--- a/src/cmd/link/internal/loader/loader_test.go
+++ b/src/cmd/link/internal/loader/loader_test.go
@@ -237,7 +237,8 @@ func sameRelocSlice(s1 *Relocs, s2 []Reloc) bool {
type addFunc func(l *Loader, s Sym, s2 Sym) Sym
func mkReloc(l *Loader, typ objabi.RelocType, off int32, siz uint8, add int64, sym Sym) Reloc {
- r := Reloc{&goobj.Reloc{}, l.extReader, l, typ}
+ r := Reloc{&goobj.Reloc{}, l.extReader, l}
+ r.SetType(typ)
r.SetOff(off)
r.SetSiz(siz)
r.SetAdd(add)
diff --git a/src/cmd/link/internal/loader/symbolbuilder.go b/src/cmd/link/internal/loader/symbolbuilder.go
index 5d37da8ac6..204d04412d 100644
--- a/src/cmd/link/internal/loader/symbolbuilder.go
+++ b/src/cmd/link/internal/loader/symbolbuilder.go
@@ -121,13 +121,11 @@ func (sb *SymbolBuilder) Relocs() Relocs {
// ResetRelocs removes all relocations on this symbol.
func (sb *SymbolBuilder) ResetRelocs() {
sb.relocs = sb.relocs[:0]
- sb.reltypes = sb.reltypes[:0]
}
// SetRelocType sets the type of the 'i'-th relocation on this sym to 't'
func (sb *SymbolBuilder) SetRelocType(i int, t objabi.RelocType) {
- sb.relocs[i].SetType(0)
- sb.reltypes[i] = t
+ sb.relocs[i].SetType(uint16(t))
}
// SetRelocSym sets the target sym of the 'i'-th relocation on this sym to 's'
@@ -143,7 +141,6 @@ func (sb *SymbolBuilder) SetRelocAdd(i int, a int64) {
// Add n relocations, return a handle to the relocations.
func (sb *SymbolBuilder) AddRelocs(n int) Relocs {
sb.relocs = append(sb.relocs, make([]goobj.Reloc, n)...)
- sb.reltypes = append(sb.reltypes, make([]objabi.RelocType, n)...)
return sb.l.Relocs(sb.symIdx)
}
@@ -152,7 +149,7 @@ func (sb *SymbolBuilder) AddRelocs(n int) Relocs {
func (sb *SymbolBuilder) AddRel(typ objabi.RelocType) (Reloc, int) {
j := len(sb.relocs)
sb.relocs = append(sb.relocs, goobj.Reloc{})
- sb.reltypes = append(sb.reltypes, typ)
+ sb.relocs[j].SetType(uint16(typ))
relocs := sb.Relocs()
return relocs.At(j), j
}
@@ -169,7 +166,6 @@ func (p *relocsByOff) Len() int { return len(p.relocs) }
func (p *relocsByOff) Less(i, j int) bool { return p.relocs[i].Off() < p.relocs[j].Off() }
func (p *relocsByOff) Swap(i, j int) {
p.relocs[i], p.relocs[j] = p.relocs[j], p.relocs[i]
- p.reltypes[i], p.reltypes[j] = p.reltypes[j], p.reltypes[i]
}
func (sb *SymbolBuilder) Reachable() bool {