mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 01:27:16 +08:00
proc: simplify partial unit support (#1565)
Instead of reading partial units as we see them skip them entirely and then re-read them when they are imported, directly into the destination compile unit. This avoids a lot of duplicate code in the loadDebugInfoMaps function and will simplify implementing logical breakpoints and support for the new DW_AT_go_package_name attribute added in Go 1.13.
This commit is contained in:
committed by
Derek Parker
parent
7c18354c1c
commit
215e13e81b
@ -123,20 +123,6 @@ type dwarfRef struct {
|
|||||||
offset dwarf.Offset
|
offset dwarf.Offset
|
||||||
}
|
}
|
||||||
|
|
||||||
type partialUnitConstant struct {
|
|
||||||
name string
|
|
||||||
typ dwarf.Offset
|
|
||||||
value int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type partialUnit struct {
|
|
||||||
entry *dwarf.Entry
|
|
||||||
types map[string]dwarf.Offset
|
|
||||||
variables []packageVar
|
|
||||||
constants []partialUnitConstant
|
|
||||||
functions []Function
|
|
||||||
}
|
|
||||||
|
|
||||||
// inlinedFn represents a concrete inlined function, e.g.
|
// inlinedFn represents a concrete inlined function, e.g.
|
||||||
// an entry for the generated code of an inlined function.
|
// an entry for the generated code of an inlined function.
|
||||||
type inlinedFn struct {
|
type inlinedFn struct {
|
||||||
|
|||||||
@ -176,16 +176,31 @@ func (v packageVarsByAddr) Len() int { return len(v) }
|
|||||||
func (v packageVarsByAddr) Less(i int, j int) bool { return v[i].addr < v[j].addr }
|
func (v packageVarsByAddr) Less(i int, j int) bool { return v[i].addr < v[j].addr }
|
||||||
func (v packageVarsByAddr) Swap(i int, j int) { v[i], v[j] = v[j], v[i] }
|
func (v packageVarsByAddr) Swap(i int, j int) { v[i], v[j] = v[j], v[i] }
|
||||||
|
|
||||||
|
type loadDebugInfoMapsContext struct {
|
||||||
|
ardr *reader.Reader
|
||||||
|
abstractOriginNameTable map[dwarf.Offset]string
|
||||||
|
knownPackageVars map[string]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLoadDebugInfoMapsContext(bi *BinaryInfo, image *Image) *loadDebugInfoMapsContext {
|
||||||
|
ctxt := &loadDebugInfoMapsContext{}
|
||||||
|
|
||||||
|
ctxt.ardr = image.DwarfReader()
|
||||||
|
ctxt.abstractOriginNameTable = make(map[dwarf.Offset]string)
|
||||||
|
|
||||||
|
ctxt.knownPackageVars = map[string]struct{}{}
|
||||||
|
for _, v := range bi.packageVars {
|
||||||
|
ctxt.knownPackageVars[v.name] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctxt
|
||||||
|
}
|
||||||
|
|
||||||
func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugLineBytes []byte, wg *sync.WaitGroup, cont func()) {
|
func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugLineBytes []byte, wg *sync.WaitGroup, cont func()) {
|
||||||
if wg != nil {
|
if wg != nil {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
var cu *compileUnit
|
|
||||||
var pu *partialUnit
|
|
||||||
var partialUnits = make(map[dwarf.Offset]*partialUnit)
|
|
||||||
var lastOffset dwarf.Offset
|
|
||||||
|
|
||||||
if !bi.initialized {
|
if !bi.initialized {
|
||||||
bi.types = make(map[string]dwarfRef)
|
bi.types = make(map[string]dwarfRef)
|
||||||
bi.consts = make(map[dwarfRef]*constantType)
|
bi.consts = make(map[dwarfRef]*constantType)
|
||||||
@ -194,31 +209,18 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugLineBytes []byte, wg
|
|||||||
}
|
}
|
||||||
image.runtimeTypeToDIE = make(map[uint64]runtimeTypeDIE)
|
image.runtimeTypeToDIE = make(map[uint64]runtimeTypeDIE)
|
||||||
|
|
||||||
|
ctxt := newLoadDebugInfoMapsContext(bi, image)
|
||||||
|
|
||||||
reader := image.DwarfReader()
|
reader := image.DwarfReader()
|
||||||
ardr := image.DwarfReader()
|
|
||||||
abstractOriginNameTable := make(map[dwarf.Offset]string)
|
|
||||||
|
|
||||||
knownPackageVars := map[string]struct{}{}
|
|
||||||
for _, v := range bi.packageVars {
|
|
||||||
knownPackageVars[v.name] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
outer:
|
|
||||||
for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() {
|
for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
image.setLoadError("error reading debug_info: %v", err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
lastOffset = entry.Offset
|
|
||||||
switch entry.Tag {
|
switch entry.Tag {
|
||||||
case dwarf.TagCompileUnit:
|
case dwarf.TagCompileUnit:
|
||||||
if pu != nil {
|
cu := &compileUnit{}
|
||||||
partialUnits[pu.entry.Offset] = pu
|
|
||||||
pu = nil
|
|
||||||
}
|
|
||||||
if cu != nil {
|
|
||||||
cu.endOffset = entry.Offset
|
|
||||||
}
|
|
||||||
cu = &compileUnit{}
|
|
||||||
cu.image = image
|
cu.image = image
|
||||||
cu.entry = entry
|
cu.entry = entry
|
||||||
cu.startOffset = entry.Offset
|
cu.startOffset = entry.Offset
|
||||||
@ -261,221 +263,17 @@ outer:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bi.compileUnits = append(bi.compileUnits, cu)
|
bi.compileUnits = append(bi.compileUnits, cu)
|
||||||
|
cu.endOffset = bi.loadDebugInfoMapsCompileUnit(ctxt, image, reader, cu)
|
||||||
|
|
||||||
case dwarf.TagPartialUnit:
|
case dwarf.TagPartialUnit:
|
||||||
if pu != nil {
|
|
||||||
partialUnits[pu.entry.Offset] = pu
|
|
||||||
pu = nil
|
|
||||||
}
|
|
||||||
pu = &partialUnit{}
|
|
||||||
pu.entry = entry
|
|
||||||
pu.types = make(map[string]dwarf.Offset)
|
|
||||||
|
|
||||||
case dwarf.TagImportedUnit:
|
|
||||||
if unit, exists := partialUnits[entry.Val(dwarf.AttrImport).(dwarf.Offset)]; exists {
|
|
||||||
for name, offset := range unit.types {
|
|
||||||
if pu != nil {
|
|
||||||
pu.types[name] = offset
|
|
||||||
} else {
|
|
||||||
if !cu.isgo {
|
|
||||||
name = "C." + name
|
|
||||||
}
|
|
||||||
bi.types[name] = dwarfRef{image.index, offset}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pVar := range unit.variables {
|
|
||||||
if pu != nil {
|
|
||||||
pu.variables = append(pu.variables, pVar)
|
|
||||||
} else {
|
|
||||||
pVar2 := pVar
|
|
||||||
if !cu.isgo {
|
|
||||||
pVar2.name = "C." + pVar2.name
|
|
||||||
}
|
|
||||||
pVar2.cu = cu
|
|
||||||
if _, known := knownPackageVars[pVar2.name]; !known {
|
|
||||||
bi.packageVars = append(bi.packageVars, pVar2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pCt := range unit.constants {
|
|
||||||
if pu != nil {
|
|
||||||
pu.constants = append(pu.constants, pCt)
|
|
||||||
} else {
|
|
||||||
if !cu.isgo {
|
|
||||||
pCt.name = "C." + pCt.name
|
|
||||||
}
|
|
||||||
ct := bi.consts[dwarfRef{image.index, pCt.typ}]
|
|
||||||
if ct == nil {
|
|
||||||
ct = &constantType{}
|
|
||||||
bi.consts[dwarfRef{image.index, pCt.typ}] = ct
|
|
||||||
}
|
|
||||||
ct.values = append(ct.values, constantValue{name: pCt.name, fullName: pCt.name, value: pCt.value})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pFunc := range unit.functions {
|
|
||||||
if pu != nil {
|
|
||||||
pu.functions = append(pu.functions, pFunc)
|
|
||||||
} else {
|
|
||||||
if !cu.isgo {
|
|
||||||
pFunc.Name = "C." + pFunc.Name
|
|
||||||
}
|
|
||||||
pFunc.cu = cu
|
|
||||||
bi.Functions = append(bi.Functions, pFunc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case dwarf.TagArrayType, dwarf.TagBaseType, dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType, dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType, dwarf.TagEnumerationType, dwarf.TagPointerType, dwarf.TagSubroutineType, dwarf.TagTypedef, dwarf.TagUnspecifiedType:
|
|
||||||
if name, ok := entry.Val(dwarf.AttrName).(string); ok {
|
|
||||||
if pu != nil {
|
|
||||||
if _, exists := pu.types[name]; !exists {
|
|
||||||
pu.types[name] = entry.Offset
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !cu.isgo {
|
|
||||||
name = "C." + name
|
|
||||||
}
|
|
||||||
if _, exists := bi.types[name]; !exists {
|
|
||||||
bi.types[name] = dwarfRef{image.index, entry.Offset}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cu != nil && cu.isgo {
|
|
||||||
bi.registerTypeToPackageMap(entry)
|
|
||||||
}
|
|
||||||
image.registerRuntimeTypeToDIE(entry, ardr)
|
|
||||||
reader.SkipChildren()
|
reader.SkipChildren()
|
||||||
|
|
||||||
case dwarf.TagVariable:
|
default:
|
||||||
if n, ok := entry.Val(dwarf.AttrName).(string); ok {
|
// ignore unknown tags
|
||||||
var addr uint64
|
reader.SkipChildren()
|
||||||
if loc, ok := entry.Val(dwarf.AttrLocation).([]byte); ok {
|
|
||||||
if len(loc) == bi.Arch.PtrSize()+1 && op.Opcode(loc[0]) == op.DW_OP_addr {
|
|
||||||
addr = binary.LittleEndian.Uint64(loc[1:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if pu != nil {
|
|
||||||
pu.variables = append(pu.variables, packageVar{n, nil, entry.Offset, addr + image.StaticBase})
|
|
||||||
} else {
|
|
||||||
if !cu.isgo {
|
|
||||||
n = "C." + n
|
|
||||||
}
|
|
||||||
if _, known := knownPackageVars[n]; !known {
|
|
||||||
bi.packageVars = append(bi.packageVars, packageVar{n, cu, entry.Offset, addr + image.StaticBase})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case dwarf.TagConstant:
|
|
||||||
name, okName := entry.Val(dwarf.AttrName).(string)
|
|
||||||
typ, okType := entry.Val(dwarf.AttrType).(dwarf.Offset)
|
|
||||||
val, okVal := entry.Val(dwarf.AttrConstValue).(int64)
|
|
||||||
if okName && okType && okVal {
|
|
||||||
if pu != nil {
|
|
||||||
pu.constants = append(pu.constants, partialUnitConstant{name: name, typ: typ, value: val})
|
|
||||||
} else {
|
|
||||||
if !cu.isgo {
|
|
||||||
name = "C." + name
|
|
||||||
}
|
|
||||||
ct := bi.consts[dwarfRef{image.index, typ}]
|
|
||||||
if ct == nil {
|
|
||||||
ct = &constantType{}
|
|
||||||
bi.consts[dwarfRef{image.index, typ}] = ct
|
|
||||||
}
|
|
||||||
ct.values = append(ct.values, constantValue{name: name, fullName: name, value: val})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case dwarf.TagSubprogram:
|
|
||||||
ok1 := false
|
|
||||||
inlined := false
|
|
||||||
var lowpc, highpc uint64
|
|
||||||
if inval, ok := entry.Val(dwarf.AttrInline).(int64); ok {
|
|
||||||
inlined = inval == 1
|
|
||||||
}
|
|
||||||
if ranges, _ := image.dwarf.Ranges(entry); len(ranges) == 1 {
|
|
||||||
ok1 = true
|
|
||||||
lowpc = ranges[0][0] + image.StaticBase
|
|
||||||
highpc = ranges[0][1] + image.StaticBase
|
|
||||||
}
|
|
||||||
name, ok2 := entry.Val(dwarf.AttrName).(string)
|
|
||||||
if !ok2 {
|
|
||||||
originOffset, hasAbstractOrigin := entry.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
|
|
||||||
if hasAbstractOrigin {
|
|
||||||
name, ok2 = abstractOriginNameTable[originOffset]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var fn Function
|
|
||||||
if (ok1 == !inlined) && ok2 {
|
|
||||||
if inlined {
|
|
||||||
abstractOriginNameTable[entry.Offset] = name
|
|
||||||
}
|
|
||||||
if pu != nil {
|
|
||||||
fn = Function{
|
|
||||||
Name: name,
|
|
||||||
Entry: lowpc, End: highpc,
|
|
||||||
offset: entry.Offset,
|
|
||||||
cu: &compileUnit{},
|
|
||||||
}
|
|
||||||
pu.functions = append(pu.functions, fn)
|
|
||||||
} else {
|
|
||||||
if !cu.isgo {
|
|
||||||
name = "C." + name
|
|
||||||
}
|
|
||||||
fn = Function{
|
|
||||||
Name: name,
|
|
||||||
Entry: lowpc, End: highpc,
|
|
||||||
offset: entry.Offset,
|
|
||||||
cu: cu,
|
|
||||||
}
|
|
||||||
bi.Functions = append(bi.Functions, fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if entry.Children {
|
|
||||||
for {
|
|
||||||
entry, err = reader.Next()
|
|
||||||
if err != nil {
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
if entry.Tag == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if entry.Tag == dwarf.TagInlinedSubroutine {
|
|
||||||
originOffset := entry.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
|
|
||||||
name := abstractOriginNameTable[originOffset]
|
|
||||||
if ranges, _ := image.dwarf.Ranges(entry); len(ranges) == 1 {
|
|
||||||
ok1 = true
|
|
||||||
lowpc = ranges[0][0]
|
|
||||||
highpc = ranges[0][1]
|
|
||||||
}
|
|
||||||
callfileidx, ok1 := entry.Val(dwarf.AttrCallFile).(int64)
|
|
||||||
callline, ok2 := entry.Val(dwarf.AttrCallLine).(int64)
|
|
||||||
if ok1 && ok2 {
|
|
||||||
callfile := cu.lineInfo.FileNames[callfileidx-1].Path
|
|
||||||
cu.concreteInlinedFns = append(cu.concreteInlinedFns, inlinedFn{
|
|
||||||
Name: name,
|
|
||||||
LowPC: lowpc + image.StaticBase,
|
|
||||||
HighPC: highpc + image.StaticBase,
|
|
||||||
CallFile: callfile,
|
|
||||||
CallLine: callline,
|
|
||||||
Parent: &fn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reader.SkipChildren()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cu != nil {
|
|
||||||
cu.endOffset = lastOffset + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(compileUnitsByLowpc(bi.compileUnits))
|
sort.Sort(compileUnitsByLowpc(bi.compileUnits))
|
||||||
sort.Sort(functionsDebugInfoByEntry(bi.Functions))
|
sort.Sort(functionsDebugInfoByEntry(bi.Functions))
|
||||||
sort.Sort(packageVarsByAddr(bi.packageVars))
|
sort.Sort(packageVarsByAddr(bi.packageVars))
|
||||||
@ -501,6 +299,169 @@ outer:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadDebugInfoMapsCompileUnit loads entry from a single compile unit.
|
||||||
|
func (bi *BinaryInfo) loadDebugInfoMapsCompileUnit(ctxt *loadDebugInfoMapsContext, image *Image, reader *reader.Reader, cu *compileUnit) dwarf.Offset {
|
||||||
|
var lastOffset dwarf.Offset
|
||||||
|
for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() {
|
||||||
|
if err != nil {
|
||||||
|
image.setLoadError("error reading debug_info: %v", err)
|
||||||
|
return lastOffset + 1
|
||||||
|
}
|
||||||
|
if entry.Tag != 0 {
|
||||||
|
lastOffset = entry.Offset
|
||||||
|
}
|
||||||
|
switch entry.Tag {
|
||||||
|
case 0:
|
||||||
|
return lastOffset + 1
|
||||||
|
case dwarf.TagImportedUnit:
|
||||||
|
bi.loadDebugInfoMapsImportedUnit(entry, ctxt, image, cu)
|
||||||
|
reader.SkipChildren()
|
||||||
|
|
||||||
|
case dwarf.TagArrayType, dwarf.TagBaseType, dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType, dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType, dwarf.TagEnumerationType, dwarf.TagPointerType, dwarf.TagSubroutineType, dwarf.TagTypedef, dwarf.TagUnspecifiedType:
|
||||||
|
if name, ok := entry.Val(dwarf.AttrName).(string); ok {
|
||||||
|
if !cu.isgo {
|
||||||
|
name = "C." + name
|
||||||
|
}
|
||||||
|
if _, exists := bi.types[name]; !exists {
|
||||||
|
bi.types[name] = dwarfRef{image.index, entry.Offset}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cu != nil && cu.isgo {
|
||||||
|
bi.registerTypeToPackageMap(entry)
|
||||||
|
}
|
||||||
|
image.registerRuntimeTypeToDIE(entry, ctxt.ardr)
|
||||||
|
reader.SkipChildren()
|
||||||
|
|
||||||
|
case dwarf.TagVariable:
|
||||||
|
if n, ok := entry.Val(dwarf.AttrName).(string); ok {
|
||||||
|
var addr uint64
|
||||||
|
if loc, ok := entry.Val(dwarf.AttrLocation).([]byte); ok {
|
||||||
|
if len(loc) == bi.Arch.PtrSize()+1 && op.Opcode(loc[0]) == op.DW_OP_addr {
|
||||||
|
addr = binary.LittleEndian.Uint64(loc[1:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !cu.isgo {
|
||||||
|
n = "C." + n
|
||||||
|
}
|
||||||
|
if _, known := ctxt.knownPackageVars[n]; !known {
|
||||||
|
bi.packageVars = append(bi.packageVars, packageVar{n, cu, entry.Offset, addr + image.StaticBase})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.SkipChildren()
|
||||||
|
|
||||||
|
case dwarf.TagConstant:
|
||||||
|
name, okName := entry.Val(dwarf.AttrName).(string)
|
||||||
|
typ, okType := entry.Val(dwarf.AttrType).(dwarf.Offset)
|
||||||
|
val, okVal := entry.Val(dwarf.AttrConstValue).(int64)
|
||||||
|
if okName && okType && okVal {
|
||||||
|
if !cu.isgo {
|
||||||
|
name = "C." + name
|
||||||
|
}
|
||||||
|
ct := bi.consts[dwarfRef{image.index, typ}]
|
||||||
|
if ct == nil {
|
||||||
|
ct = &constantType{}
|
||||||
|
bi.consts[dwarfRef{image.index, typ}] = ct
|
||||||
|
}
|
||||||
|
ct.values = append(ct.values, constantValue{name: name, fullName: name, value: val})
|
||||||
|
}
|
||||||
|
reader.SkipChildren()
|
||||||
|
|
||||||
|
case dwarf.TagSubprogram:
|
||||||
|
ok1 := false
|
||||||
|
inlined := false
|
||||||
|
var lowpc, highpc uint64
|
||||||
|
if inval, ok := entry.Val(dwarf.AttrInline).(int64); ok {
|
||||||
|
inlined = inval == 1
|
||||||
|
}
|
||||||
|
if ranges, _ := image.dwarf.Ranges(entry); len(ranges) == 1 {
|
||||||
|
ok1 = true
|
||||||
|
lowpc = ranges[0][0] + image.StaticBase
|
||||||
|
highpc = ranges[0][1] + image.StaticBase
|
||||||
|
}
|
||||||
|
name, ok2 := entry.Val(dwarf.AttrName).(string)
|
||||||
|
if !ok2 {
|
||||||
|
originOffset, hasAbstractOrigin := entry.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
|
||||||
|
if hasAbstractOrigin {
|
||||||
|
name, ok2 = ctxt.abstractOriginNameTable[originOffset]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fn Function
|
||||||
|
if (ok1 == !inlined) && ok2 {
|
||||||
|
if inlined {
|
||||||
|
ctxt.abstractOriginNameTable[entry.Offset] = name
|
||||||
|
}
|
||||||
|
if !cu.isgo {
|
||||||
|
name = "C." + name
|
||||||
|
}
|
||||||
|
fn = Function{
|
||||||
|
Name: name,
|
||||||
|
Entry: lowpc, End: highpc,
|
||||||
|
offset: entry.Offset,
|
||||||
|
cu: cu,
|
||||||
|
}
|
||||||
|
bi.Functions = append(bi.Functions, fn)
|
||||||
|
}
|
||||||
|
if entry.Children {
|
||||||
|
for {
|
||||||
|
entry, err = reader.Next()
|
||||||
|
if err != nil {
|
||||||
|
image.setLoadError("error reading debug_info: %v", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if entry.Tag == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if entry.Tag == dwarf.TagInlinedSubroutine {
|
||||||
|
originOffset := entry.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
|
||||||
|
name := ctxt.abstractOriginNameTable[originOffset]
|
||||||
|
if ranges, _ := image.dwarf.Ranges(entry); len(ranges) == 1 {
|
||||||
|
ok1 = true
|
||||||
|
lowpc = ranges[0][0]
|
||||||
|
highpc = ranges[0][1]
|
||||||
|
}
|
||||||
|
callfileidx, ok1 := entry.Val(dwarf.AttrCallFile).(int64)
|
||||||
|
callline, ok2 := entry.Val(dwarf.AttrCallLine).(int64)
|
||||||
|
if ok1 && ok2 {
|
||||||
|
callfile := cu.lineInfo.FileNames[callfileidx-1].Path
|
||||||
|
cu.concreteInlinedFns = append(cu.concreteInlinedFns, inlinedFn{
|
||||||
|
Name: name,
|
||||||
|
LowPC: lowpc + image.StaticBase,
|
||||||
|
HighPC: highpc + image.StaticBase,
|
||||||
|
CallFile: callfile,
|
||||||
|
CallLine: callline,
|
||||||
|
Parent: &fn,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.SkipChildren()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastOffset + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadDebugInfoMapsImportedUnit loads entries into cu from the partial unit
|
||||||
|
// referenced in a DW_TAG_imported_unit entry.
|
||||||
|
func (bi *BinaryInfo) loadDebugInfoMapsImportedUnit(entry *dwarf.Entry, ctxt *loadDebugInfoMapsContext, image *Image, cu *compileUnit) {
|
||||||
|
off, ok := entry.Val(dwarf.AttrImport).(dwarf.Offset)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reader := image.DwarfReader()
|
||||||
|
reader.Seek(off)
|
||||||
|
imentry, err := reader.Next()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if imentry.Tag != dwarf.TagPartialUnit {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bi.loadDebugInfoMapsCompileUnit(ctxt, image, reader, cu)
|
||||||
|
}
|
||||||
|
|
||||||
func uniq(s []string) []string {
|
func uniq(s []string) []string {
|
||||||
if len(s) <= 0 {
|
if len(s) <= 0 {
|
||||||
return s
|
return s
|
||||||
|
|||||||
Reference in New Issue
Block a user