diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -16,6 +16,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/Support/Error.h" +#include #include #include #include @@ -686,9 +687,20 @@ void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, Optional Offset) const; + using RefHandlerType = + std::function; + /// Parse the section from raw data. \p Data is assumed to contain the whole /// frame section contents to be parsed. - Error parse(DWARFDataExtractor Data); + /// If non-null RefHandler is passed, call it for every encountered external + /// reference in frame data. The expected signature is: + /// + /// void RefHandler(uint64_t Value, uint64_t Offset, uint64_t Type); + /// + /// where Value is a value of the reference, Offset - is an offset into the + /// frame data at which the reference occured, and Type is a DWARF encoding + /// type of the reference. + Error parse(DWARFDataExtractor Data, RefHandlerType RefHandler= nullptr); /// Return whether the section has any entries. bool empty() const { return Entries.empty(); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -1032,7 +1032,8 @@ errs() << "\n"; } -Error DWARFDebugFrame::parse(DWARFDataExtractor Data) { +Error DWARFDebugFrame::parse(DWARFDataExtractor Data, + RefHandlerType RefHandler) { uint64_t Offset = 0; DenseMap CIEs; @@ -1114,6 +1115,8 @@ Personality = Data.getEncodedPointer( &Offset, *PersonalityEncoding, EHFrameAddress ? EHFrameAddress + Offset : 0); + if (RefHandler) + RefHandler(*Personality, Offset, *PersonalityEncoding); break; } case 'R': @@ -1179,6 +1182,8 @@ EHFrameAddress + Offset)) { InitialLocation = *Val; } + if (RefHandler) + RefHandler(InitialLocation, Offset, Cie->getFDEPointerEncoding()); if (auto Val = Data.getEncodedPointer( &Offset, Cie->getFDEPointerEncoding(), 0)) { AddressRange = *Val; @@ -1196,6 +1201,8 @@ LSDAAddress = Data.getEncodedPointer( &Offset, Cie->getLSDAPointerEncoding(), EHFrameAddress ? Offset + EHFrameAddress : 0); + if (RefHandler) + RefHandler(*LSDAAddress, Offset, Cie->getLSDAPointerEncoding()); } if (Offset != EndAugmentationOffset)