]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/compile, cmd/link: move away from DWARF file renumbering
authorThan McIntosh <thanm@google.com>
Thu, 12 Mar 2020 18:10:09 +0000 (14:10 -0400)
committerThan McIntosh <thanm@google.com>
Fri, 20 Mar 2020 16:19:22 +0000 (16:19 +0000)
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 <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/internal/obj/objfile.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/loader/loader.go

index 8a8e0c47c319d2bd82e9f5e6a270d05370f4de56..8f219d4cf7e20a1bd184d75dcfe776bd572089b3 100644 (file)
@@ -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 {
index 0a8edcfd545109179d3b32d4ee298c67b42cbc12..982a57427699deec4114212fa9035106d627f80c 100644 (file)
@@ -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.
index 6a068937af4d303f48f10cc8a17b79cad037905c..77b072bcf0fabcfbdeb90e0bb4e1603654c94db0 100644 (file)
@@ -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)
                }