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)
|
name, ok := subprogramEntryName(entry, cu)
|
||||||
if !ok {
|
if !ok {
|
||||||
bi.logger.Warnf("reading debug_info: abstract subprogram without name at %#x", entry.Offset)
|
bi.logger.Warnf("reading debug_info: abstract subprogram without name at %#x", entry.Offset)
|
||||||
if entry.Children {
|
// In some cases clang produces abstract subprograms that do not have a
|
||||||
reader.SkipChildren()
|
// name, but we should process them anyway.
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Children {
|
if entry.Children {
|
||||||
@ -1950,6 +1948,7 @@ func (bi *BinaryInfo) addConcreteInlinedSubprogram(entry *dwarf.Entry, originOff
|
|||||||
fn.offset = entry.Offset
|
fn.offset = entry.Offset
|
||||||
fn.Entry = lowpc
|
fn.Entry = lowpc
|
||||||
fn.End = highpc
|
fn.End = highpc
|
||||||
|
fn.cu = cu
|
||||||
|
|
||||||
if entry.Children {
|
if entry.Children {
|
||||||
bi.loadDebugInfoMapsInlinedCalls(ctxt, reader, cu)
|
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)
|
lowpc, highpc, ok := subprogramEntryRange(entry, cu.image)
|
||||||
if !ok {
|
if !ok {
|
||||||
bi.logger.Warnf("reading debug_info: concrete subprogram without address range at %#x", entry.Offset)
|
bi.logger.Warnf("reading debug_info: concrete subprogram without address range at %#x", entry.Offset)
|
||||||
if entry.Children {
|
// When clang inlines a function, in some cases, it produces a concrete
|
||||||
reader.SkipChildren()
|
// subprogram without address range and then inlined calls that reference
|
||||||
}
|
// it, instead of producing an abstract subprogram.
|
||||||
return
|
// It is unclear if this behavior is standard.
|
||||||
}
|
}
|
||||||
|
|
||||||
name, ok := subprogramEntryName(entry, cu)
|
name, ok := subprogramEntryName(entry, cu)
|
||||||
if !ok {
|
if !ok {
|
||||||
bi.logger.Warnf("reading debug_info: concrete subprogram without name at %#x", entry.Offset)
|
bi.logger.Warnf("reading debug_info: concrete subprogram without name at %#x", entry.Offset)
|
||||||
if entry.Children {
|
|
||||||
reader.SkipChildren()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := Function{
|
originIdx := ctxt.lookupAbstractOrigin(bi, entry.Offset)
|
||||||
Name: name,
|
fn := &bi.Functions[originIdx]
|
||||||
Entry: lowpc,
|
|
||||||
End: highpc,
|
fn.Name = name
|
||||||
offset: entry.Offset,
|
fn.Entry = lowpc
|
||||||
cu: cu,
|
fn.End = highpc
|
||||||
}
|
fn.offset = entry.Offset
|
||||||
bi.Functions = append(bi.Functions, fn)
|
fn.cu = cu
|
||||||
|
|
||||||
if entry.Children {
|
if entry.Children {
|
||||||
bi.loadDebugInfoMapsInlinedCalls(ctxt, reader, cu)
|
bi.loadDebugInfoMapsInlinedCalls(ctxt, reader, cu)
|
||||||
@ -2030,9 +2025,6 @@ func (bi *BinaryInfo) loadDebugInfoMapsInlinedCalls(ctxt *loadDebugInfoMapsConte
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
originIdx := ctxt.lookupAbstractOrigin(bi, originOffset)
|
|
||||||
fn := &bi.Functions[originIdx]
|
|
||||||
|
|
||||||
lowpc, highpc, ok := subprogramEntryRange(entry, cu.image)
|
lowpc, highpc, ok := subprogramEntryRange(entry, cu.image)
|
||||||
if !ok {
|
if !ok {
|
||||||
bi.logger.Warnf("reading debug_info: inlined call without address range at %#x", entry.Offset)
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
originIdx := ctxt.lookupAbstractOrigin(bi, originOffset)
|
||||||
|
fn := &bi.Functions[originIdx]
|
||||||
|
|
||||||
fn.InlinedCalls = append(fn.InlinedCalls, InlinedCall{
|
fn.InlinedCalls = append(fn.InlinedCalls, InlinedCall{
|
||||||
cu: cu,
|
cu: cu,
|
||||||
LowPC: lowpc,
|
LowPC: lowpc,
|
||||||
HighPC: highpc,
|
HighPC: highpc,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if fn.cu == nil {
|
||||||
|
fn.cu = cu
|
||||||
|
}
|
||||||
|
|
||||||
fl := fileLine{callfile, int(callline)}
|
fl := fileLine{callfile, int(callline)}
|
||||||
bi.inlinedCallLines[fl] = append(bi.inlinedCallLines[fl], lowpc)
|
bi.inlinedCallLines[fl] = append(bi.inlinedCallLines[fl], lowpc)
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ func (ctxt *loadDebugInfoMapsContext) lookupAbstractOrigin(bi *BinaryInfo, off d
|
|||||||
if !ok {
|
if !ok {
|
||||||
bi.Functions = append(bi.Functions, Function{})
|
bi.Functions = append(bi.Functions, Function{})
|
||||||
r = len(bi.Functions) - 1
|
r = len(bi.Functions) - 1
|
||||||
|
bi.Functions[r].offset = off
|
||||||
ctxt.abstractOriginTable[off] = r
|
ctxt.abstractOriginTable[off] = r
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
|
Loading…
Reference in New Issue
Block a user