From 59fe2fbfe549f3dffec940581a71b42644ee5320 Mon Sep 17 00:00:00 2001 From: Heschi Kreinick Date: Mon, 22 May 2017 20:17:31 -0400 Subject: [PATCH] [dev.debug] cmd/link: let the linker combine .debug_ranges, remove globals The linker is pretty good at combining a bunch of symbols into a section, so let it do .debug_ranges the normal way. Along the way, remove a bunch of globals that were only used by one function that would only be called once per invocation. Change-Id: I1a528a438b193c41e7c444e8830516b07f11affc Reviewed-on: https://go-review.googlesource.com/43890 Reviewed-by: Alessandro Arzilli Reviewed-by: Ian Lance Taylor --- src/cmd/link/internal/ld/data.go | 41 ++++++++------- src/cmd/link/internal/ld/dwarf.go | 83 +++++++++++-------------------- 2 files changed, 52 insertions(+), 72 deletions(-) diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 452332367c..bf219f7b62 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -592,15 +592,7 @@ func relocsym(ctxt *Link, s *Symbol) { } case objabi.R_DWARFREF: - var sectName string - var vaddr int64 - switch { - case r.Sym.Sect != nil: - sectName = r.Sym.Sect.Name - vaddr = int64(r.Sym.Sect.Vaddr) - case r.Sym.Type == SDWARFRANGE: - sectName = ".debug_ranges" - default: + if r.Sym.Sect == nil { Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name) } @@ -615,8 +607,8 @@ func relocsym(ctxt *Link, s *Symbol) { r.Type = objabi.R_ADDR } - r.Xsym = ctxt.Syms.ROLookup(sectName, 0) - r.Xadd = r.Add + Symaddr(r.Sym) - vaddr + r.Xsym = ctxt.Syms.ROLookup(r.Sym.Sect.Name, 0) + r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) o = r.Xadd rs = r.Xsym @@ -625,7 +617,7 @@ func relocsym(ctxt *Link, s *Symbol) { } break } - o = Symaddr(r.Sym) + r.Add - vaddr + o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr) case objabi.R_WEAKADDROFF: if !r.Sym.Attr.Reachable() { @@ -1843,9 +1835,9 @@ func (ctxt *Link) dodata() { dwarfgeneratedebugsyms(ctxt) - var s *Symbol var i int - for i, s = range dwarfp { + for ; i < len(dwarfp); i++ { + s := dwarfp[i] if s.Type != SDWARFSECT { break } @@ -1862,13 +1854,24 @@ func (ctxt *Link) dodata() { } checkdatsize(ctxt, datsize, SDWARFSECT) - if i < len(dwarfp) { - sect = addsection(&Segdwarf, ".debug_info", 04) + for i < len(dwarfp) { + curType := dwarfp[i].Type + var sect *Section + switch curType { + case SDWARFINFO: + sect = addsection(&Segdwarf, ".debug_info", 04) + case SDWARFRANGE: + sect = addsection(&Segdwarf, ".debug_ranges", 04) + default: + Errorf(dwarfp[i], "unknown DWARF section %v", curType) + } + sect.Align = 1 datsize = Rnd(datsize, int64(sect.Align)) sect.Vaddr = uint64(datsize) - for _, s := range dwarfp[i:] { - if s.Type != SDWARFINFO { + for ; i < len(dwarfp); i++ { + s := dwarfp[i] + if s.Type != curType { break } s.Sect = sect @@ -1878,7 +1881,7 @@ func (ctxt *Link) dodata() { datsize += s.Size } sect.Length = uint64(datsize) - sect.Vaddr - checkdatsize(ctxt, datsize, SDWARFINFO) + checkdatsize(ctxt, datsize, curType) } /* number the sections */ diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index ba8ace54c8..9b11fdcff6 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -67,26 +67,15 @@ func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64 r.Add = ofs } -/* - * Offsets and sizes of the debug_* sections in the cout file. - */ -var abbrevsym *Symbol -var arangessec *Symbol -var framesec *Symbol -var infosec *Symbol -var linesec *Symbol -var rangesec *Symbol - var gdbscript string var dwarfp []*Symbol -func writeabbrev(ctxt *Link, syms []*Symbol) []*Symbol { +func writeabbrev(ctxt *Link) *Symbol { s := ctxt.Syms.Lookup(".debug_abbrev", 0) s.Type = SDWARFSECT - abbrevsym = s Addbytes(s, dwarf.GetAbbrev()) - return append(syms, s) + return s } /* @@ -993,13 +982,10 @@ func getCompilationDir() string { func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) { var dwarfctxt dwarf.Context = dwctxt{ctxt} - if linesec == nil { - linesec = ctxt.Syms.Lookup(".debug_line", 0) - } - linesec.Type = SDWARFSECT - linesec.R = linesec.R[:0] + ls := ctxt.Syms.Lookup(".debug_line", 0) + ls.Type = SDWARFSECT + ls.R = ls.R[:0] - ls := linesec syms = append(syms, ls) var funcs []*Symbol @@ -1019,7 +1005,7 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) { dwinfo = newdie(ctxt, &dwroot, dwarf.DW_ABRV_COMPUNIT, "go", 0) newattr(dwinfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(lang), 0) - newattr(dwinfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, 0, linesec) + newattr(dwinfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, 0, ls) newattr(dwinfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, s.Value, s) // OS X linker requires compilation dir or absolute path in comp unit name to output debug info. compDir := getCompilationDir() @@ -1178,12 +1164,9 @@ func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte { func writeframes(ctxt *Link, syms []*Symbol) []*Symbol { var dwarfctxt dwarf.Context = dwctxt{ctxt} - if framesec == nil { - framesec = ctxt.Syms.Lookup(".debug_frame", 0) - } - framesec.Type = SDWARFSECT - framesec.R = framesec.R[:0] - fs := framesec + fs := ctxt.Syms.Lookup(".debug_frame", 0) + fs.Type = SDWARFSECT + fs.R = fs.R[:0] syms = append(syms, fs) // Emit the CIE, Section 6.4.1 @@ -1280,7 +1263,7 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol { // ptrsize: address range Adduint32(ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself) if Linkmode == LinkExternal { - adddwarfref(ctxt, fs, framesec, 4) + adddwarfref(ctxt, fs, fs, 4) } else { Adduint32(ctxt, fs, 0) // CIE offset } @@ -1292,27 +1275,24 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol { } func writeranges(ctxt *Link, syms []*Symbol) []*Symbol { - if rangesec == nil { - rangesec = ctxt.Syms.Lookup(".debug_ranges", 0) - } - rangesec.Type = SDWARFSECT - rangesec.Attr |= AttrReachable - rangesec.R = rangesec.R[:0] - + empty := true for _, s := range ctxt.Textp { rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version)) - rangeSym.Attr |= AttrReachable - rangeSym.Type = SDWARFRANGE - rangeSym.Value = rangesec.Size - rangesec.P = append(rangesec.P, rangeSym.P...) - for _, r := range rangeSym.R { - r.Off += int32(rangesec.Size) - rangesec.R = append(rangesec.R, r) + if rangeSym.Size == 0 { + continue } - rangesec.Size += rangeSym.Size + rangeSym.Attr |= AttrReachable | AttrNotInSymbolTable + rangeSym.Type = SDWARFRANGE + syms = append(syms, rangeSym) + empty = false } - if rangesec.Size > 0 { + if !empty { // PE does not like empty sections + rangesec := ctxt.Syms.Lookup(".debug_ranges", 0) + rangesec.Type = SDWARFRANGE + rangesec.Attr |= AttrReachable + rangesec.R = rangesec.R[:0] + syms = append(syms, rangesec) } return syms @@ -1325,18 +1305,14 @@ const ( COMPUNITHEADERSIZE = 4 + 2 + 4 + 1 ) -func writeinfo(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol { - if infosec == nil { - infosec = ctxt.Syms.Lookup(".debug_info", 0) - } +func writeinfo(ctxt *Link, syms []*Symbol, funcs []*Symbol, abbrevsym *Symbol) []*Symbol { + infosec := ctxt.Syms.Lookup(".debug_info", 0) infosec.R = infosec.R[:0] infosec.Type = SDWARFINFO infosec.Attr |= AttrReachable syms = append(syms, infosec) - if arangessec == nil { - arangessec = ctxt.Syms.Lookup(".dwarfaranges", 0) - } + arangessec := ctxt.Syms.Lookup(".dwarfaranges", 0) arangessec.R = arangessec.R[:0] var dwarfctxt dwarf.Context = dwctxt{ctxt} @@ -1577,10 +1553,10 @@ func dwarfgeneratedebugsyms(ctxt *Link) { genasmsym(ctxt, defdwsymb) - syms := writeabbrev(ctxt, nil) + abbrev := writeabbrev(ctxt) + syms := []*Symbol{abbrev} syms, funcs := writelines(ctxt, syms) syms = writeframes(ctxt, syms) - syms = writeranges(ctxt, syms) synthesizestringtypes(ctxt, dwtypes.Child) synthesizeslicetypes(ctxt, dwtypes.Child) @@ -1596,13 +1572,14 @@ func dwarfgeneratedebugsyms(ctxt *Link) { // Need to reorder symbols so SDWARFINFO is after all SDWARFSECT // (but we need to generate dies before writepub) - infosyms := writeinfo(ctxt, nil, funcs) + infosyms := writeinfo(ctxt, nil, funcs, abbrev) syms = writepub(ctxt, ".debug_pubnames", ispubname, syms) syms = writepub(ctxt, ".debug_pubtypes", ispubtype, syms) syms = writearanges(ctxt, syms) syms = writegdbscript(ctxt, syms) syms = append(syms, infosyms...) + syms = writeranges(ctxt, syms) dwarfp = syms } -- 2.48.1