]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: expose loader PatchDWARFName hook for asm subprogram DIEs
authorThan McIntosh <thanm@google.com>
Thu, 20 Feb 2020 19:16:04 +0000 (14:16 -0500)
committerThan McIntosh <thanm@google.com>
Thu, 5 Mar 2020 16:20:57 +0000 (16:20 +0000)
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 <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/link/internal/loader/loader.go

index ed7e889bf549ff98eb4235bce060075493908566..e4691b481377becfaf02e4ad823ccf557e5d3c6c 100644 (file)
@@ -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")