diff options
Diffstat (limited to 'lib/DebugInfo/DWARFFormValue.cpp')
-rw-r--r-- | lib/DebugInfo/DWARFFormValue.cpp | 95 |
1 files changed, 68 insertions, 27 deletions
diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp index fea9fd7..9f807aa 100644 --- a/lib/DebugInfo/DWARFFormValue.cpp +++ b/lib/DebugInfo/DWARFFormValue.cpp @@ -72,7 +72,7 @@ static const uint8_t form_sizes_addr8[] = { 8, // 0x14 DW_FORM_ref8 0, // 0x15 DW_FORM_ref_udata 0, // 0x16 DW_FORM_indirect - 8, // 0x17 DW_FORM_sec_offset + 4, // 0x17 DW_FORM_sec_offset 0, // 0x18 DW_FORM_exprloc 0, // 0x19 DW_FORM_flag_present 8, // 0x20 DW_FORM_ref_sig8 @@ -101,15 +101,15 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, case DW_FORM_addr: case DW_FORM_ref_addr: { RelocAddrMap::const_iterator AI - = cu->getContext().relocMap().find(*offset_ptr); - if (AI != cu->getContext().relocMap().end()) { + = cu->getRelocMap()->find(*offset_ptr); + if (AI != cu->getRelocMap()->end()) { const std::pair<uint8_t, int64_t> &R = AI->second; - Value.uval = R.second; - *offset_ptr += R.first; + 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); @@ -149,11 +149,10 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, break; case DW_FORM_strp: { RelocAddrMap::const_iterator AI - = cu->getContext().relocMap().find(*offset_ptr); - if (AI != cu->getContext().relocMap().end()) { + = cu->getRelocMap()->find(*offset_ptr); + if (AI != cu->getRelocMap()->end()) { const std::pair<uint8_t, int64_t> &R = AI->second; - Value.uval = R.second; - *offset_ptr += R.first; + Value.uval = data.getU32(offset_ptr) + R.second; } else Value.uval = data.getU32(offset_ptr); break; @@ -174,10 +173,8 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, indirect = true; break; case DW_FORM_sec_offset: - if (cu->getAddressByteSize() == 4) - Value.uval = data.getU32(offset_ptr); - else - Value.uval = data.getU64(offset_ptr); + // FIXME: This is 64-bit for DWARF64. + Value.uval = data.getU32(offset_ptr); break; case DW_FORM_flag_present: Value.uval = 1; @@ -185,6 +182,12 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, 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; } @@ -253,7 +256,7 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, // 0 byte values - implied from the form. case DW_FORM_flag_present: return true; - + // 1 byte values case DW_FORM_data1: case DW_FORM_flag: @@ -286,6 +289,8 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: + case DW_FORM_GNU_str_index: + case DW_FORM_GNU_addr_index: debug_info_data.getULEB128(offset_ptr); return true; @@ -294,14 +299,11 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, form = debug_info_data.getULEB128(offset_ptr); break; - // 4 for DWARF32, 8 for DWARF64. + // FIXME: 4 for DWARF32, 8 for DWARF64. case DW_FORM_sec_offset: - if (cu->getAddressByteSize() == 4) - *offset_ptr += 4; - else - *offset_ptr += 8; + *offset_ptr += 4; return true; - + default: return false; } @@ -311,12 +313,23 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, void DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const { - DataExtractor debug_str_data(cu->getContext().getStringSection(), true, 0); + DataExtractor debug_str_data(cu->getStringSection(), true, 0); + DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0); uint64_t uvalue = getUnsigned(); bool cu_relative_offset = false; switch (Form) { case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break; + case DW_FORM_GNU_addr_index: { + StringRef AddrOffsetSec = cu->getAddrOffsetSection(); + OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue); + if (AddrOffsetSec.size() != 0) { + DataExtractor DA(AddrOffsetSec, true, cu->getAddressByteSize()); + OS << format("0x%016" PRIx64, getIndirectAddress(&DA, cu)); + } else + OS << "<no .debug_addr section>"; + break; + } case DW_FORM_flag_present: OS << "true"; break; case DW_FORM_flag: case DW_FORM_data1: OS << format("0x%02x", (uint8_t)uvalue); break; @@ -370,6 +383,17 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const { } break; } + case DW_FORM_GNU_str_index: { + OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue); + const char *dbg_str = getIndirectCString(&debug_str_data, + &debug_str_offset_data); + if (dbg_str) { + OS << '"'; + OS.write_escaped(dbg_str); + OS << '"'; + } + break; + } case DW_FORM_ref_addr: OS << format("0x%016" PRIx64, uvalue); break; @@ -400,13 +424,11 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const { OS << "DW_FORM_indirect"; break; + // Should be formatted to 64-bit for DWARF64. case DW_FORM_sec_offset: - if (cu->getAddressByteSize() == 4) - OS << format("0x%08x", (uint32_t)uvalue); - else - OS << format("0x%016" PRIx64, uvalue); + OS << format("0x%08x", (uint32_t)uvalue); break; - + default: OS << format("DW_FORM(0x%4.4x)", Form); break; @@ -427,6 +449,25 @@ DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const { return NULL; } +const char* +DWARFFormValue::getIndirectCString(const DataExtractor *DS, + const DataExtractor *DSO) const { + if (!DS || !DSO) return NULL; + + uint32_t offset = Value.uval * 4; + uint32_t soffset = DSO->getU32(&offset); + return DS->getCStr(&soffset); +} + +uint64_t +DWARFFormValue::getIndirectAddress(const DataExtractor *DA, + const DWARFCompileUnit *cu) const { + if (!DA) return 0; + + uint32_t offset = Value.uval * cu->getAddressByteSize(); + return DA->getAddress(&offset); +} + uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const { uint64_t die_offset = Value.uval; switch (Form) { |