diff options
author | Rafael Auler <rafaelauler@fb.com> | 2018-03-07 19:19:51 +0000 |
---|---|---|
committer | Rafael Auler <rafaelauler@fb.com> | 2018-03-07 19:19:51 +0000 |
commit | 7fdf44440ca47bbb3f52e2c01d77895fe1a2e0e1 (patch) | |
tree | fc008db81a38d91377f5af2425bef4cd69b6b362 /llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp | |
parent | 915b4dbf8a3cf694390243050f63ebccd3e10cf2 (diff) | |
download | bcm5719-llvm-7fdf44440ca47bbb3f52e2c01d77895fe1a2e0e1.tar.gz bcm5719-llvm-7fdf44440ca47bbb3f52e2c01d77895fe1a2e0e1.zip |
[DebugInfo] Support DWARF expressions in eh_frame
This patch enhances DWARFDebugFrame with the capability of parsing and
printing DWARF expressions in CFI instructions. It also makes FDEs and
CIEs accessible to lib users, so they can process them in client tools
that rely on LLVM. To make it self-contained with a test case, it
teaches llvm-readobj to be able to dump EH frames and checks they are
correct in a unit test. The llvm-readobj code is Maksim Panchenko's work
(maksfb).
Reviewers: JDevlieghere, espindola
Reviewed By: JDevlieghere
Differential Revision: https://reviews.llvm.org/D43313
llvm-svn: 326932
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp index 861dd313fb0..03e31746139 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" using namespace llvm; @@ -25,3 +26,71 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, *SecNdx = Rel->SectionIndex; return getUnsigned(Off, Size) + Rel->Value; } + +Optional<uint64_t> +DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding, + uint64_t PCRelOffset) const { + if (Encoding == dwarf::DW_EH_PE_omit) + return None; + + uint64_t Result = 0; + uint32_t OldOffset = *Offset; + // First get value + switch (Encoding & 0x0F) { + case dwarf::DW_EH_PE_absptr: + switch (getAddressSize()) { + case 2: + case 4: + case 8: + Result = getUnsigned(Offset, getAddressSize()); + break; + default: + return None; + } + break; + case dwarf::DW_EH_PE_uleb128: + Result = getULEB128(Offset); + break; + case dwarf::DW_EH_PE_sleb128: + Result = getSLEB128(Offset); + break; + case dwarf::DW_EH_PE_udata2: + Result = getUnsigned(Offset, 2); + break; + case dwarf::DW_EH_PE_udata4: + Result = getUnsigned(Offset, 4); + break; + case dwarf::DW_EH_PE_udata8: + Result = getUnsigned(Offset, 8); + break; + case dwarf::DW_EH_PE_sdata2: + Result = getSigned(Offset, 2); + break; + case dwarf::DW_EH_PE_sdata4: + Result = getSigned(Offset, 4); + break; + case dwarf::DW_EH_PE_sdata8: + Result = getSigned(Offset, 8); + break; + default: + return None; + } + // Then add relative offset, if required + switch (Encoding & 0x70) { + case dwarf::DW_EH_PE_absptr: + // do nothing + break; + case dwarf::DW_EH_PE_pcrel: + Result += PCRelOffset; + break; + case dwarf::DW_EH_PE_datarel: + case dwarf::DW_EH_PE_textrel: + case dwarf::DW_EH_PE_funcrel: + case dwarf::DW_EH_PE_aligned: + default: + *Offset = OldOffset; + return None; + } + + return Result; +} |