summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-05-19 20:29:28 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-05-19 20:29:28 +0000
commitbf19a578e602d65d6d6ccc58586c41958a29b184 (patch)
tree8314f6d236a9004d2a7e12aaaf0165bb36205829 /llvm/lib/DebugInfo
parentf999547d11249ff13853683d5ca63383593ef4fd (diff)
downloadbcm5719-llvm-bf19a578e602d65d6d6ccc58586c41958a29b184.tar.gz
bcm5719-llvm-bf19a578e602d65d6d6ccc58586c41958a29b184.zip
[DWARF parser] Add basic support for DWZ DWARF multifile extensions.
This change implements basic support for DWARF alternate sections proposal: http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open LLVM tools now understand new forms: DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt, which are used as references to .debug_info and .debug_str sections respectively, stored in a separate file, and possibly shared between different executables / shared objects. llvm-dwarfdump and llvm-symbolizer don't yet know how to access this alternate debug file (usually pointed by .gnu_debugaltlink section), but they can at lease properly parse and dump regular files, which refer to it. This change should fix crashes of llvm-dwarfdump and llvm-symbolizer on files produced by running "dwz" tool. Such files are already installed on some modern Linux distributions. llvm-svn: 237721
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp17
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp77
2 files changed, 51 insertions, 43 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index e963b7ca6e6..5abbde4ac0f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -161,14 +161,15 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
// We have dumped the attribute raw value. For some attributes
// having both the raw value and the pretty-printed value is
// interesting. These attributes are handled below.
- if ((attr == DW_AT_specification || attr == DW_AT_abstract_origin) &&
- // The signature references aren't handled.
- formValue.getForm() != DW_FORM_ref_sig8) {
- uint32_t Ref = formValue.getAsReference(u).getValue();
- DWARFDebugInfoEntryMinimal DIE;
- if (const DWARFUnit *RefU = findUnitAndExtractFast(DIE, u, &Ref))
- if (const char *Ref = DIE.getName(RefU, DINameKind::LinkageName))
- OS << " \"" << Ref << '\"';
+ if (attr == DW_AT_specification || attr == DW_AT_abstract_origin) {
+ Optional<uint64_t> Ref = formValue.getAsReference(u);
+ if (Ref.hasValue()) {
+ uint32_t RefOffset = Ref.getValue();
+ DWARFDebugInfoEntryMinimal DIE;
+ if (const DWARFUnit *RefU = findUnitAndExtractFast(DIE, u, &RefOffset))
+ if (const char *Name = DIE.getName(RefU, DINameKind::LinkageName))
+ OS << " \"" << Name << '\"';
+ }
} else if (attr == DW_AT_APPLE_property_attribute) {
if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
dumpApplePropertyAttribute(OS, *OptVal);
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;
}
}
OpenPOWER on IntegriCloud