proc: be more lenient when parsing debug_info (#2394)
- allow a concrete subprogram to be treated as the abstract origin for an inlined call - allow nameless concrete and abstract subprograms Fixes #2393
This commit is contained in:
parent
da27e34217
commit
618f366998
@ -1917,10 +1917,8 @@ func (bi *BinaryInfo) addAbstractSubprogram(entry *dwarf.Entry, ctxt *loadDebugI
|
||||
name, ok := subprogramEntryName(entry, cu)
|
||||
if !ok {
|
||||
bi.logger.Warnf("reading debug_info: abstract subprogram without name at %#x", entry.Offset)
|
||||
if entry.Children {
|
||||
reader.SkipChildren()
|
||||
}
|
||||
return
|
||||
// In some cases clang produces abstract subprograms that do not have a
|
||||
// name, but we should process them anyway.
|
||||
}
|
||||
|
||||
if entry.Children {
|
||||
@ -1950,6 +1948,7 @@ func (bi *BinaryInfo) addConcreteInlinedSubprogram(entry *dwarf.Entry, originOff
|
||||
fn.offset = entry.Offset
|
||||
fn.Entry = lowpc
|
||||
fn.End = highpc
|
||||
fn.cu = cu
|
||||
|
||||
if entry.Children {
|
||||
bi.loadDebugInfoMapsInlinedCalls(ctxt, reader, cu)
|
||||
@ -1962,29 +1961,25 @@ func (bi *BinaryInfo) addConcreteSubprogram(entry *dwarf.Entry, ctxt *loadDebugI
|
||||
lowpc, highpc, ok := subprogramEntryRange(entry, cu.image)
|
||||
if !ok {
|
||||
bi.logger.Warnf("reading debug_info: concrete subprogram without address range at %#x", entry.Offset)
|
||||
if entry.Children {
|
||||
reader.SkipChildren()
|
||||
}
|
||||
return
|
||||
// When clang inlines a function, in some cases, it produces a concrete
|
||||
// subprogram without address range and then inlined calls that reference
|
||||
// it, instead of producing an abstract subprogram.
|
||||
// It is unclear if this behavior is standard.
|
||||
}
|
||||
|
||||
name, ok := subprogramEntryName(entry, cu)
|
||||
if !ok {
|
||||
bi.logger.Warnf("reading debug_info: concrete subprogram without name at %#x", entry.Offset)
|
||||
if entry.Children {
|
||||
reader.SkipChildren()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fn := Function{
|
||||
Name: name,
|
||||
Entry: lowpc,
|
||||
End: highpc,
|
||||
offset: entry.Offset,
|
||||
cu: cu,
|
||||
}
|
||||
bi.Functions = append(bi.Functions, fn)
|
||||
originIdx := ctxt.lookupAbstractOrigin(bi, entry.Offset)
|
||||
fn := &bi.Functions[originIdx]
|
||||
|
||||
fn.Name = name
|
||||
fn.Entry = lowpc
|
||||
fn.End = highpc
|
||||
fn.offset = entry.Offset
|
||||
fn.cu = cu
|
||||
|
||||
if entry.Children {
|
||||
bi.loadDebugInfoMapsInlinedCalls(ctxt, reader, cu)
|
||||
@ -2030,9 +2025,6 @@ func (bi *BinaryInfo) loadDebugInfoMapsInlinedCalls(ctxt *loadDebugInfoMapsConte
|
||||
continue
|
||||
}
|
||||
|
||||
originIdx := ctxt.lookupAbstractOrigin(bi, originOffset)
|
||||
fn := &bi.Functions[originIdx]
|
||||
|
||||
lowpc, highpc, ok := subprogramEntryRange(entry, cu.image)
|
||||
if !ok {
|
||||
bi.logger.Warnf("reading debug_info: inlined call without address range at %#x", entry.Offset)
|
||||
@ -2054,12 +2046,19 @@ func (bi *BinaryInfo) loadDebugInfoMapsInlinedCalls(ctxt *loadDebugInfoMapsConte
|
||||
continue
|
||||
}
|
||||
|
||||
originIdx := ctxt.lookupAbstractOrigin(bi, originOffset)
|
||||
fn := &bi.Functions[originIdx]
|
||||
|
||||
fn.InlinedCalls = append(fn.InlinedCalls, InlinedCall{
|
||||
cu: cu,
|
||||
LowPC: lowpc,
|
||||
HighPC: highpc,
|
||||
})
|
||||
|
||||
if fn.cu == nil {
|
||||
fn.cu = cu
|
||||
}
|
||||
|
||||
fl := fileLine{callfile, int(callline)}
|
||||
bi.inlinedCallLines[fl] = append(bi.inlinedCallLines[fl], lowpc)
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ func (ctxt *loadDebugInfoMapsContext) lookupAbstractOrigin(bi *BinaryInfo, off d
|
||||
if !ok {
|
||||
bi.Functions = append(bi.Functions, Function{})
|
||||
r = len(bi.Functions) - 1
|
||||
bi.Functions[r].offset = off
|
||||
ctxt.abstractOriginTable[off] = r
|
||||
}
|
||||
return r
|
||||
|
Loading…
Reference in New Issue
Block a user