예제 #1
0
void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
  uint32_t Offset = 0;
  while (data.isValidOffset(Offset+AddressSize-1)) {
    Locations.resize(Locations.size() + 1);
    LocationList &Loc = Locations.back();
    Loc.Offset = Offset;
    // 2.6.2 Location Lists
    // A location list entry consists of:
    while (true) {
      Entry E;
      RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
      // 1. A beginning address offset. ...
      E.Begin = data.getUnsigned(&Offset, AddressSize);
      if (AI != RelocMap.end())
        E.Begin += AI->second.second;

      AI = RelocMap.find(Offset);
      // 2. An ending address offset. ...
      E.End = data.getUnsigned(&Offset, AddressSize);
      if (AI != RelocMap.end())
        E.End += AI->second.second;

      // The end of any given location list is marked by an end of list entry,
      // which consists of a 0 for the beginning address offset and a 0 for the
      // ending address offset.
      if (E.Begin == 0 && E.End == 0)
        break;

      unsigned Bytes = data.getU16(&Offset);
      // A single location description describing the location of the object...
      StringRef str = data.getData().substr(Offset, Bytes);
      Offset += Bytes;
      E.Loc.reserve(str.size());
      std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
      Loc.Entries.push_back(llvm_move(E));
    }
  }
  if (data.isValidOffset(Offset))
    llvm::errs() << "error: failed to consume entire .debug_loc section\n";
}
예제 #2
0
void DWARFDebugFrame::parse(DataExtractor Data) {
  uint32_t Offset = 0;
  DenseMap<uint32_t, CIE *> CIEs;

  while (Data.isValidOffset(Offset)) {
    uint32_t StartOffset = Offset;

    bool IsDWARF64 = false;
    uint64_t Length = Data.getU32(&Offset);
    uint64_t Id;

    if (Length == UINT32_MAX) {
      // DWARF-64 is distinguished by the first 32 bits of the initial length
      // field being 0xffffffff. Then, the next 64 bits are the actual entry
      // length.
      IsDWARF64 = true;
      Length = Data.getU64(&Offset);
    }

    // At this point, Offset points to the next field after Length.
    // Length is the structure size excluding itself. Compute an offset one
    // past the end of the structure (needed to know how many instructions to
    // read).
    // TODO: For honest DWARF64 support, DataExtractor will have to treat
    //       offset_ptr as uint64_t*
    uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);

    // The Id field's size depends on the DWARF format
    Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
    bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);

    if (IsCIE) {
      uint8_t Version = Data.getU8(&Offset);
      const char *Augmentation = Data.getCStr(&Offset);
      uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : Data.getU8(&Offset);
      Data.setAddressSize(AddressSize);
      uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
      uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
      int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
      uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);

      auto Cie = make_unique<CIE>(StartOffset, Length, Version,
                                  StringRef(Augmentation), AddressSize,
                                  SegmentDescriptorSize, CodeAlignmentFactor,
                                  DataAlignmentFactor, ReturnAddressRegister);
      CIEs[StartOffset] = Cie.get();
      Entries.emplace_back(std::move(Cie));
    } else {
      // FDE
      uint64_t CIEPointer = Id;
      uint64_t InitialLocation = Data.getAddress(&Offset);
      uint64_t AddressRange = Data.getAddress(&Offset);

      Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
                                   InitialLocation, AddressRange,
                                   CIEs[CIEPointer]));
    }

    Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);

    if (Offset != EndStructureOffset) {
      std::string Str;
      raw_string_ostream OS(Str);
      OS << format("Parsing entry instructions at %lx failed", StartOffset);
      report_fatal_error(Str);
    }
  }
}
예제 #3
0
bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
                                  const DWARFUnit *cu) {
  bool indirect = false;
  bool is_block = false;
  Value.data = nullptr;
  // Read the value for the form into value and follow and DW_FORM_indirect
  // instances we run into
  do {
    indirect = false;
    switch (Form) {
    case DW_FORM_addr:
    case DW_FORM_ref_addr: {
      uint16_t AddrSize =
          (Form == DW_FORM_addr)
              ? cu->getAddressByteSize()
              : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
      if (AI != cu->getRelocMap()->end()) {
        const std::pair<uint8_t, int64_t> &R = AI->second;
        Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
      } else
        Value.uval = data.getUnsigned(offset_ptr, AddrSize);
      break;
    }
    case DW_FORM_exprloc:
    case DW_FORM_block:
      Value.uval = data.getULEB128(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block1:
      Value.uval = data.getU8(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block2:
      Value.uval = data.getU16(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block4:
      Value.uval = data.getU32(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_data1:
    case DW_FORM_ref1:
    case DW_FORM_flag:
      Value.uval = data.getU8(offset_ptr);
      break;
    case DW_FORM_data2:
    case DW_FORM_ref2:
      Value.uval = data.getU16(offset_ptr);
      break;
    case DW_FORM_data4:
    case DW_FORM_ref4: {
      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
      Value.uval = data.getU32(offset_ptr);
      if (AI != cu->getRelocMap()->end())
        Value.uval += AI->second.second;
      break;
    }
    case DW_FORM_data8:
    case DW_FORM_ref8:
      Value.uval = data.getU64(offset_ptr);
      break;
    case DW_FORM_sdata:
      Value.sval = data.getSLEB128(offset_ptr);
      break;
    case DW_FORM_strp: {
      RelocAddrMap::const_iterator AI
        = cu->getRelocMap()->find(*offset_ptr);
      if (AI != cu->getRelocMap()->end()) {
        const std::pair<uint8_t, int64_t> &R = AI->second;
        Value.uval = data.getU32(offset_ptr) + R.second;
      } else
        Value.uval = data.getU32(offset_ptr);
      break;
    }
    case DW_FORM_udata:
    case DW_FORM_ref_udata:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    case DW_FORM_string:
      Value.cstr = data.getCStr(offset_ptr);
      break;
    case DW_FORM_indirect:
      Form = data.getULEB128(offset_ptr);
      indirect = true;
      break;
    case DW_FORM_sec_offset: {
      // FIXME: This is 64-bit for DWARF64.
      RelocAddrMap::const_iterator AI
        = cu->getRelocMap()->find(*offset_ptr);
      if (AI != cu->getRelocMap()->end()) {
        const std::pair<uint8_t, int64_t> &R = AI->second;
        Value.uval = data.getU32(offset_ptr) + R.second;
      } else
        Value.uval = data.getU32(offset_ptr);
      break;
    }
    case DW_FORM_flag_present:
      Value.uval = 1;
      break;
    case DW_FORM_ref_sig8:
      Value.uval = data.getU64(offset_ptr);
      break;
    case DW_FORM_GNU_addr_index:
    case DW_FORM_GNU_str_index:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    default:
      return false;
    }
  } while (indirect);

  if (is_block) {
    StringRef str = data.getData().substr(*offset_ptr, Value.uval);
    Value.data = nullptr;
    if (!str.empty()) {
      Value.data = reinterpret_cast<const uint8_t *>(str.data());
      *offset_ptr += Value.uval;
    }
  }

  return true;
}
예제 #4
0
void DWARFDebugFrame::parse(DataExtractor Data) {
  uint32_t Offset = 0;

  while (Data.isValidOffset(Offset)) {
    uint32_t StartOffset = Offset;

    bool IsDWARF64 = false;
    uint64_t Length = Data.getU32(&Offset);
    uint64_t Id;

    if (Length == UINT32_MAX) {
      // DWARF-64 is distinguished by the first 32 bits of the initial length
      // field being 0xffffffff. Then, the next 64 bits are the actual entry
      // length.
      IsDWARF64 = true;
      Length = Data.getU64(&Offset);
    }

    // At this point, Offset points to the next field after Length.
    // Length is the structure size excluding itself. Compute an offset one
    // past the end of the structure (needed to know how many instructions to
    // read).
    // TODO: For honest DWARF64 support, DataExtractor will have to treat
    //       offset_ptr as uint64_t*
    uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);

    // The Id field's size depends on the DWARF format
    Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
    bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);

    if (IsCIE) {
      // Note: this is specifically DWARFv3 CIE header structure. It was
      // changed in DWARFv4. We currently don't support reading DWARFv4
      // here because LLVM itself does not emit it (and LLDB doesn't
      // support it either).
      uint8_t Version = Data.getU8(&Offset);
      const char *Augmentation = Data.getCStr(&Offset);
      uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
      int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
      uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);

      Entries.emplace_back(new CIE(StartOffset, Length, Version,
                                   StringRef(Augmentation), CodeAlignmentFactor,
                                   DataAlignmentFactor, ReturnAddressRegister));
    } else {
      // FDE
      uint64_t CIEPointer = Id;
      uint64_t InitialLocation = Data.getAddress(&Offset);
      uint64_t AddressRange = Data.getAddress(&Offset);

      Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
                                   InitialLocation, AddressRange));
    }

    Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);

    if (Offset != EndStructureOffset) {
      string_ostream Str;
      Str << format("Parsing entry instructions at %lx failed", StartOffset);
      report_fatal_error(Str.str());
    }
  }
}
bool
DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
                             const DWARFCompileUnit *cu) {
  bool indirect = false;
  bool is_block = false;
  Value.data = NULL;
  // Read the value for the form into value and follow and DW_FORM_indirect
  // instances we run into
  do {
    indirect = false;
    switch (Form) {
    case DW_FORM_addr:
    case DW_FORM_ref_addr:
      Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize());
      break;
    case DW_FORM_block:
      Value.uval = data.getULEB128(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block1:
      Value.uval = data.getU8(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block2:
      Value.uval = data.getU16(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block4:
      Value.uval = data.getU32(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_data1:
    case DW_FORM_ref1:
    case DW_FORM_flag:
      Value.uval = data.getU8(offset_ptr);
      break;
    case DW_FORM_data2:
    case DW_FORM_ref2:
      Value.uval = data.getU16(offset_ptr);
      break;
    case DW_FORM_data4:
    case DW_FORM_ref4:
      Value.uval = data.getU32(offset_ptr);
      break;
    case DW_FORM_data8:
    case DW_FORM_ref8:
      Value.uval = data.getU64(offset_ptr);
      break;
    case DW_FORM_sdata:
      Value.sval = data.getSLEB128(offset_ptr);
      break;
    case DW_FORM_strp:
      Value.uval = data.getU32(offset_ptr);
      break;
    case DW_FORM_udata:
    case DW_FORM_ref_udata:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    case DW_FORM_string:
      Value.cstr = data.getCStr(offset_ptr);
      // Set the string value to also be the data for inlined cstr form
      // values only so we can tell the differnence between DW_FORM_string
      // and DW_FORM_strp form values
      Value.data = (uint8_t*)Value.cstr;
      break;
    case DW_FORM_indirect:
      Form = data.getULEB128(offset_ptr);
      indirect = true;
      break;
    default:
      return false;
    }
  } while (indirect);

  if (is_block) {
    StringRef str = data.getData().substr(*offset_ptr, Value.uval);
    Value.data = NULL;
    if (!str.empty()) {
      Value.data = reinterpret_cast<const uint8_t *>(str.data());
      *offset_ptr += Value.uval;
    }
  }

  return true;
}
예제 #6
0
void DWARFDebugFrame::parse(DataExtractor Data) {
  uint32_t Offset = 0;
  DenseMap<uint32_t, CIE *> CIEs;

  while (Data.isValidOffset(Offset)) {
    uint32_t StartOffset = Offset;

    auto ReportError = [StartOffset](const char *ErrorMsg) {
      std::string Str;
      raw_string_ostream OS(Str);
      OS << format(ErrorMsg, StartOffset);
      OS.flush();
      report_fatal_error(Str);
    };

    bool IsDWARF64 = false;
    uint64_t Length = Data.getU32(&Offset);
    uint64_t Id;

    if (Length == UINT32_MAX) {
      // DWARF-64 is distinguished by the first 32 bits of the initial length
      // field being 0xffffffff. Then, the next 64 bits are the actual entry
      // length.
      IsDWARF64 = true;
      Length = Data.getU64(&Offset);
    }

    // At this point, Offset points to the next field after Length.
    // Length is the structure size excluding itself. Compute an offset one
    // past the end of the structure (needed to know how many instructions to
    // read).
    // TODO: For honest DWARF64 support, DataExtractor will have to treat
    //       offset_ptr as uint64_t*
    uint32_t StartStructureOffset = Offset;
    uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);

    // The Id field's size depends on the DWARF format
    Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
    bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||
                  Id == DW_CIE_ID ||
                  (IsEH && !Id));

    if (IsCIE) {
      uint8_t Version = Data.getU8(&Offset);
      const char *Augmentation = Data.getCStr(&Offset);
      StringRef AugmentationString(Augmentation ? Augmentation : "");
      uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
                                          Data.getU8(&Offset);
      Data.setAddressSize(AddressSize);
      uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
      uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
      int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
      uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);

      // Parse the augmentation data for EH CIEs
      StringRef AugmentationData("");
      uint32_t FDEPointerEncoding = DW_EH_PE_omit;
      uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
      if (IsEH) {
        Optional<uint32_t> PersonalityEncoding;
        Optional<uint64_t> Personality;

        Optional<uint64_t> AugmentationLength;
        uint32_t StartAugmentationOffset;
        uint32_t EndAugmentationOffset;

        // Walk the augmentation string to get all the augmentation data.
        for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
          switch (AugmentationString[i]) {
            default:
              ReportError("Unknown augmentation character in entry at %lx");
            case 'L':
              LSDAPointerEncoding = Data.getU8(&Offset);
              break;
            case 'P': {
              if (Personality)
                ReportError("Duplicate personality in entry at %lx");
              PersonalityEncoding = Data.getU8(&Offset);
              Personality = readPointer(Data, Offset, *PersonalityEncoding);
              break;
            }
            case 'R':
              FDEPointerEncoding = Data.getU8(&Offset);
              break;
            case 'z':
              if (i)
                ReportError("'z' must be the first character at %lx");
              // Parse the augmentation length first.  We only parse it if
              // the string contains a 'z'.
              AugmentationLength = Data.getULEB128(&Offset);
              StartAugmentationOffset = Offset;
              EndAugmentationOffset = Offset +
                static_cast<uint32_t>(*AugmentationLength);
          }
        }

        if (AugmentationLength.hasValue()) {
          if (Offset != EndAugmentationOffset)
            ReportError("Parsing augmentation data at %lx failed");

          AugmentationData = Data.getData().slice(StartAugmentationOffset,
                                                  EndAugmentationOffset);
        }
      }

      auto Cie = make_unique<CIE>(StartOffset, Length, Version,
                                  AugmentationString, AddressSize,
                                  SegmentDescriptorSize, CodeAlignmentFactor,
                                  DataAlignmentFactor, ReturnAddressRegister,
                                  AugmentationData, FDEPointerEncoding,
                                  LSDAPointerEncoding);
      CIEs[StartOffset] = Cie.get();
      Entries.emplace_back(std::move(Cie));
    } else {
      // FDE
      uint64_t CIEPointer = Id;
      uint64_t InitialLocation = 0;
      uint64_t AddressRange = 0;
      CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];

      if (IsEH) {
        // The address size is encoded in the CIE we reference.
        if (!Cie)
          ReportError("Parsing FDE data at %lx failed due to missing CIE");

        InitialLocation = readPointer(Data, Offset,
                                      Cie->getFDEPointerEncoding());
        AddressRange = readPointer(Data, Offset,
                                   Cie->getFDEPointerEncoding());

        StringRef AugmentationString = Cie->getAugmentationString();
        if (!AugmentationString.empty()) {
          // Parse the augmentation length and data for this FDE.
          uint64_t AugmentationLength = Data.getULEB128(&Offset);

          uint32_t EndAugmentationOffset =
            Offset + static_cast<uint32_t>(AugmentationLength);

          // Decode the LSDA if the CIE augmentation string said we should.
          if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit)
            readPointer(Data, Offset, Cie->getLSDAPointerEncoding());

          if (Offset != EndAugmentationOffset)
            ReportError("Parsing augmentation data at %lx failed");
        }
      } else {
        InitialLocation = Data.getAddress(&Offset);
        AddressRange = Data.getAddress(&Offset);
      }

      Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
                                   InitialLocation, AddressRange,
                                   Cie));
    }

    Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);

    if (Offset != EndStructureOffset)
      ReportError("Parsing entry instructions at %lx failed");
  }
}
예제 #7
0
bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
                                     uint32_t *offset_ptr) {
  const uint64_t prologue_offset = *offset_ptr;

  clear();
  TotalLength = debug_line_data.getU32(offset_ptr);
  if (TotalLength == UINT32_MAX) {
    IsDWARF64 = true;
    TotalLength = debug_line_data.getU64(offset_ptr);
  } else if (TotalLength > 0xffffff00) {
    return false;
  }
  Version = debug_line_data.getU16(offset_ptr);
  if (Version < 2)
    return false;

  PrologueLength =
      debug_line_data.getUnsigned(offset_ptr, sizeofPrologueLength());
  const uint64_t end_prologue_offset = PrologueLength + *offset_ptr;
  MinInstLength = debug_line_data.getU8(offset_ptr);
  if (Version >= 4)
    MaxOpsPerInst = debug_line_data.getU8(offset_ptr);
  DefaultIsStmt = debug_line_data.getU8(offset_ptr);
  LineBase = debug_line_data.getU8(offset_ptr);
  LineRange = debug_line_data.getU8(offset_ptr);
  OpcodeBase = debug_line_data.getU8(offset_ptr);

  StandardOpcodeLengths.reserve(OpcodeBase - 1);
  for (uint32_t i = 1; i < OpcodeBase; ++i) {
    uint8_t op_len = debug_line_data.getU8(offset_ptr);
    StandardOpcodeLengths.push_back(op_len);
  }

  while (*offset_ptr < end_prologue_offset) {
    const char *s = debug_line_data.getCStr(offset_ptr);
    if (s && s[0])
      IncludeDirectories.push_back(s);
    else
      break;
  }

  while (*offset_ptr < end_prologue_offset) {
    const char *name = debug_line_data.getCStr(offset_ptr);
    if (name && name[0]) {
      FileNameEntry fileEntry;
      fileEntry.Name = name;
      fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
      fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
      fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
      FileNames.push_back(fileEntry);
    } else {
      break;
    }
  }

  if (*offset_ptr != end_prologue_offset) {
    fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64
                    " should have ended at 0x%8.8" PRIx64
                    " but it ended at 0x%8.8" PRIx64 "\n",
            prologue_offset, end_prologue_offset, (uint64_t)*offset_ptr);
    return false;
  }
  return true;
}
예제 #8
0
bool
DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
                             const DWARFCompileUnit *cu) {
  bool indirect = false;
  bool is_block = false;
  Value.data = NULL;
  // Read the value for the form into value and follow and DW_FORM_indirect
  // instances we run into
  do {
    indirect = false;
    switch (Form) {
    case DW_FORM_addr:
    case DW_FORM_ref_addr: {
      RelocAddrMap::const_iterator AI
        = cu->getRelocMap()->find(*offset_ptr);
      if (AI != cu->getRelocMap()->end()) {
        const std::pair<uint8_t, int64_t> &R = AI->second;
        Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize()) +
                     R.second;
      } else
        Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize());
      break;
    }
    case DW_FORM_exprloc:
    case DW_FORM_block:
      Value.uval = data.getULEB128(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block1:
      Value.uval = data.getU8(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block2:
      Value.uval = data.getU16(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_block4:
      Value.uval = data.getU32(offset_ptr);
      is_block = true;
      break;
    case DW_FORM_data1:
    case DW_FORM_ref1:
    case DW_FORM_flag:
      Value.uval = data.getU8(offset_ptr);
      break;
    case DW_FORM_data2:
    case DW_FORM_ref2:
      Value.uval = data.getU16(offset_ptr);
      break;
    case DW_FORM_data4:
    case DW_FORM_ref4:
      Value.uval = data.getU32(offset_ptr);
      break;
    case DW_FORM_data8:
    case DW_FORM_ref8:
      Value.uval = data.getU64(offset_ptr);
      break;
    case DW_FORM_sdata:
      Value.sval = data.getSLEB128(offset_ptr);
      break;
    case DW_FORM_strp: {
      RelocAddrMap::const_iterator AI
        = cu->getRelocMap()->find(*offset_ptr);
      if (AI != cu->getRelocMap()->end()) {
        const std::pair<uint8_t, int64_t> &R = AI->second;
        Value.uval = data.getU32(offset_ptr) + R.second;
      } else
        Value.uval = data.getU32(offset_ptr);
      break;
    }
    case DW_FORM_udata:
    case DW_FORM_ref_udata:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    case DW_FORM_string:
      Value.cstr = data.getCStr(offset_ptr);
      // Set the string value to also be the data for inlined cstr form
      // values only so we can tell the differnence between DW_FORM_string
      // and DW_FORM_strp form values
      Value.data = (const uint8_t*)Value.cstr;
      break;
    case DW_FORM_indirect:
      Form = data.getULEB128(offset_ptr);
      indirect = true;
      break;
    case DW_FORM_sec_offset:
      // FIXME: This is 64-bit for DWARF64.
      Value.uval = data.getU32(offset_ptr);
      break;
    case DW_FORM_flag_present:
      Value.uval = 1;
      break;
    case DW_FORM_ref_sig8:
      Value.uval = data.getU64(offset_ptr);
      break;
    case DW_FORM_GNU_addr_index:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    case DW_FORM_GNU_str_index:
      Value.uval = data.getULEB128(offset_ptr);
      break;
    default:
      return false;
    }
  } while (indirect);

  if (is_block) {
    StringRef str = data.getData().substr(*offset_ptr, Value.uval);
    Value.data = NULL;
    if (!str.empty()) {
      Value.data = reinterpret_cast<const uint8_t *>(str.data());
      *offset_ptr += Value.uval;
    }
  }

  return true;
}