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:
parent
8c46cb1bf5
commit
3c3cc19564
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user