mirror of
https://github.com/golang/go.git
synced 2025-05-31 23:25:39 +00:00
[dev.link] cmd/link: remove legacy DWARF gen code
Remove the temporary "-newdw2" linker command line option, along with the remainder of the legacy sym.Symbol based DWARF generation code. Change-Id: I86c0581dd021cd4e2209ca9bc45f34037d42323c Reviewed-on: https://go-review.googlesource.com/c/go/+/222766 Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
29c5291f03
commit
cdc1b19513
@ -2064,93 +2064,10 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
|
||||
// every DIE constructed and convert the symbols.
|
||||
}
|
||||
|
||||
// dwarfConvertSymbols is invoked around the time that loader.LoadFull
|
||||
// runs (converting all loader.Sym's into sym.Symbols); it walks
|
||||
// through dwarf DIE objects and rewrites loader.Sym refs to
|
||||
// sym.Symbol there as well. This is obviously a temporary function.
|
||||
func dwarfConvertSymbols(ctxt *Link) {
|
||||
if !dwarfEnabled(ctxt) {
|
||||
return
|
||||
}
|
||||
if *FlagNewDw2 {
|
||||
// don't convert since we're running phase 2 with loader
|
||||
return
|
||||
}
|
||||
convdies := make(map[*dwarf.DWDie]bool)
|
||||
for _, lib := range ctxt.Library {
|
||||
for _, unit := range lib.Units {
|
||||
convertSymbolsInDIE(ctxt, unit.DWInfo, convdies)
|
||||
}
|
||||
}
|
||||
convertSymbolsInDIE(ctxt, &dwtypes, convdies)
|
||||
|
||||
// Convert over the unit function DIE and abstract function DIE lists.
|
||||
for _, lib := range ctxt.Library {
|
||||
for _, unit := range lib.Units {
|
||||
for _, fd := range unit.FuncDIEs2 {
|
||||
ds := ctxt.loader.Syms[fd]
|
||||
if ds == nil {
|
||||
panic("bad")
|
||||
}
|
||||
unit.FuncDIEs = append(unit.FuncDIEs, ds)
|
||||
}
|
||||
for _, fd := range unit.RangeSyms2 {
|
||||
ds := ctxt.loader.Syms[fd]
|
||||
if ds == nil {
|
||||
panic("bad")
|
||||
}
|
||||
unit.RangeSyms = append(unit.RangeSyms, ds)
|
||||
}
|
||||
for _, fd := range unit.AbsFnDIEs2 {
|
||||
ds := ctxt.loader.Syms[fd]
|
||||
if ds == nil {
|
||||
panic("bad")
|
||||
}
|
||||
unit.AbsFnDIEs = append(unit.AbsFnDIEs, ds)
|
||||
}
|
||||
if unit.Consts2 != 0 {
|
||||
ds := ctxt.loader.Syms[unit.Consts2]
|
||||
if ds == nil {
|
||||
panic("bad")
|
||||
}
|
||||
unit.Consts = ds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func convertSymbolsInDIE(ctxt *Link, die *dwarf.DWDie, convdies map[*dwarf.DWDie]bool) {
|
||||
if die == nil {
|
||||
return
|
||||
}
|
||||
if convdies[die] {
|
||||
return
|
||||
}
|
||||
convdies[die] = true
|
||||
if die.Sym != nil {
|
||||
ds, ok := die.Sym.(dwSym)
|
||||
if !ok {
|
||||
panic("bad die sym field")
|
||||
}
|
||||
symIdx := loader.Sym(ds)
|
||||
if symIdx == 0 {
|
||||
panic("zero loader sym for die")
|
||||
}
|
||||
die.Sym = ctxt.loader.Syms[symIdx]
|
||||
}
|
||||
for a := die.Attr; a != nil; a = a.Link {
|
||||
if attrSym, ok := a.Data.(dwSym); ok {
|
||||
a.Data = ctxt.loader.Syms[loader.Sym(attrSym)]
|
||||
}
|
||||
}
|
||||
convertSymbolsInDIE(ctxt, die.Child, convdies)
|
||||
convertSymbolsInDIE(ctxt, die.Link, convdies)
|
||||
}
|
||||
|
||||
// dwarfGenerateDebugSyms constructs debug_line, debug_frame, debug_loc,
|
||||
// debug_pubnames and debug_pubtypes. It also writes out the debug_info
|
||||
// section using symbols generated in dwarfGenerateDebugInfo2.
|
||||
func dwarfGenerateDebugSyms2(ctxt *Link) {
|
||||
func dwarfGenerateDebugSyms(ctxt *Link) {
|
||||
if !dwarfEnabled(ctxt) {
|
||||
return
|
||||
}
|
||||
@ -2295,3 +2212,23 @@ func (d *dwctxt2) dwarfcompress(ctxt *Link) {
|
||||
func (d *dwctxt2) getPkgFromCUSym(s loader.Sym) string {
|
||||
return strings.TrimPrefix(d.ldr.SymName(s), dwarf.InfoPrefix+".pkg.")
|
||||
}
|
||||
|
||||
// On AIX, the symbol table needs to know where are the compilation units parts
|
||||
// for a specific package in each .dw section.
|
||||
// dwsectCUSize map will save the size of a compilation unit for
|
||||
// the corresponding .dw section.
|
||||
// This size can later be retrieved with the index "sectionName.pkgName".
|
||||
var dwsectCUSize map[string]uint64
|
||||
|
||||
// getDwsectCUSize retrieves the corresponding package size inside the current section.
|
||||
func getDwsectCUSize(sname string, pkgname string) uint64 {
|
||||
return dwsectCUSize[sname+"."+pkgname]
|
||||
}
|
||||
|
||||
func saveDwsectCUSize(sname string, pkgname string, size uint64) {
|
||||
dwsectCUSize[sname+"."+pkgname] = size
|
||||
}
|
||||
|
||||
func addDwsectCUSize(sname string, pkgname string, size uint64) {
|
||||
dwsectCUSize[sname+"."+pkgname] += size
|
||||
}
|
||||
|
@ -15,111 +15,18 @@ package ld
|
||||
|
||||
import (
|
||||
"cmd/internal/dwarf"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
"cmd/link/internal/sym"
|
||||
"fmt"
|
||||
"log"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type dwctxt struct {
|
||||
linkctxt *Link
|
||||
}
|
||||
|
||||
func (c dwctxt) PtrSize() int {
|
||||
return c.linkctxt.Arch.PtrSize
|
||||
}
|
||||
func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
|
||||
ls := s.(*sym.Symbol)
|
||||
ls.AddUintXX(c.linkctxt.Arch, uint64(i), size)
|
||||
}
|
||||
func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
|
||||
ls := s.(*sym.Symbol)
|
||||
ls.AddBytes(b)
|
||||
}
|
||||
func (c dwctxt) AddString(s dwarf.Sym, v string) {
|
||||
Addstring(s.(*sym.Symbol), v)
|
||||
}
|
||||
|
||||
func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
|
||||
if value != 0 {
|
||||
value -= (data.(*sym.Symbol)).Value
|
||||
}
|
||||
s.(*sym.Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value)
|
||||
}
|
||||
|
||||
func (c dwctxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
|
||||
if value != 0 {
|
||||
value -= (data.(*sym.Symbol)).Value
|
||||
}
|
||||
s.(*sym.Symbol).AddCURelativeAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value)
|
||||
}
|
||||
|
||||
func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
|
||||
ls := s.(*sym.Symbol)
|
||||
switch size {
|
||||
default:
|
||||
Errorf(ls, "invalid size %d in adddwarfref\n", size)
|
||||
fallthrough
|
||||
case c.linkctxt.Arch.PtrSize:
|
||||
ls.AddAddr(c.linkctxt.Arch, t.(*sym.Symbol))
|
||||
case 4:
|
||||
ls.AddAddrPlus4(t.(*sym.Symbol), 0)
|
||||
}
|
||||
r := &ls.R[len(ls.R)-1]
|
||||
r.Type = objabi.R_ADDROFF
|
||||
r.Add = ofs
|
||||
}
|
||||
|
||||
func (c dwctxt) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
|
||||
size := 4
|
||||
if isDwarf64(c.linkctxt) {
|
||||
size = 8
|
||||
}
|
||||
|
||||
c.AddSectionOffset(s, size, t, ofs)
|
||||
ls := s.(*sym.Symbol)
|
||||
ls.R[len(ls.R)-1].Type = objabi.R_DWARFSECREF
|
||||
}
|
||||
|
||||
func (c dwctxt) Logf(format string, args ...interface{}) {
|
||||
c.linkctxt.Logf(format, args...)
|
||||
}
|
||||
|
||||
// At the moment these interfaces are only used in the compiler.
|
||||
|
||||
func (c dwctxt) AddFileRef(s dwarf.Sym, f interface{}) {
|
||||
panic("should be used only in the compiler")
|
||||
}
|
||||
|
||||
func (c dwctxt) CurrentOffset(s dwarf.Sym) int64 {
|
||||
panic("should be used only in the compiler")
|
||||
}
|
||||
|
||||
func (c dwctxt) RecordDclReference(s dwarf.Sym, t dwarf.Sym, dclIdx int, inlIndex int) {
|
||||
panic("should be used only in the compiler")
|
||||
}
|
||||
|
||||
func (c dwctxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
|
||||
panic("should be used only in the compiler")
|
||||
}
|
||||
|
||||
func isDwarf64(ctxt *Link) bool {
|
||||
return ctxt.HeadType == objabi.Haix
|
||||
}
|
||||
|
||||
var dwarfp []*sym.Symbol
|
||||
|
||||
func writeabbrev(ctxt *Link) *sym.Symbol {
|
||||
s := ctxt.Syms.Lookup(".debug_abbrev", 0)
|
||||
s.Type = sym.SDWARFSECT
|
||||
s.AddBytes(dwarf.GetAbbrev())
|
||||
return s
|
||||
}
|
||||
|
||||
// Every DIE manufactured by the linker has at least an AT_name
|
||||
// attribute (but it will only be written out if it is listed in the abbrev).
|
||||
// The compiler does create nameless DWARF DIEs (ex: concrete subprogram
|
||||
@ -148,742 +55,6 @@ func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version in
|
||||
return die
|
||||
}
|
||||
|
||||
func adddwarfref(ctxt *Link, s *sym.Symbol, t *sym.Symbol, size int) int64 {
|
||||
var result int64
|
||||
switch size {
|
||||
default:
|
||||
Errorf(s, "invalid size %d in adddwarfref\n", size)
|
||||
fallthrough
|
||||
case ctxt.Arch.PtrSize:
|
||||
result = s.AddAddr(ctxt.Arch, t)
|
||||
case 4:
|
||||
result = s.AddAddrPlus4(t, 0)
|
||||
}
|
||||
r := &s.R[len(s.R)-1]
|
||||
r.Type = objabi.R_DWARFSECREF
|
||||
return result
|
||||
}
|
||||
|
||||
func newrefattr(die *dwarf.DWDie, attr uint16, ref *sym.Symbol) *dwarf.DWAttr {
|
||||
if ref == nil {
|
||||
return nil
|
||||
}
|
||||
return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref)
|
||||
}
|
||||
|
||||
func dtolsym(s dwarf.Sym) *sym.Symbol {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
return s.(*sym.Symbol)
|
||||
}
|
||||
|
||||
func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol {
|
||||
s := dtolsym(die.Sym)
|
||||
if s == nil {
|
||||
s = syms[len(syms)-1]
|
||||
} else {
|
||||
if s.Attr.OnList() {
|
||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||
}
|
||||
s.Attr |= sym.AttrOnList
|
||||
syms = append(syms, s)
|
||||
}
|
||||
dwarf.Uleb128put(ctxt, s, int64(die.Abbrev))
|
||||
dwarf.PutAttrs(ctxt, s, die.Abbrev, die.Attr)
|
||||
if dwarf.HasChildren(die) {
|
||||
for die := die.Child; die != nil; die = die.Link {
|
||||
syms = putdie(linkctxt, ctxt, syms, die)
|
||||
}
|
||||
syms[len(syms)-1].AddUint8(0)
|
||||
}
|
||||
return syms
|
||||
}
|
||||
|
||||
// dwarfFuncSym looks up a DWARF metadata symbol for function symbol s.
|
||||
// If the symbol does not exist, it creates it if create is true,
|
||||
// or returns nil otherwise.
|
||||
func dwarfFuncSym(ctxt *Link, s *sym.Symbol, meta string, create bool) *sym.Symbol {
|
||||
// All function ABIs use symbol version 0 for the DWARF data.
|
||||
//
|
||||
// TODO(austin): It may be useful to have DWARF info for ABI
|
||||
// wrappers, in which case we may want these versions to
|
||||
// align. Better yet, replace these name lookups with a
|
||||
// general way to attach metadata to a symbol.
|
||||
ver := 0
|
||||
if s.IsFileLocal() {
|
||||
ver = int(s.Version)
|
||||
}
|
||||
if create {
|
||||
return ctxt.Syms.Lookup(meta+s.Name, ver)
|
||||
}
|
||||
return ctxt.Syms.ROLookup(meta+s.Name, ver)
|
||||
}
|
||||
|
||||
// createUnitLength creates the initial length field with value v and update
|
||||
// offset of unit_length if needed.
|
||||
func createUnitLength(ctxt *Link, s *sym.Symbol, v uint64) {
|
||||
if isDwarf64(ctxt) {
|
||||
s.AddUint32(ctxt.Arch, 0xFFFFFFFF)
|
||||
}
|
||||
addDwarfAddrField(ctxt, s, v)
|
||||
}
|
||||
|
||||
// addDwarfAddrField adds a DWARF field in DWARF 64bits or 32bits.
|
||||
func addDwarfAddrField(ctxt *Link, s *sym.Symbol, v uint64) {
|
||||
if isDwarf64(ctxt) {
|
||||
s.AddUint(ctxt.Arch, v)
|
||||
} else {
|
||||
s.AddUint32(ctxt.Arch, uint32(v))
|
||||
}
|
||||
}
|
||||
|
||||
// addDwarfAddrRef adds a DWARF pointer in DWARF 64bits or 32bits.
|
||||
func addDwarfAddrRef(ctxt *Link, s *sym.Symbol, t *sym.Symbol) {
|
||||
if isDwarf64(ctxt) {
|
||||
adddwarfref(ctxt, s, t, 8)
|
||||
} else {
|
||||
adddwarfref(ctxt, s, t, 4)
|
||||
}
|
||||
}
|
||||
|
||||
// calcCompUnitRanges calculates the PC ranges of the compilation units.
|
||||
func calcCompUnitRanges(ctxt *Link) {
|
||||
var prevUnit *sym.CompilationUnit
|
||||
for _, s := range ctxt.Textp {
|
||||
if s.FuncInfo == nil {
|
||||
continue
|
||||
}
|
||||
// Skip linker-created functions (ex: runtime.addmoduledata), since they
|
||||
// don't have DWARF to begin with.
|
||||
if s.Unit == nil {
|
||||
continue
|
||||
}
|
||||
unit := s.Unit
|
||||
// Update PC ranges.
|
||||
//
|
||||
// We don't simply compare the end of the previous
|
||||
// symbol with the start of the next because there's
|
||||
// often a little padding between them. Instead, we
|
||||
// only create boundaries between symbols from
|
||||
// different units.
|
||||
if prevUnit != unit {
|
||||
unit.PCs = append(unit.PCs, dwarf.Range{Start: s.Value - unit.Textp[0].Value})
|
||||
prevUnit = unit
|
||||
}
|
||||
unit.PCs[len(unit.PCs)-1].End = s.Value - unit.Textp[0].Value + s.Size
|
||||
}
|
||||
}
|
||||
|
||||
// If the pcln table contains runtime/proc.go, use that to set gdbscript path.
|
||||
func finddebugruntimepath(s *sym.Symbol) {
|
||||
if gdbscript != "" {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range s.FuncInfo.File {
|
||||
f := s.FuncInfo.File[i]
|
||||
// We can't use something that may be dead-code
|
||||
// eliminated from a binary here. proc.go contains
|
||||
// main and the scheduler, so it's not going anywhere.
|
||||
if i := strings.Index(f.Name, "runtime/proc.go"); i >= 0 {
|
||||
gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func writelines(ctxt *Link, unit *sym.CompilationUnit, ls *sym.Symbol) {
|
||||
|
||||
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
||||
is_stmt := uint8(1) // initially = recommended default_is_stmt = 1, tracks is_stmt toggles.
|
||||
|
||||
unitstart := int64(-1)
|
||||
headerstart := int64(-1)
|
||||
headerend := int64(-1)
|
||||
|
||||
newattr(unit.DWInfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, ls.Size, ls)
|
||||
|
||||
// Write .debug_line Line Number Program Header (sec 6.2.4)
|
||||
// Fields marked with (*) must be changed for 64-bit dwarf
|
||||
unitLengthOffset := ls.Size
|
||||
createUnitLength(ctxt, ls, 0) // unit_length (*), filled in at end
|
||||
unitstart = ls.Size
|
||||
ls.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F) -- version 3 is incompatible w/ XCode 9.0's dsymutil, latest supported on OSX 10.12 as of 2018-05
|
||||
headerLengthOffset := ls.Size
|
||||
addDwarfAddrField(ctxt, ls, 0) // header_length (*), filled in at end
|
||||
headerstart = ls.Size
|
||||
|
||||
// cpos == unitstart + 4 + 2 + 4
|
||||
ls.AddUint8(1) // minimum_instruction_length
|
||||
ls.AddUint8(is_stmt) // default_is_stmt
|
||||
ls.AddUint8(LINE_BASE & 0xFF) // line_base
|
||||
ls.AddUint8(LINE_RANGE) // line_range
|
||||
ls.AddUint8(OPCODE_BASE) // opcode_base
|
||||
ls.AddUint8(0) // standard_opcode_lengths[1]
|
||||
ls.AddUint8(1) // standard_opcode_lengths[2]
|
||||
ls.AddUint8(1) // standard_opcode_lengths[3]
|
||||
ls.AddUint8(1) // standard_opcode_lengths[4]
|
||||
ls.AddUint8(1) // standard_opcode_lengths[5]
|
||||
ls.AddUint8(0) // standard_opcode_lengths[6]
|
||||
ls.AddUint8(0) // standard_opcode_lengths[7]
|
||||
ls.AddUint8(0) // standard_opcode_lengths[8]
|
||||
ls.AddUint8(1) // standard_opcode_lengths[9]
|
||||
ls.AddUint8(0) // standard_opcode_lengths[10]
|
||||
ls.AddUint8(0) // include_directories (empty)
|
||||
|
||||
// Copy over the file table.
|
||||
fileNums := make(map[string]int)
|
||||
for i, name := range unit.DWARFFileTable {
|
||||
if len(name) != 0 {
|
||||
if strings.HasPrefix(name, src.FileSymPrefix) {
|
||||
name = name[len(src.FileSymPrefix):]
|
||||
}
|
||||
name = expandGoroot(name)
|
||||
} else {
|
||||
// Can't have empty filenames, and having a unique filename is quite useful
|
||||
// for debugging.
|
||||
name = fmt.Sprintf("<missing>_%d", i)
|
||||
}
|
||||
fileNums[name] = i + 1
|
||||
dwarfctxt.AddString(ls, name)
|
||||
ls.AddUint8(0)
|
||||
ls.AddUint8(0)
|
||||
ls.AddUint8(0)
|
||||
}
|
||||
// Grab files for inlined functions.
|
||||
// TODO: With difficulty, this could be moved into the compiler.
|
||||
for _, s := range unit.Textp {
|
||||
dsym := dwarfFuncSym(ctxt, s, dwarf.InfoPrefix, true)
|
||||
for ri := 0; ri < len(dsym.R); ri++ {
|
||||
r := &dsym.R[ri]
|
||||
if r.Type != objabi.R_DWARFFILEREF {
|
||||
continue
|
||||
}
|
||||
name := r.Sym.Name
|
||||
if _, ok := fileNums[name]; ok {
|
||||
continue
|
||||
}
|
||||
fileNums[name] = len(fileNums) + 1
|
||||
dwarfctxt.AddString(ls, name)
|
||||
ls.AddUint8(0)
|
||||
ls.AddUint8(0)
|
||||
ls.AddUint8(0)
|
||||
}
|
||||
}
|
||||
|
||||
// 4 zeros: the string termination + 3 fields.
|
||||
ls.AddUint8(0)
|
||||
// terminate file_names.
|
||||
headerend = ls.Size
|
||||
|
||||
// Output the state machine for each function remaining.
|
||||
var lastAddr int64
|
||||
for _, s := range unit.Textp {
|
||||
finddebugruntimepath(s)
|
||||
|
||||
// Set the PC.
|
||||
ls.AddUint8(0)
|
||||
dwarf.Uleb128put(dwarfctxt, ls, 1+int64(ctxt.Arch.PtrSize))
|
||||
ls.AddUint8(dwarf.DW_LNE_set_address)
|
||||
addr := ls.AddAddr(ctxt.Arch, s)
|
||||
// Make sure the units are sorted.
|
||||
if addr < lastAddr {
|
||||
Errorf(s, "address wasn't increasing %x < %x", addr, lastAddr)
|
||||
}
|
||||
lastAddr = addr
|
||||
|
||||
// Output the line table.
|
||||
// TODO: Now that we have all the debug information in separate
|
||||
// symbols, it would make sense to use a rope, and concatenate them all
|
||||
// together rather then the append() below. This would allow us to have
|
||||
// the compiler emit the DW_LNE_set_address and a rope data structure
|
||||
// to concat them all together in the output.
|
||||
lines := dwarfFuncSym(ctxt, s, dwarf.DebugLinesPrefix, false)
|
||||
if lines != nil {
|
||||
ls.P = append(ls.P, lines.P...)
|
||||
}
|
||||
}
|
||||
|
||||
ls.AddUint8(0) // start extended opcode
|
||||
dwarf.Uleb128put(dwarfctxt, ls, 1)
|
||||
ls.AddUint8(dwarf.DW_LNE_end_sequence)
|
||||
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
saveDwsectCUSize(".debug_line", unit.Lib.Pkg, uint64(ls.Size-unitLengthOffset))
|
||||
}
|
||||
if isDwarf64(ctxt) {
|
||||
ls.SetUint(ctxt.Arch, unitLengthOffset+4, uint64(ls.Size-unitstart)) // +4 because of 0xFFFFFFFF
|
||||
ls.SetUint(ctxt.Arch, headerLengthOffset, uint64(headerend-headerstart))
|
||||
} else {
|
||||
ls.SetUint32(ctxt.Arch, unitLengthOffset, uint32(ls.Size-unitstart))
|
||||
ls.SetUint32(ctxt.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{})
|
||||
s := unit.Textp[0]
|
||||
for _, f := range unit.FuncDIEs {
|
||||
for ri := range f.R {
|
||||
r := &f.R[ri]
|
||||
if r.Type != objabi.R_DWARFFILEREF {
|
||||
continue
|
||||
}
|
||||
idx, ok := fileNums[r.Sym.Name]
|
||||
if ok {
|
||||
if int(int32(idx)) != idx {
|
||||
Errorf(f, "bad R_DWARFFILEREF relocation: file index overflow")
|
||||
}
|
||||
if r.Siz != 4 {
|
||||
Errorf(f, "bad R_DWARFFILEREF relocation: has size %d, expected 4", r.Siz)
|
||||
}
|
||||
if r.Off < 0 || r.Off+4 > int32(len(f.P)) {
|
||||
Errorf(f, "bad R_DWARFFILEREF relocation offset %d + 4 would write past length %d", r.Off, len(s.P))
|
||||
continue
|
||||
}
|
||||
if r.Add != 0 {
|
||||
Errorf(f, "bad R_DWARFFILEREF relocation: addend not zero")
|
||||
}
|
||||
r.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
|
||||
r.Add = int64(idx) // record the index in r.Add, we'll apply it in the reloc phase.
|
||||
} else {
|
||||
_, found := missing[int(r.Sym.Value)]
|
||||
if !found {
|
||||
Errorf(f, "R_DWARFFILEREF relocation file missing: %v idx %d", r.Sym, r.Sym.Value)
|
||||
missing[int(r.Sym.Value)] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// writepcranges generates the DW_AT_ranges table for compilation unit cu.
|
||||
func writepcranges(ctxt *Link, unit *sym.CompilationUnit, base *sym.Symbol, pcs []dwarf.Range, ranges *sym.Symbol) {
|
||||
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
||||
|
||||
unitLengthOffset := ranges.Size
|
||||
|
||||
// Create PC ranges for this CU.
|
||||
newattr(unit.DWInfo, dwarf.DW_AT_ranges, dwarf.DW_CLS_PTR, ranges.Size, ranges)
|
||||
newattr(unit.DWInfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, base.Value, base)
|
||||
dwarf.PutBasedRanges(dwarfctxt, ranges, pcs)
|
||||
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
addDwsectCUSize(".debug_ranges", unit.Lib.Pkg, uint64(ranges.Size-unitLengthOffset))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
||||
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
||||
fs := ctxt.Syms.Lookup(".debug_frame", 0)
|
||||
fs.Type = sym.SDWARFSECT
|
||||
syms = append(syms, fs)
|
||||
|
||||
// Length field is 4 bytes on Dwarf32 and 12 bytes on Dwarf64
|
||||
lengthFieldSize := int64(4)
|
||||
if isDwarf64(ctxt) {
|
||||
lengthFieldSize += 8
|
||||
}
|
||||
|
||||
// Emit the CIE, Section 6.4.1
|
||||
cieReserve := uint32(16)
|
||||
if haslinkregister(ctxt) {
|
||||
cieReserve = 32
|
||||
}
|
||||
if isDwarf64(ctxt) {
|
||||
cieReserve += 4 // 4 bytes added for cid
|
||||
}
|
||||
createUnitLength(ctxt, fs, uint64(cieReserve)) // initial length, must be multiple of thearch.ptrsize
|
||||
addDwarfAddrField(ctxt, fs, ^uint64(0)) // cid
|
||||
fs.AddUint8(3) // dwarf version (appendix F)
|
||||
fs.AddUint8(0) // augmentation ""
|
||||
dwarf.Uleb128put(dwarfctxt, fs, 1) // code_alignment_factor
|
||||
dwarf.Sleb128put(dwarfctxt, fs, dataAlignmentFactor) // all CFI offset calculations include multiplication with this factor
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfreglr)) // return_address_register
|
||||
|
||||
fs.AddUint8(dwarf.DW_CFA_def_cfa) // Set the current frame address..
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)...
|
||||
if haslinkregister(ctxt) {
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...plus a 0 offset.
|
||||
|
||||
fs.AddUint8(dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfreglr))
|
||||
|
||||
fs.AddUint8(dwarf.DW_CFA_val_offset) // The previous value...
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfregsp)) // ...of the platform's SP register...
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...is CFA+0.
|
||||
} else {
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(ctxt.Arch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
|
||||
|
||||
fs.AddUint8(dwarf.DW_CFA_offset_extended) // The previous value...
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfreglr)) // ...of the return address...
|
||||
dwarf.Uleb128put(dwarfctxt, fs, int64(-ctxt.Arch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
|
||||
}
|
||||
|
||||
pad := int64(cieReserve) + lengthFieldSize - fs.Size
|
||||
|
||||
if pad < 0 {
|
||||
Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
|
||||
}
|
||||
|
||||
fs.AddBytes(zeros[:pad])
|
||||
|
||||
var deltaBuf []byte
|
||||
pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
|
||||
for _, s := range ctxt.Textp {
|
||||
if s.FuncInfo == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Emit a FDE, Section 6.4.1.
|
||||
// First build the section contents into a byte buffer.
|
||||
deltaBuf = deltaBuf[:0]
|
||||
if haslinkregister(ctxt) && s.Attr.TopFrame() {
|
||||
// Mark the link register as having an undefined value.
|
||||
// This stops call stack unwinders progressing any further.
|
||||
// TODO: similar mark on non-LR architectures.
|
||||
deltaBuf = append(deltaBuf, dwarf.DW_CFA_undefined)
|
||||
deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
|
||||
}
|
||||
for pcsp.Init(s.FuncInfo.Pcsp.P); !pcsp.Done; pcsp.Next() {
|
||||
nextpc := pcsp.NextPC
|
||||
|
||||
// pciterinit goes up to the end of the function,
|
||||
// but DWARF expects us to stop just before the end.
|
||||
if int64(nextpc) == s.Size {
|
||||
nextpc--
|
||||
if nextpc < pcsp.PC {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
spdelta := int64(pcsp.Value)
|
||||
if !haslinkregister(ctxt) {
|
||||
// Return address has been pushed onto stack.
|
||||
spdelta += int64(ctxt.Arch.PtrSize)
|
||||
}
|
||||
|
||||
if haslinkregister(ctxt) && !s.Attr.TopFrame() {
|
||||
// TODO(bryanpkc): This is imprecise. In general, the instruction
|
||||
// that stores the return address to the stack frame is not the
|
||||
// same one that allocates the frame.
|
||||
if pcsp.Value > 0 {
|
||||
// The return address is preserved at (CFA-frame_size)
|
||||
// after a stack frame has been allocated.
|
||||
deltaBuf = append(deltaBuf, dwarf.DW_CFA_offset_extended_sf)
|
||||
deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
|
||||
deltaBuf = dwarf.AppendSleb128(deltaBuf, -spdelta/dataAlignmentFactor)
|
||||
} else {
|
||||
// The return address is restored into the link register
|
||||
// when a stack frame has been de-allocated.
|
||||
deltaBuf = append(deltaBuf, dwarf.DW_CFA_same_value)
|
||||
deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
|
||||
}
|
||||
}
|
||||
|
||||
deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.PC), spdelta)
|
||||
}
|
||||
pad := int(Rnd(int64(len(deltaBuf)), int64(ctxt.Arch.PtrSize))) - len(deltaBuf)
|
||||
deltaBuf = append(deltaBuf, zeros[:pad]...)
|
||||
|
||||
// Emit the FDE header, Section 6.4.1.
|
||||
// 4 bytes: length, must be multiple of thearch.ptrsize
|
||||
// 4/8 bytes: Pointer to the CIE above, at offset 0
|
||||
// ptrsize: initial location
|
||||
// ptrsize: address range
|
||||
|
||||
fdeLength := uint64(4 + 2*ctxt.Arch.PtrSize + len(deltaBuf))
|
||||
if isDwarf64(ctxt) {
|
||||
fdeLength += 4 // 4 bytes added for CIE pointer
|
||||
}
|
||||
createUnitLength(ctxt, fs, fdeLength)
|
||||
|
||||
if ctxt.LinkMode == LinkExternal {
|
||||
addDwarfAddrRef(ctxt, fs, fs)
|
||||
} else {
|
||||
addDwarfAddrField(ctxt, fs, 0) // CIE offset
|
||||
}
|
||||
fs.AddAddr(ctxt.Arch, s)
|
||||
fs.AddUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
|
||||
fs.AddBytes(deltaBuf)
|
||||
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
addDwsectCUSize(".debug_frame", s.File, fdeLength+uint64(lengthFieldSize))
|
||||
}
|
||||
}
|
||||
return syms
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk DWarfDebugInfoEntries, and emit .debug_info
|
||||
*/
|
||||
|
||||
func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*sym.CompilationUnit, abbrevsym *sym.Symbol, pubNames, pubTypes *pubWriter) []*sym.Symbol {
|
||||
infosec := ctxt.Syms.Lookup(".debug_info", 0)
|
||||
infosec.Type = sym.SDWARFINFO
|
||||
infosec.Attr |= sym.AttrReachable
|
||||
syms = append(syms, infosec)
|
||||
|
||||
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
||||
|
||||
for _, u := range units {
|
||||
compunit := u.DWInfo
|
||||
s := dtolsym(compunit.Sym)
|
||||
|
||||
if len(u.Textp) == 0 && u.DWInfo.Child == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
pubNames.beginCompUnit(compunit)
|
||||
pubTypes.beginCompUnit(compunit)
|
||||
|
||||
// Write .debug_info Compilation Unit Header (sec 7.5.1)
|
||||
// Fields marked with (*) must be changed for 64-bit dwarf
|
||||
// This must match COMPUNITHEADERSIZE above.
|
||||
createUnitLength(ctxt, s, 0) // unit_length (*), will be filled in later.
|
||||
s.AddUint16(ctxt.Arch, 4) // dwarf version (appendix F)
|
||||
|
||||
// debug_abbrev_offset (*)
|
||||
addDwarfAddrRef(ctxt, s, abbrevsym)
|
||||
|
||||
s.AddUint8(uint8(ctxt.Arch.PtrSize)) // address_size
|
||||
|
||||
dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
|
||||
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
|
||||
|
||||
cu := []*sym.Symbol{s}
|
||||
cu = append(cu, u.AbsFnDIEs...)
|
||||
cu = append(cu, u.FuncDIEs...)
|
||||
if u.Consts != nil {
|
||||
cu = append(cu, u.Consts)
|
||||
}
|
||||
var cusize int64
|
||||
for _, child := range cu {
|
||||
cusize += child.Size
|
||||
}
|
||||
|
||||
for die := compunit.Child; die != nil; die = die.Link {
|
||||
l := len(cu)
|
||||
lastSymSz := cu[l-1].Size
|
||||
cu = putdie(ctxt, dwarfctxt, cu, die)
|
||||
if ispubname(die) {
|
||||
pubNames.add(die, cusize)
|
||||
}
|
||||
if ispubtype(die) {
|
||||
pubTypes.add(die, cusize)
|
||||
}
|
||||
if lastSymSz != cu[l-1].Size {
|
||||
// putdie will sometimes append directly to the last symbol of the list
|
||||
cusize = cusize - lastSymSz + cu[l-1].Size
|
||||
}
|
||||
for _, child := range cu[l:] {
|
||||
cusize += child.Size
|
||||
}
|
||||
}
|
||||
cu[len(cu)-1].AddUint8(0) // closes compilation unit DIE
|
||||
cusize++
|
||||
|
||||
// Save size for AIX symbol table.
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
saveDwsectCUSize(".debug_info", getPkgFromCUSym(s), uint64(cusize))
|
||||
}
|
||||
if isDwarf64(ctxt) {
|
||||
cusize -= 12 // exclude the length field.
|
||||
s.SetUint(ctxt.Arch, 4, uint64(cusize)) // 4 because of 0XFFFFFFFF
|
||||
} else {
|
||||
cusize -= 4 // exclude the length field.
|
||||
s.SetUint32(ctxt.Arch, 0, uint32(cusize))
|
||||
}
|
||||
pubNames.endCompUnit(compunit, uint32(cusize)+4)
|
||||
pubTypes.endCompUnit(compunit, uint32(cusize)+4)
|
||||
syms = append(syms, cu...)
|
||||
}
|
||||
return syms
|
||||
}
|
||||
|
||||
type pubWriter struct {
|
||||
ctxt *Link
|
||||
s *sym.Symbol
|
||||
sname string
|
||||
|
||||
sectionstart int64
|
||||
culengthOff int64
|
||||
}
|
||||
|
||||
func newPubWriter(ctxt *Link, sname string) *pubWriter {
|
||||
s := ctxt.Syms.Lookup(sname, 0)
|
||||
s.Type = sym.SDWARFSECT
|
||||
return &pubWriter{ctxt: ctxt, s: s, sname: sname}
|
||||
}
|
||||
|
||||
func (pw *pubWriter) beginCompUnit(compunit *dwarf.DWDie) {
|
||||
pw.sectionstart = pw.s.Size
|
||||
|
||||
// Write .debug_pubnames/types Header (sec 6.1.1)
|
||||
createUnitLength(pw.ctxt, pw.s, 0) // unit_length (*), will be filled in later.
|
||||
pw.s.AddUint16(pw.ctxt.Arch, 2) // dwarf version (appendix F)
|
||||
addDwarfAddrRef(pw.ctxt, pw.s, dtolsym(compunit.Sym)) // debug_info_offset (of the Comp unit Header)
|
||||
pw.culengthOff = pw.s.Size
|
||||
addDwarfAddrField(pw.ctxt, pw.s, uint64(0)) // debug_info_length, will be filled in later.
|
||||
|
||||
}
|
||||
|
||||
func (pw *pubWriter) add(die *dwarf.DWDie, offset int64) {
|
||||
dwa := getattr(die, dwarf.DW_AT_name)
|
||||
name := dwa.Data.(string)
|
||||
if die.Sym == nil {
|
||||
fmt.Println("Missing sym for ", name)
|
||||
}
|
||||
addDwarfAddrField(pw.ctxt, pw.s, uint64(offset))
|
||||
Addstring(pw.s, name)
|
||||
}
|
||||
|
||||
func (pw *pubWriter) endCompUnit(compunit *dwarf.DWDie, culength uint32) {
|
||||
addDwarfAddrField(pw.ctxt, pw.s, 0) // Null offset
|
||||
|
||||
// On AIX, save the current size of this compilation unit.
|
||||
if pw.ctxt.HeadType == objabi.Haix {
|
||||
saveDwsectCUSize(pw.sname, getPkgFromCUSym(dtolsym(compunit.Sym)), uint64(pw.s.Size-pw.sectionstart))
|
||||
}
|
||||
if isDwarf64(pw.ctxt) {
|
||||
pw.s.SetUint(pw.ctxt.Arch, pw.sectionstart+4, uint64(pw.s.Size-pw.sectionstart)-12) // exclude the length field.
|
||||
pw.s.SetUint(pw.ctxt.Arch, pw.culengthOff, uint64(culength))
|
||||
} else {
|
||||
pw.s.SetUint32(pw.ctxt.Arch, pw.sectionstart, uint32(pw.s.Size-pw.sectionstart)-4) // exclude the length field.
|
||||
pw.s.SetUint32(pw.ctxt.Arch, pw.culengthOff, culength)
|
||||
}
|
||||
}
|
||||
|
||||
func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
||||
// TODO (aix): make it available
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
return syms
|
||||
}
|
||||
if ctxt.LinkMode == LinkExternal && ctxt.HeadType == objabi.Hwindows && ctxt.BuildMode == BuildModeCArchive {
|
||||
// gcc on Windows places .debug_gdb_scripts in the wrong location, which
|
||||
// causes the program not to run. See https://golang.org/issue/20183
|
||||
// Non c-archives can avoid this issue via a linker script
|
||||
// (see fix near writeGDBLinkerScript).
|
||||
// c-archive users would need to specify the linker script manually.
|
||||
// For UX it's better not to deal with this.
|
||||
return syms
|
||||
}
|
||||
|
||||
if gdbscript != "" {
|
||||
s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
|
||||
s.Type = sym.SDWARFSECT
|
||||
syms = append(syms, s)
|
||||
s.AddUint8(1) // magic 1 byte?
|
||||
Addstring(s, gdbscript)
|
||||
}
|
||||
|
||||
return syms
|
||||
}
|
||||
|
||||
// dwarfGenerateDebugSyms constructs debug_line, debug_frame, debug_loc,
|
||||
// debug_pubnames and debug_pubtypes. It also writes out the debug_info
|
||||
// section using symbols generated in dwarfGenerateDebugInfo.
|
||||
func dwarfGenerateDebugSyms(ctxt *Link) {
|
||||
if !dwarfEnabled(ctxt) {
|
||||
return
|
||||
}
|
||||
if *FlagNewDw2 {
|
||||
dwarfGenerateDebugSyms2(ctxt)
|
||||
return
|
||||
}
|
||||
|
||||
abbrev := writeabbrev(ctxt)
|
||||
syms := []*sym.Symbol{abbrev}
|
||||
|
||||
calcCompUnitRanges(ctxt)
|
||||
sort.Sort(compilationUnitByStartPC(ctxt.compUnits))
|
||||
|
||||
// Write per-package line and range tables and start their CU DIEs.
|
||||
debugLine := ctxt.Syms.Lookup(".debug_line", 0)
|
||||
debugLine.Type = sym.SDWARFSECT
|
||||
debugRanges := ctxt.Syms.Lookup(".debug_ranges", 0)
|
||||
debugRanges.Type = sym.SDWARFRANGE
|
||||
debugRanges.Attr |= sym.AttrReachable
|
||||
syms = append(syms, debugLine)
|
||||
for _, u := range ctxt.compUnits {
|
||||
reversetree(&u.DWInfo.Child)
|
||||
if u.DWInfo.Abbrev == dwarf.DW_ABRV_COMPUNIT_TEXTLESS {
|
||||
continue
|
||||
}
|
||||
writelines(ctxt, u, debugLine)
|
||||
writepcranges(ctxt, u, u.Textp[0], u.PCs, debugRanges)
|
||||
}
|
||||
|
||||
// newdie adds DIEs to the *beginning* of the parent's DIE list.
|
||||
// Now that we're done creating DIEs, reverse the trees so DIEs
|
||||
// appear in the order they were created.
|
||||
reversetree(&dwtypes.Child)
|
||||
movetomodule(ctxt, &dwtypes)
|
||||
|
||||
pubNames := newPubWriter(ctxt, ".debug_pubnames")
|
||||
pubTypes := newPubWriter(ctxt, ".debug_pubtypes")
|
||||
|
||||
// Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT
|
||||
infosyms := writeinfo(ctxt, nil, ctxt.compUnits, abbrev, pubNames, pubTypes)
|
||||
|
||||
syms = writeframes(ctxt, syms)
|
||||
syms = append(syms, pubNames.s, pubTypes.s)
|
||||
syms = writegdbscript(ctxt, syms)
|
||||
// Now we're done writing SDWARFSECT symbols, so we can write
|
||||
// other SDWARF* symbols.
|
||||
syms = append(syms, infosyms...)
|
||||
syms = collectlocs(ctxt, syms, ctxt.compUnits)
|
||||
syms = append(syms, debugRanges)
|
||||
for _, unit := range ctxt.compUnits {
|
||||
syms = append(syms, unit.RangeSyms...)
|
||||
}
|
||||
dwarfp = syms
|
||||
}
|
||||
|
||||
func collectlocs(ctxt *Link, syms []*sym.Symbol, units []*sym.CompilationUnit) []*sym.Symbol {
|
||||
empty := true
|
||||
for _, u := range units {
|
||||
for _, fn := range u.FuncDIEs {
|
||||
for i := range fn.R {
|
||||
reloc := &fn.R[i] // Copying sym.Reloc has measurable impact on performance
|
||||
if reloc.Type == objabi.R_DWARFSECREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) {
|
||||
reloc.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
|
||||
syms = append(syms, reloc.Sym)
|
||||
empty = false
|
||||
// One location list entry per function, but many relocations to it. Don't duplicate.
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Don't emit .debug_loc if it's empty -- it makes the ARM linker mad.
|
||||
if !empty {
|
||||
locsym := ctxt.Syms.Lookup(".debug_loc", 0)
|
||||
locsym.Type = sym.SDWARFLOC
|
||||
locsym.Attr |= sym.AttrReachable
|
||||
syms = append(syms, locsym)
|
||||
}
|
||||
return syms
|
||||
}
|
||||
|
||||
// Read a pointer-sized uint from the beginning of buf.
|
||||
func readPtr(ctxt *Link, buf []byte) uint64 {
|
||||
switch ctxt.Arch.PtrSize {
|
||||
case 4:
|
||||
return uint64(ctxt.Arch.ByteOrder.Uint32(buf))
|
||||
case 8:
|
||||
return ctxt.Arch.ByteOrder.Uint64(buf)
|
||||
default:
|
||||
panic("unexpected pointer size")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Elf.
|
||||
*/
|
||||
@ -1008,31 +179,3 @@ func (v compilationUnitByStartPC) Less(i, j int) bool {
|
||||
return v[i].PCs[0].Start < v[j].PCs[0].Start
|
||||
}
|
||||
}
|
||||
|
||||
// On AIX, the symbol table needs to know where are the compilation units parts
|
||||
// for a specific package in each .dw section.
|
||||
// dwsectCUSize map will save the size of a compilation unit for
|
||||
// the corresponding .dw section.
|
||||
// This size can later be retrieved with the index "sectionName.pkgName".
|
||||
var dwsectCUSize map[string]uint64
|
||||
|
||||
// getDwsectCUSize retrieves the corresponding package size inside the current section.
|
||||
func getDwsectCUSize(sname string, pkgname string) uint64 {
|
||||
return dwsectCUSize[sname+"."+pkgname]
|
||||
}
|
||||
|
||||
func saveDwsectCUSize(sname string, pkgname string, size uint64) {
|
||||
dwsectCUSize[sname+"."+pkgname] = size
|
||||
}
|
||||
|
||||
func addDwsectCUSize(sname string, pkgname string, size uint64) {
|
||||
dwsectCUSize[sname+"."+pkgname] += size
|
||||
}
|
||||
|
||||
// getPkgFromCUSym returns the package name for the compilation unit
|
||||
// represented by s.
|
||||
// The prefix dwarf.InfoPrefix+".pkg." needs to be removed in order to get
|
||||
// the package name.
|
||||
func getPkgFromCUSym(s *sym.Symbol) string {
|
||||
return strings.TrimPrefix(s.Name, dwarf.InfoPrefix+".pkg.")
|
||||
}
|
||||
|
@ -2682,11 +2682,6 @@ func (ctxt *Link) loadlibfull() {
|
||||
ctxt.loader.ExtractSymbols(ctxt.Syms, ctxt.Reachparent)
|
||||
ctxt.lookup = ctxt.Syms.ROLookup
|
||||
|
||||
// When we generated dwarf DIE objects, we created them
|
||||
// with embedded loader.Sym refs as opposed to sym.Symbol refs.
|
||||
// Call a helper to rewrite the former to the latter in all DIEs.
|
||||
dwarfConvertSymbols(ctxt)
|
||||
|
||||
setupdynexp(ctxt)
|
||||
|
||||
// Drop the cgodata reference.
|
||||
|
@ -88,7 +88,6 @@ var (
|
||||
flagInterpreter = flag.String("I", "", "use `linker` as ELF dynamic linker")
|
||||
FlagDebugTramp = flag.Int("debugtramp", 0, "debug trampolines")
|
||||
FlagStrictDups = flag.Int("strictdups", 0, "sanity check duplicate symbol contents during object file reading (1=warn 2=err).")
|
||||
FlagNewDw2 = flag.Bool("newdw2", true, "DWARF gen phase 2 new loader")
|
||||
FlagRound = flag.Int("R", -1, "set address rounding `quantum`")
|
||||
FlagTextAddr = flag.Int64("T", -1, "set text segment `address`")
|
||||
flagEntrySymbol = flag.String("E", "", "set `entry` symbol name")
|
||||
|
Loading…
x
Reference in New Issue
Block a user