diff options
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp | 77 |
1 files changed, 42 insertions, 35 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index 6946f833424..75ca7622139 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -113,14 +113,17 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { if (Form < ArrayRef<FormClass>(DWARF4FormClasses).size() && DWARF4FormClasses[Form] == FC) return true; - // Check DW_FORM_ref_sig8 from DWARF4. - if (Form == DW_FORM_ref_sig8) + // Check more forms from DWARF4 and DWARF5 proposals. + switch (Form) { + case DW_FORM_ref_sig8: + case DW_FORM_GNU_ref_alt: return (FC == FC_Reference); - // Check for some DWARF5 forms. - if (Form == DW_FORM_GNU_addr_index) + case DW_FORM_GNU_addr_index: return (FC == FC_Address); - if (Form == DW_FORM_GNU_str_index) + case DW_FORM_GNU_str_index: + case DW_FORM_GNU_strp_alt: return (FC == FC_String); + } // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset. // Don't check for DWARF version here, as some producers may still do this // by mistake. @@ -199,15 +202,6 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, case DW_FORM_sdata: Value.sval = data.getSLEB128(offset_ptr); break; - case DW_FORM_strp: { - Value.uval = data.getU32(offset_ptr); - if (!cu) - break; - RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4); - if (AI != cu->getRelocMap()->end()) - Value.uval += AI->second.second; - break; - } case DW_FORM_udata: case DW_FORM_ref_udata: Value.uval = data.getULEB128(offset_ptr); @@ -219,14 +213,18 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, Form = data.getULEB128(offset_ptr); indirect = true; break; - case DW_FORM_sec_offset: { + case DW_FORM_sec_offset: + case DW_FORM_strp: + case DW_FORM_GNU_ref_alt: + case DW_FORM_GNU_strp_alt: { // FIXME: This is 64-bit for DWARF64. Value.uval = data.getU32(offset_ptr); if (!cu) break; - RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4); + RelocAddrMap::const_iterator AI = + cu->getRelocMap()->find(*offset_ptr - 4); if (AI != cu->getRelocMap()->end()) - Value.uval += AI->second.second; + Value.uval += AI->second.second; break; } case DW_FORM_flag_present: @@ -323,7 +321,6 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, return true; // 4 byte values - case DW_FORM_strp: case DW_FORM_data4: case DW_FORM_ref4: *offset_ptr += 4; @@ -353,6 +350,9 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, // FIXME: 4 for DWARF32, 8 for DWARF64. case DW_FORM_sec_offset: + case DW_FORM_strp: + case DW_FORM_GNU_ref_alt: + case DW_FORM_GNU_strp_alt: *offset_ptr += 4; return true; @@ -424,24 +424,17 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { case DW_FORM_udata: OS << Value.uval; break; case DW_FORM_strp: { OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); - Optional<const char *> DbgStr = getAsCString(cu); - if (DbgStr.hasValue()) { - raw_ostream &COS = WithColor(OS, syntax::String); - COS << '"'; - COS.write_escaped(DbgStr.getValue()); - COS << '"'; - } + dumpString(OS, cu); break; } case DW_FORM_GNU_str_index: { OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue); - Optional<const char *> DbgStr = getAsCString(cu); - if (DbgStr.hasValue()) { - raw_ostream &COS = WithColor(OS, syntax::String); - COS << '"'; - COS.write_escaped(DbgStr.getValue()); - COS << '"'; - } + dumpString(OS, cu); + break; + } + case DW_FORM_GNU_strp_alt: { + OS << format("alt indirect string, offset: 0x%" PRIx64 "", uvalue); + dumpString(OS, cu); break; } case DW_FORM_ref_addr: @@ -467,6 +460,9 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { cu_relative_offset = true; OS << format("cu + 0x%" PRIx64, uvalue); break; + case DW_FORM_GNU_ref_alt: + OS << format("<alt 0x%" PRIx64 ">", uvalue); + break; // All DW_FORM_indirect attributes should be resolved prior to calling // this function @@ -492,12 +488,23 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { } } +void DWARFFormValue::dumpString(raw_ostream &OS, const DWARFUnit *U) const { + Optional<const char *> DbgStr = getAsCString(U); + if (DbgStr.hasValue()) { + raw_ostream &COS = WithColor(OS, syntax::String); + COS << '"'; + COS.write_escaped(DbgStr.getValue()); + COS << '"'; + } +} + Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const { if (!isFormClass(FC_String)) return None; if (Form == DW_FORM_string) return Value.cstr; - if (!U) + // FIXME: Add support for DW_FORM_GNU_strp_alt + if (Form == DW_FORM_GNU_strp_alt || U == nullptr) return None; uint32_t Offset = Value.uval; if (Form == DW_FORM_GNU_str_index) { @@ -539,9 +546,9 @@ Optional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const { return Value.uval + U->getOffset(); case DW_FORM_ref_addr: return Value.uval; - // FIXME: Add proper support for DW_FORM_ref_sig8 + // FIXME: Add proper support for DW_FORM_ref_sig8 and DW_FORM_GNU_ref_alt. default: - return Value.uval; + return None; } } |