[DWARF5]: Added support for dumping strx forms in llvm-dwarfdump
This patch adds support for dumping DW_MACRO_define_strx, DW_MACRO_undef_strx in llvm-dwarfdump. These forms are currently supported only in debug_macro section. Reviewed By: ikudrin, dblaikie Differential Revision: https://reviews.llvm.org/D78736
This commit is contained in:
parent
013f06703e
commit
93aee9ca86
@ -11,6 +11,7 @@
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/WithColor.h"
|
||||
@ -101,13 +102,25 @@ public:
|
||||
/// Print the macro list found within the debug_macinfo/debug_macro section.
|
||||
void dump(raw_ostream &OS) const;
|
||||
|
||||
/// Parse the debug_macinfo/debug_macro section accessible via the 'Data'
|
||||
/// parameter.
|
||||
Error parse(DataExtractor StringExtractor, DWARFDataExtractor Data,
|
||||
bool IsMacro);
|
||||
Error parseMacro(DWARFUnitVector::iterator_range Units,
|
||||
DataExtractor StringExtractor,
|
||||
DWARFDataExtractor MacroData) {
|
||||
return parseImpl(Units, StringExtractor, MacroData, /*IsMacro=*/true);
|
||||
}
|
||||
|
||||
Error parseMacinfo(DWARFDataExtractor MacroData) {
|
||||
return parseImpl(None, None, MacroData, /*IsMacro=*/false);
|
||||
}
|
||||
|
||||
/// Return whether the section has any entries.
|
||||
bool empty() const { return MacroLists.empty(); }
|
||||
|
||||
private:
|
||||
/// Parse the debug_macinfo/debug_macro section accessible via the 'MacroData'
|
||||
/// parameter.
|
||||
Error parseImpl(Optional<DWARFUnitVector::iterator_range> Units,
|
||||
Optional<DataExtractor> StringExtractor,
|
||||
DWARFDataExtractor Data, bool IsMacro);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@ -263,7 +263,10 @@ std::unique_ptr<DWARFDebugMacro>
|
||||
DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
|
||||
auto Macro = std::make_unique<DWARFDebugMacro>();
|
||||
auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
|
||||
if (Error Err = Macro->parse(getStringExtractor(), Data, IsMacro)) {
|
||||
// FIXME: Add support for debug_macro.dwo section.
|
||||
if (Error Err = IsMacro ? Macro->parseMacro(compile_units(),
|
||||
getStringExtractor(), Data)
|
||||
: Macro->parseMacinfo(Data)) {
|
||||
RecoverableErrorHandler(std::move(Err));
|
||||
Macro = nullptr;
|
||||
}
|
||||
|
||||
@ -62,6 +62,8 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
|
||||
case DW_MACRO_undef:
|
||||
case DW_MACRO_define_strp:
|
||||
case DW_MACRO_undef_strp:
|
||||
case DW_MACRO_define_strx:
|
||||
case DW_MACRO_undef_strx:
|
||||
OS << " - lineno: " << E.Line;
|
||||
OS << " macro: " << E.MacroStr;
|
||||
break;
|
||||
@ -84,10 +86,23 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
|
||||
}
|
||||
}
|
||||
|
||||
Error DWARFDebugMacro::parse(DataExtractor StringExtractor,
|
||||
DWARFDataExtractor Data, bool IsMacro) {
|
||||
Error DWARFDebugMacro::parseImpl(
|
||||
Optional<DWARFUnitVector::iterator_range> Units,
|
||||
Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data,
|
||||
bool IsMacro) {
|
||||
uint64_t Offset = 0;
|
||||
MacroList *M = nullptr;
|
||||
using MacroToUnitsMap = DenseMap<uint64_t, DWARFUnit *>;
|
||||
MacroToUnitsMap MacroToUnits;
|
||||
if (IsMacro && Data.isValidOffset(Offset)) {
|
||||
// Keep a mapping from Macro contribution to CUs, this will
|
||||
// be needed while retrieving macro from DW_MACRO_define_strx form.
|
||||
for (const auto &U : Units.getValue())
|
||||
if (auto CUDIE = U->getUnitDIE())
|
||||
// Skip units which does not contibutes to macro section.
|
||||
if (auto MacroOffset = toSectionOffset(CUDIE.find(DW_AT_macros)))
|
||||
MacroToUnits.try_emplace(*MacroOffset, U.get());
|
||||
}
|
||||
while (Data.isValidOffset(Offset)) {
|
||||
if (!M) {
|
||||
MacroLists.emplace_back();
|
||||
@ -132,13 +147,47 @@ Error DWARFDebugMacro::parse(DataExtractor StringExtractor,
|
||||
break;
|
||||
case DW_MACRO_define_strp:
|
||||
case DW_MACRO_undef_strp: {
|
||||
if (!IsMacro) {
|
||||
// DW_MACRO_define_strp is a new form introduced in DWARFv5, it is
|
||||
// not supported in debug_macinfo[.dwo] sections. Assume it as an
|
||||
// invalid entry, push it and halt parsing.
|
||||
E.Type = DW_MACINFO_invalid;
|
||||
return Error::success();
|
||||
}
|
||||
uint64_t StrOffset = 0;
|
||||
// 2. Source line
|
||||
E.Line = Data.getULEB128(&Offset);
|
||||
// 3. Macro string
|
||||
// FIXME: Add support for DWARF64
|
||||
StrOffset = Data.getRelocatedValue(/*OffsetSize=*/4, &Offset);
|
||||
E.MacroStr = StringExtractor.getCStr(&StrOffset);
|
||||
assert(StringExtractor && "String Extractor not found");
|
||||
E.MacroStr = StringExtractor->getCStr(&StrOffset);
|
||||
break;
|
||||
}
|
||||
case DW_MACRO_define_strx:
|
||||
case DW_MACRO_undef_strx: {
|
||||
if (!IsMacro) {
|
||||
// DW_MACRO_define_strx is a new form introduced in DWARFv5, it is
|
||||
// not supported in debug_macinfo[.dwo] sections. Assume it as an
|
||||
// invalid entry, push it and halt parsing.
|
||||
E.Type = DW_MACINFO_invalid;
|
||||
return Error::success();
|
||||
}
|
||||
E.Line = Data.getULEB128(&Offset);
|
||||
auto MacroContributionOffset = MacroToUnits.find(M->Offset);
|
||||
if (MacroContributionOffset == MacroToUnits.end())
|
||||
return createStringError(errc::invalid_argument,
|
||||
"Macro contribution of the unit not found");
|
||||
Optional<uint64_t> StrOffset =
|
||||
MacroContributionOffset->second->getStringOffsetSectionItem(
|
||||
Data.getULEB128(&Offset));
|
||||
if (!StrOffset)
|
||||
return createStringError(
|
||||
errc::invalid_argument,
|
||||
"String offsets contribution of the unit not found");
|
||||
E.MacroStr =
|
||||
MacroContributionOffset->second->getStringExtractor().getCStr(
|
||||
&*StrOffset);
|
||||
break;
|
||||
}
|
||||
case DW_MACRO_start_file:
|
||||
|
||||
14
llvm/test/DebugInfo/X86/debug-macinfo-strp.s
Normal file
14
llvm/test/DebugInfo/X86/debug-macinfo-strp.s
Normal file
@ -0,0 +1,14 @@
|
||||
## This test checks that llvm-dwarfdump produces
|
||||
## DW_MACINFO_invalid when parsing *_strp
|
||||
## form in a debug_macinfo section.
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
|
||||
# RUN: llvm-dwarfdump -debug-macro - | FileCheck %s
|
||||
|
||||
# CHECK: .debug_macinfo contents:
|
||||
# CHECK-NEXT: 0x00000000:
|
||||
# CHECK-NEXT: DW_MACINFO_invalid
|
||||
|
||||
.section .debug_macinfo,"",@progbits
|
||||
.Lcu_macinfo_begin0:
|
||||
.byte 5 # DW_MACRO_define_strp
|
||||
14
llvm/test/DebugInfo/X86/debug-macinfo-strx.s
Normal file
14
llvm/test/DebugInfo/X86/debug-macinfo-strx.s
Normal file
@ -0,0 +1,14 @@
|
||||
## This test checks that llvm-dwarfdump produces
|
||||
## DW_MACINFO_invalid when parsing *_strx
|
||||
## form in a debug_macinfo section.
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
|
||||
# RUN: llvm-dwarfdump -debug-macro - | FileCheck %s
|
||||
|
||||
# CHECK: .debug_macinfo contents:
|
||||
# CHECK-NEXT: 0x00000000:
|
||||
# CHECK-NEXT: DW_MACINFO_invalid
|
||||
|
||||
.section .debug_macinfo,"",@progbits
|
||||
.Lcu_macinfo_begin0:
|
||||
.byte 11 # DW_MACRO_define_strx
|
||||
32
llvm/test/DebugInfo/X86/debug-macro-empty-macro-offset.s
Normal file
32
llvm/test/DebugInfo/X86/debug-macro-empty-macro-offset.s
Normal file
@ -0,0 +1,32 @@
|
||||
## This test checks that llvm-dwarfdump produces error message
|
||||
## while parsing an *_strx form, if units contribution to
|
||||
## debug_macro[.dwo] section is missing.
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
|
||||
# RUN: not llvm-dwarfdump -debug-macro - /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: error: Macro contribution of the unit not found
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x12 DW_TAG_compile_unit
|
||||
.Ldebug_info_end0:
|
||||
|
||||
.section .debug_macro,"",@progbits
|
||||
.Lcu_macro_begin0:
|
||||
.short 5 # Macro information version
|
||||
.byte 0 # Flags: 32 bit
|
||||
.byte 11 # DW_MACRO_define_strx
|
||||
36
llvm/test/DebugInfo/X86/debug-macro-empty-str-offset.s
Normal file
36
llvm/test/DebugInfo/X86/debug-macro-empty-str-offset.s
Normal file
@ -0,0 +1,36 @@
|
||||
## This test checks that llvm-dwarfdump produces error message
|
||||
## while parsing an *_strx form, if units contribution to
|
||||
## debug_str_offsets[.dwo] section is missing.
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
|
||||
# RUN: not llvm-dwarfdump -debug-macro - /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: error: String offsets contribution of the unit not found
|
||||
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 121 # DW_AT_macros
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x12 DW_TAG_compile_unit
|
||||
.long .Lcu_macro_begin0 # DW_AT_macros
|
||||
.Ldebug_info_end0:
|
||||
|
||||
.section .debug_macro,"",@progbits
|
||||
.Lcu_macro_begin0:
|
||||
.short 5 # Macro information version
|
||||
.byte 0 # Flags: 32 bit
|
||||
.byte 11 # DW_MACRO_define_strx
|
||||
119
llvm/test/DebugInfo/X86/debug-macro-multi-cu-strx.s
Normal file
119
llvm/test/DebugInfo/X86/debug-macro-multi-cu-strx.s
Normal file
@ -0,0 +1,119 @@
|
||||
## This test checks that llvm-dwarfdump can dump debug_macro
|
||||
## section containing contributions from multiple CU's represented
|
||||
## using DW_MACRO_define_strx form.
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
|
||||
# RUN: llvm-dwarfdump -debug-macro - | FileCheck -strict-whitespace -match-full-lines %s
|
||||
|
||||
# CHECK:.debug_macro contents:
|
||||
# CHECK-NEXT:0x00000000:
|
||||
# CHECK-NEXT:macro header: version = 0x0005, flags = 0x02, debug_line_offset = 0x0000
|
||||
# CHECK-NEXT:DW_MACRO_start_file - lineno: 0 filenum: 0
|
||||
# CHECK-NEXT: DW_MACRO_define_strx - lineno: 1 macro: DWARF_VERSION 5
|
||||
# CHECK-NEXT: DW_MACRO_define_strx - lineno: 2 macro: COMPILE_UNIT 1
|
||||
# CHECK-NEXT: DW_MACRO_undef_strx - lineno: 3 macro: COMPILE_UNIT
|
||||
# CHECK-NEXT:DW_MACRO_end_file
|
||||
|
||||
# CHECK:0x00000015:
|
||||
# CHECK-NEXT:macro header: version = 0x0005, flags = 0x02, debug_line_offset = 0x0000
|
||||
# CHECK-NEXT:DW_MACRO_start_file - lineno: 1 filenum: 3
|
||||
# CHECK-NEXT: DW_MACRO_define_strx - lineno: 2 macro: COMPILE_UNIT 2
|
||||
# CHECK-NEXT: DW_MACRO_undef_strx - lineno: 3 macro: COMPILE_UNIT
|
||||
# CHECK-NEXT:DW_MACRO_end_file
|
||||
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 121 # DW_AT_macros
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x12 DW_TAG_compile_unit
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lcu_macro_begin0 # DW_AT_macros
|
||||
.Ldebug_info_end0:
|
||||
.Lcu_begin1:
|
||||
.long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
|
||||
.Ldebug_info_start1:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x12 DW_TAG_compile_unit
|
||||
.long .Lstr_offsets_base1 # DW_AT_str_offsets_base
|
||||
.long .Lcu_macro_begin1 # DW_AT_macros
|
||||
.Ldebug_info_end1:
|
||||
|
||||
.section .debug_macro,"",@progbits
|
||||
.Lcu_macro_begin0:
|
||||
.short 5 # Macro information version
|
||||
.byte 2 # Flags: 32 bit, debug_line_offset present
|
||||
.long 0 # debug_line_offset
|
||||
.byte 3 # DW_MACRO_start_file
|
||||
.byte 0 # Line Number
|
||||
.byte 0 # File Number
|
||||
.byte 11 # DW_MACRO_define_strx
|
||||
.byte 1 # Line Number
|
||||
.byte 0 # Macro String
|
||||
.byte 11 # DW_MACRO_define_strx
|
||||
.byte 2 # Line Number
|
||||
.byte 1 # Macro String
|
||||
.byte 12 # DW_MACRO_undef_strx
|
||||
.byte 3 # Line Number
|
||||
.byte 2 # Macro String
|
||||
.byte 4 # DW_MACRO_end_file
|
||||
.byte 0 # End Of Macro List Mark
|
||||
.Lcu_macro_begin1:
|
||||
.short 5 # Macro information version
|
||||
.byte 2 # Flags: 32 bit, debug_line_offset present
|
||||
.long 0 # debug_line_offset
|
||||
.byte 3 # DW_MACRO_start_file
|
||||
.byte 1 # Line Number
|
||||
.byte 3 # File Number
|
||||
.byte 11 # DW_MACRO_define_strx
|
||||
.byte 2 # Line Number
|
||||
.byte 0 # Macro String
|
||||
.byte 12 # DW_MACRO_undef_strx
|
||||
.byte 3 # Line Number
|
||||
.byte 1 # Macro String
|
||||
.byte 4 # DW_MACRO_end_file
|
||||
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 16 # Unit length
|
||||
.short 5 # Version
|
||||
.short 0 # Padding
|
||||
.Lstr_offsets_base0:
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long 12 # Unit length
|
||||
.short 5 # Version
|
||||
.short 0 # Padding
|
||||
.Lstr_offsets_base1:
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "DWARF_VERSION 5"
|
||||
.Linfo_string1:
|
||||
.asciz "COMPILE_UNIT 1"
|
||||
.Linfo_string2:
|
||||
.asciz "COMPILE_UNIT"
|
||||
.Linfo_string3:
|
||||
.asciz "COMPILE_UNIT 2"
|
||||
.Linfo_string4:
|
||||
.asciz "COMPILE_UNIT"
|
||||
Loading…
x
Reference in New Issue
Block a user