From 0dff5b0b9e08157e817cfd95ad240ea2509e6644 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 12 Mar 2020 14:10:09 -0400 Subject: [PATCH] [dev.link] cmd/compile, cmd/link: move away from DWARF file renumbering This patch moves the compiler and linker away from the current scheme used to generate file references in DWARF subprogram dies. Up until now the scheme has been to have the compiler emit a special relocation on a DIE file reference that points to the file symbol in question. The linker then reads this relocation and updates the addend to the index of the appropriate file in the line table of the compilation unit of the DIE (the linker emits the comp unit file table, so it knows at that point what number use). The drawback of this scheme is that it requires a lot of relocation processing. With this patch, we switch to having the compiler emit the file index directly, and then have the linker use the compiler-generated file table to emit the line table file section (no renumbering, no relocations, etc). Change-Id: Id4fbe67b28a64200a083e3c5ea358dbe091ec917 Reviewed-on: https://go-review.googlesource.com/c/go/+/223318 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/internal/obj/objfile.go | 9 ++-- src/cmd/link/internal/ld/dwarf.go | 68 -------------------------- src/cmd/link/internal/loader/loader.go | 23 --------- 3 files changed, 6 insertions(+), 94 deletions(-) diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index 8a8e0c47c3..8f219d4cf7 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -164,12 +164,15 @@ func (c dwCtxt) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) r := &ls.R[len(ls.R)-1] r.Type = objabi.R_DWARFSECREF } + func (c dwCtxt) AddFileRef(s dwarf.Sym, f interface{}) { ls := s.(*LSym) rsym := f.(*LSym) - ls.WriteAddr(c.Link, ls.Size, 4, rsym, 0) - r := &ls.R[len(ls.R)-1] - r.Type = objabi.R_DWARFFILEREF + fidx := c.Link.PosTable.FileIndex(rsym.Name) + // Note the +1 here -- the value we're writing is going to be an + // index into the DWARF line table file section, whose entries + // are numbered starting at 1, not 0. + ls.WriteInt(c.Link, ls.Size, 4, int64(fidx+1)) } func (c dwCtxt) CurrentOffset(s dwarf.Sym) int64 { diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 0a8edcfd54..982a574276 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -1181,9 +1181,6 @@ func (d *dwctxt2) writelines(unit *sym.CompilationUnit, ls loader.Sym) { lsu.AddUint8(0) // standard_opcode_lengths[10] lsu.AddUint8(0) // include_directories (empty) - // Maps loader.Sym for file symbol to expanded filename. - expandedFiles := make(map[loader.Sym]string) - // Copy over the file table. fileNums := make(map[string]int) lsDwsym := dwSym(ls) @@ -1217,7 +1214,6 @@ func (d *dwctxt2) writelines(unit *sym.CompilationUnit, ls loader.Sym) { // Output the state machine for each function remaining. var lastAddr int64 - rslice := []loader.Reloc{} for _, s := range unit.Textp2 { fnSym := loader.Sym(s) @@ -1259,70 +1255,6 @@ func (d *dwctxt2) writelines(unit *sym.CompilationUnit, ls loader.Sym) { lsu.SetUint32(d.arch, unitLengthOffset, uint32(lsu.Size()-unitstart)) lsu.SetUint32(d.arch, headerLengthOffset, uint32(headerend-headerstart)) } - - // Process any R_DWARFFILEREF relocations, since we now know the - // line table file indices for this compilation unit. Note that - // this loop visits only subprogram DIEs: if the compiler is - // changed to generate DW_AT_decl_file attributes for other - // DIE flavors (ex: variables) then those DIEs would need to - // be included below. - missing := make(map[int]interface{}) - for _, f := range unit.FuncDIEs2 { - fnSym := loader.Sym(f) - - // Create a symbol updater prior to looking at the relocations - // on the DWARF subprogram DIE symbol. We need to do this here - // so that any modifications to the reloc slice will get - // stored in loader payload for the symbol (as opposed to a - // temporary slice of relocs read from the object file). Copy - // back relocations with updated addends. - fnu := d.ldr.MakeSymbolUpdater(fnSym) - - relocs := d.ldr.Relocs(fnSym) - rslice = relocs.ReadAll(rslice) - - for ri := range rslice { - r := &rslice[ri] - if r.Type != objabi.R_DWARFFILEREF { - continue - } - - fname, ok := expandedFiles[r.Sym] - if !ok { - fname = expandFileSym(d.ldr, r.Sym) - expandedFiles[r.Sym] = fname - } - - idx, ok := fileNums[fname] - if ok { - if int(int32(idx)) != idx { - d.linkctxt.Errorf(fnSym, "bad R_DWARFFILEREF relocation: file index overflow") - } - if r.Size != 4 { - d.linkctxt.Errorf(fnSym, "bad R_DWARFFILEREF relocation: has size %d, expected 4", r.Size) - } - if r.Add != 0 { - d.linkctxt.Errorf(fnSym, "bad R_DWARFFILEREF relocation: addend not zero") - } - if r.Off < 0 || r.Off+4 > int32(len(fnu.Data())) { - d.linkctxt.Errorf(fnSym, "bad R_DWARFFILEREF relocation offset %d + 4 would write past length %d", r.Off, len(fnu.Data())) - continue - } - - d.ldr.SetAttrReachable(r.Sym, true) - d.ldr.SetAttrNotInSymbolTable(r.Sym, true) - r.Add = int64(idx) // record the index in r.Add, we'll apply it in the reloc phase. - } else { - sv := d.ldr.SymValue(r.Sym) - _, found := missing[int(sv)] - if !found { - d.linkctxt.Errorf(fnSym, "R_DWARFFILEREF relocation file missing: %s idx %d symVal %d", d.ldr.SymName(r.Sym), r.Sym, sv) - missing[int(sv)] = nil - } - } - } - fnu.WriteRelocs(rslice) - } } // writepcranges generates the DW_AT_ranges table for compilation unit cu. diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 6a068937af..77b072bcf0 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -1955,29 +1955,6 @@ func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, syms *sym.Symb } } - // If this symbol has any DWARF file relocations, we need to - // make sure that the relocations are copied back over, since - // DWARF-gen alters the offset values for these relocs. Also: - // if this is an info symbol and it refers to a previously - // unseen range/loc symbol, we'll need to fix up relocations - // for it as well. - relocs := l.Relocs(cand) - rslice = relocs.ReadSyms(rslice) - for ri := range rslice { - if rslice[ri].Type == objabi.R_DWARFFILEREF { - relfix = true - break - } - if st != sym.SDWARFINFO { - continue - } - rst := l.SymType(rslice[ri].Sym) - if rst == sym.SDWARFRANGE || rst == sym.SDWARFLOC { - relfix = true - break - } - } - if relfix { relocfixup = append(relocfixup, cand) } -- 2.48.1