1
0
mirror of https://github.com/golang/go synced 2024-09-30 09:28:33 -06:00

[dev.link] cmd/link: better naming for Loader container/subsym methods, part 1 of 2

Introduce a new loader method "AddInteriorSym" to be used when
establishing container/containee symbol relationships for host object
sub-symbols and GOT/dynamic sub-symbols.

Interior symbols are employed in situations where you have a
"container" or "payload" symbol that has content, and then a series of
"interior" sub-symbols that point into a portion of the container
symbol's content. Each interior symbol will typically have a useful
name / size / value, but no content of its own. From a symbol table
perspective the container symbol is anonymous, but the interior
symbols are added to the output symbol table.

Change-Id: I919ed5dbbfe2ef2c9a76214f7ea9b384a1be6297
Reviewed-on: https://go-review.googlesource.com/c/go/+/240508
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
Than McIntosh 2020-06-30 11:30:28 -04:00
parent 8c46cb1bf5
commit 3c3cc19564
9 changed files with 57 additions and 30 deletions

View File

@ -371,7 +371,7 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
got := ldr.MakeSymbolUpdater(syms.GOT) got := ldr.MakeSymbolUpdater(syms.GOT)
su := ldr.MakeSymbolUpdater(s) su := ldr.MakeSymbolUpdater(s)
su.SetType(got.Type()) su.SetType(got.Type())
got.PrependSub(s) got.AddInteriorSym(s)
su.SetValue(got.Size()) su.SetValue(got.Size())
got.AddUint64(target.Arch, 0) got.AddUint64(target.Arch, 0)
leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT) leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT)

View File

@ -1629,7 +1629,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
toc := ldr.Lookup(".TOC.", int(ldr.SymVersion(s))) toc := ldr.Lookup(".TOC.", int(ldr.SymVersion(s)))
if toc != 0 { if toc != 0 {
ldr.SetSymSect(toc, sect) ldr.SetSymSect(toc, sect)
ldr.PrependSub(s, toc) ldr.AddInteriorSym(s, toc)
ldr.SetSymValue(toc, 0x8000) ldr.SetSymValue(toc, 0x8000)
} }
} }

View File

@ -1119,9 +1119,9 @@ func initdynimport(ctxt *Link) *Dll {
for m = d.ms; m != nil; m = m.next { for m = d.ms; m != nil; m = m.next {
sb := ldr.MakeSymbolUpdater(m.s) sb := ldr.MakeSymbolUpdater(m.s)
sb.SetType(sym.SWINDOWS) sb.SetType(sym.SWINDOWS)
dynamic.PrependSub(m.s)
sb.SetValue(dynamic.Size()) sb.SetValue(dynamic.Size())
dynamic.SetSize(dynamic.Size() + int64(ctxt.Arch.PtrSize)) dynamic.SetSize(dynamic.Size() + int64(ctxt.Arch.PtrSize))
dynamic.AddInteriorSym(m.s)
} }
dynamic.SetSize(dynamic.Size() + int64(ctxt.Arch.PtrSize)) dynamic.SetSize(dynamic.Size() + int64(ctxt.Arch.PtrSize))

View File

@ -610,7 +610,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
sb := l.MakeSymbolUpdater(s) sb := l.MakeSymbolUpdater(s)
sb.SetType(sectsb.Type()) sb.SetType(sectsb.Type())
sectsb.PrependSub(s) sectsb.AddInteriorSym(s)
if !l.AttrCgoExportDynamic(s) { if !l.AttrCgoExportDynamic(s) {
sb.SetDynimplib("") // satisfy dynimport sb.SetDynimplib("") // satisfy dynimport
} }

View File

@ -1060,8 +1060,8 @@ func (l *Loader) AttrSubSymbol(i Sym) bool {
} }
// Note that we don't have a 'SetAttrSubSymbol' method in the loader; // Note that we don't have a 'SetAttrSubSymbol' method in the loader;
// clients should instead use the PrependSub method to establish // clients should instead use the AddInteriorSym method to establish
// outer/sub relationships for host object symbols. // containment relationships for host object symbols.
// Returns whether the i-th symbol has ReflectMethod attribute set. // Returns whether the i-th symbol has ReflectMethod attribute set.
func (l *Loader) IsReflectMethod(i Sym) bool { func (l *Loader) IsReflectMethod(i Sym) bool {
@ -1560,8 +1560,6 @@ func (l *Loader) Aux2(i Sym, j int) Aux2 {
// introduction of the loader, this was done purely using name // introduction of the loader, this was done purely using name
// lookups, e.f. for function with name XYZ we would then look up // lookups, e.f. for function with name XYZ we would then look up
// go.info.XYZ, etc. // go.info.XYZ, etc.
// FIXME: once all of dwarfgen is converted over to the loader,
// it would save some space to make these aux symbols nameless.
func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, auxDwarfRanges, auxDwarfLines Sym) { func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, auxDwarfRanges, auxDwarfLines Sym) {
if l.SymType(fnSymIdx) != sym.STEXT { if l.SymType(fnSymIdx) != sym.STEXT {
log.Fatalf("error: non-function sym %d/%s t=%s passed to GetFuncDwarfAuxSyms", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String()) log.Fatalf("error: non-function sym %d/%s t=%s passed to GetFuncDwarfAuxSyms", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
@ -1601,25 +1599,53 @@ func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, a
return return
} }
// PrependSub prepends 'sub' onto the sub list for outer symbol 'outer'. // AddInteriorSym sets up 'interior' as an interior symbol of
// Will panic if 'sub' already has an outer sym or sub sym. // container/payload symbol 'container'. An interior symbol does not
// FIXME: should this be instead a method on SymbolBuilder? // itself have data, but gives a name to a subrange of the data in its
func (l *Loader) PrependSub(outer Sym, sub Sym) { // container symbol. The container itself may or may not have a name.
// NB: this presupposes that an outer sym can't be a sub symbol of // This method is intended primarily for use in the host object
// some other outer-outer sym (I'm assuming this is true, but I // loaders, to capture the semantics of symbols and sections in an
// haven't tested exhaustively). // object file. When reading a host object file, we'll typically
if l.OuterSym(outer) != 0 { // encounter a static section symbol (ex: ".text") containing content
// for a collection of functions, then a series of ELF (or macho, etc)
// symbol table entries each of which points into a sub-section
// (offset and length) of its corresponding container symbol. Within
// the go linker we create a loader.Sym for the container (which is
// expected to have the actual content/payload) and then a set of
// interior loader.Sym's that point into a portion of the container.
func (l *Loader) AddInteriorSym(container Sym, interior Sym) {
// Container symbols are expected to have content/data.
// NB: this restriction may turn out to be too strict (it's possible
// to imagine a zero-sized container with an interior symbol pointing
// into it); it's ok to relax or remove it if we counter an
// oddball host object that triggers this.
if l.SymSize(container) == 0 && len(l.Data(container)) == 0 {
panic("unexpected empty container symbol")
}
// The interior symbols for a container are not expected to have
// content/data or relocations.
if len(l.Data(interior)) != 0 {
panic("unexpected non-empty interior symbol")
}
// Interior symbol is expected to be in the symbol table.
if l.AttrNotInSymbolTable(interior) {
panic("interior symbol must be in symtab")
}
// Only a single level of containment is allowed.
if l.OuterSym(container) != 0 {
panic("outer has outer itself") panic("outer has outer itself")
} }
if l.SubSym(sub) != 0 { // Interior sym should not already have a sibling.
if l.SubSym(interior) != 0 {
panic("sub set for subsym") panic("sub set for subsym")
} }
if l.OuterSym(sub) != 0 { // Interior sym should not already point at a container.
if l.OuterSym(interior) != 0 {
panic("outer already set for subsym") panic("outer already set for subsym")
} }
l.sub[sub] = l.sub[outer] l.sub[interior] = l.sub[container]
l.sub[outer] = sub l.sub[container] = interior
l.outer[sub] = outer l.outer[interior] = container
} }
// OuterSym gets the outer symbol for host object loaded symbols. // OuterSym gets the outer symbol for host object loaded symbols.

View File

@ -359,6 +359,7 @@ func TestOuterSub(t *testing.T) {
// Populate loader with some symbols. // Populate loader with some symbols.
addDummyObjSym(t, ldr, or, "type.uint8") addDummyObjSym(t, ldr, or, "type.uint8")
es1 := ldr.LookupOrCreateSym("outer", 0) es1 := ldr.LookupOrCreateSym("outer", 0)
ldr.MakeSymbolUpdater(es1).SetSize(101)
es2 := ldr.LookupOrCreateSym("sub1", 0) es2 := ldr.LookupOrCreateSym("sub1", 0)
es3 := ldr.LookupOrCreateSym("sub2", 0) es3 := ldr.LookupOrCreateSym("sub2", 0)
es4 := ldr.LookupOrCreateSym("sub3", 0) es4 := ldr.LookupOrCreateSym("sub3", 0)
@ -374,7 +375,7 @@ func TestOuterSub(t *testing.T) {
} }
// Establish first outer/sub relationship // Establish first outer/sub relationship
ldr.PrependSub(es1, es2) ldr.AddInteriorSym(es1, es2)
if ldr.OuterSym(es1) != 0 { if ldr.OuterSym(es1) != 0 {
t.Errorf("ldr.OuterSym(es1) got %d wanted %d", ldr.OuterSym(es1), 0) t.Errorf("ldr.OuterSym(es1) got %d wanted %d", ldr.OuterSym(es1), 0)
} }
@ -389,7 +390,7 @@ func TestOuterSub(t *testing.T) {
} }
// Establish second outer/sub relationship // Establish second outer/sub relationship
ldr.PrependSub(es1, es3) ldr.AddInteriorSym(es1, es3)
if ldr.OuterSym(es1) != 0 { if ldr.OuterSym(es1) != 0 {
t.Errorf("ldr.OuterSym(es1) got %d wanted %d", ldr.OuterSym(es1), 0) t.Errorf("ldr.OuterSym(es1) got %d wanted %d", ldr.OuterSym(es1), 0)
} }
@ -407,9 +408,9 @@ func TestOuterSub(t *testing.T) {
} }
// Some more // Some more
ldr.PrependSub(es1, es4) ldr.AddInteriorSym(es1, es4)
ldr.PrependSub(es1, es5) ldr.AddInteriorSym(es1, es5)
ldr.PrependSub(es1, es6) ldr.AddInteriorSym(es1, es6)
// Set values. // Set values.
ldr.SetSymValue(es2, 7) ldr.SetSymValue(es2, 7)

View File

@ -240,8 +240,8 @@ func (sb *SymbolBuilder) SortSub() {
sb.l.SortSub(sb.symIdx) sb.l.SortSub(sb.symIdx)
} }
func (sb *SymbolBuilder) PrependSub(sub Sym) { func (sb *SymbolBuilder) AddInteriorSym(sub Sym) {
sb.l.PrependSub(sb.symIdx, sub) sb.l.AddInteriorSym(sb.symIdx, sub)
} }
func (sb *SymbolBuilder) AddUint8(v uint8) int64 { func (sb *SymbolBuilder) AddUint8(v uint8) int64 {

View File

@ -633,7 +633,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
} }
bld.SetType(l.SymType(outer)) bld.SetType(l.SymType(outer))
l.PrependSub(outer, s) l.AddInteriorSym(outer, s)
bld.SetValue(int64(machsym.value - sect.addr)) bld.SetValue(int64(machsym.value - sect.addr))
if !l.AttrCgoExportDynamic(s) { if !l.AttrCgoExportDynamic(s) {

View File

@ -409,7 +409,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
bld = makeUpdater(l, bld, s) bld = makeUpdater(l, bld, s)
sectsym := sectsyms[sect] sectsym := sectsyms[sect]
bld.SetType(l.SymType(sectsym)) bld.SetType(l.SymType(sectsym))
l.PrependSub(sectsym, s) l.AddInteriorSym(sectsym, s)
bld.SetValue(int64(pesym.Value)) bld.SetValue(int64(pesym.Value))
bld.SetSize(4) bld.SetSize(4)
if l.SymType(sectsym) == sym.STEXT { if l.SymType(sectsym) == sym.STEXT {