Optional<DWARFDebugLoc::LocationList> DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) { LocationList LL; LL.Offset = *Offset; // 2.6.2 Location Lists // A location list entry consists of: while (true) { Entry E; if (!Data.isValidOffsetForDataOfSize(*Offset, 2 * Data.getAddressSize())) { llvm::errs() << "Location list overflows the debug_loc section.\n"; return None; } // 1. A beginning address offset. ... E.Begin = Data.getRelocatedAddress(Offset); // 2. An ending address offset. ... E.End = Data.getRelocatedAddress(Offset); // 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) return LL; if (!Data.isValidOffsetForDataOfSize(*Offset, 2)) { llvm::errs() << "Location list overflows the debug_loc section.\n"; return None; } unsigned Bytes = Data.getU16(Offset); if (!Data.isValidOffsetForDataOfSize(*Offset, Bytes)) { llvm::errs() << "Location list overflows the debug_loc section.\n"; return None; } // 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)); LL.Entries.push_back(std::move(E)); } }
bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, DWARFFormParams FP, const DWARFUnit *CU) { U = CU; bool Indirect = false; bool IsBlock = 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 Size = (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize(); Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex); break; } case DW_FORM_exprloc: case DW_FORM_block: Value.uval = Data.getULEB128(OffsetPtr); IsBlock = true; break; case DW_FORM_block1: Value.uval = Data.getU8(OffsetPtr); IsBlock = true; break; case DW_FORM_block2: Value.uval = Data.getU16(OffsetPtr); IsBlock = true; break; case DW_FORM_block4: Value.uval = Data.getU32(OffsetPtr); IsBlock = true; break; case DW_FORM_data1: case DW_FORM_ref1: case DW_FORM_flag: case DW_FORM_strx1: case DW_FORM_addrx1: Value.uval = Data.getU8(OffsetPtr); break; case DW_FORM_data2: case DW_FORM_ref2: case DW_FORM_strx2: case DW_FORM_addrx2: Value.uval = Data.getU16(OffsetPtr); break; case DW_FORM_strx3: Value.uval = Data.getU24(OffsetPtr); break; case DW_FORM_data4: case DW_FORM_ref4: case DW_FORM_ref_sup4: case DW_FORM_strx4: case DW_FORM_addrx4: Value.uval = Data.getRelocatedValue(4, OffsetPtr); break; case DW_FORM_data8: case DW_FORM_ref8: case DW_FORM_ref_sup8: Value.uval = Data.getU64(OffsetPtr); break; case DW_FORM_data16: // Treat this like a 16-byte block. Value.uval = 16; IsBlock = true; break; case DW_FORM_sdata: Value.sval = Data.getSLEB128(OffsetPtr); break; case DW_FORM_udata: case DW_FORM_ref_udata: Value.uval = Data.getULEB128(OffsetPtr); break; case DW_FORM_string: Value.cstr = Data.getCStr(OffsetPtr); break; case DW_FORM_indirect: Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr)); Indirect = true; break; case DW_FORM_strp: case DW_FORM_sec_offset: case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: case DW_FORM_line_strp: case DW_FORM_strp_sup: { Value.uval = Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr); break; } case DW_FORM_flag_present: Value.uval = 1; break; case DW_FORM_ref_sig8: Value.uval = Data.getU64(OffsetPtr); break; case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: case DW_FORM_strx: Value.uval = Data.getULEB128(OffsetPtr); break; default: // DWARFFormValue::skipValue() will have caught this and caused all // DWARF DIEs to fail to be parsed, so this code is not be reachable. llvm_unreachable("unsupported form"); } } while (Indirect); if (IsBlock) { StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval); Value.data = nullptr; if (!Str.empty()) { Value.data = reinterpret_cast<const uint8_t *>(Str.data()); *OffsetPtr += Value.uval; } } return true; }