diff options
Diffstat (limited to 'contrib/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp')
| -rw-r--r-- | contrib/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp | 69 | 
1 files changed, 69 insertions, 0 deletions
diff --git a/contrib/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/contrib/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp index 861dd313fb09..03e317461396 100644 --- a/contrib/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ b/contrib/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; +}  | 
