From ef44bd8413a9174f83af39538c62277ea195405a Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 20 Feb 2020 14:16:04 -0500 Subject: [PATCH] [dev.link] cmd/link: expose loader PatchDWARFName hook for asm subprogram DIEs Add a new loader method PatchDWARFName to patch up live DWARF function DIEs during DWARF generation. This is needed to handle subprogram DIE symbols emitted by the assembler, which still embeds "". package tokens into the data sections of these dies. Note: this is expected to be a temporary hack, as we are going to transition the assembler to do the patching itself when passed the "-p" option (once this happens the plan is to toss all of the various PatchDWARFName helpers). Change-Id: Id689a751f08d7f4c096c4ac2f99991f9641959e1 Reviewed-on: https://go-review.googlesource.com/c/go/+/220986 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang Reviewed-by: Jeremy Faller --- src/cmd/link/internal/loader/loader.go | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index ed7e889bf5..e4691b4813 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -2550,6 +2550,48 @@ func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, exts return textp2 } +// PatchDWARFName applies DWARF name attribute patching to the +// specified symbol. If the symbol does not need patching, it will be +// left alone; if it does, cloneToExternal will be invoked so that the +// data for the symbol can be rewritten. +// +// Notes: +// +// - currently only required for assembler-generated subprogram DIE +// symbols (compiler-gen are ok) +// +// - should only be invoked on reachable/live symbols, as opposed to +// across the board (there is a cost to doing the cloning, we don't +// want to do it unless absolutely necessary). +// +// - over the years patchDWARFName has been a significant source +// of bugs and head-scratching. Something we might want to consider is +// switching from DW_FORM_str to DW_FORM_strp for package-qualified +// names in DWARF DIEs -- this might make our lives easier overall. +// +func (l *Loader) PatchDWARFName(s Sym) { + if l.IsExternal(s) { + // no patching needed here + return + } + patched, found := patchDWARFName1(l.Data(s), l.objSyms[s].r) + if found == -1 { + return + } + l.cloneToExternal(s) + l.SetAttrReadOnly(s, false) + pp := l.getPayload(s) + pp.data = patched + delta := int64(len(patched)) - pp.size + pp.size = int64(len(patched)) + for i := range pp.relocs { + r := &pp.relocs[i] + if r.Off > int32(found) { + r.Off += int32(delta) + } + } +} + // For debugging. func (l *Loader) Dump() { fmt.Println("objs") -- 2.48.1