mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-21 18:22:53 +01:00
[Debug-Info][llvm-dwarfdump] Don't try to dump location
list for attributes that don't have the loclist class. Summary: The overflow error occurs when we try to dump location list for those attributes that do not have the loclist class, like DW_AT_count and DW_AT_byte_size. After re-reviewed the entire list, I sorted those attributes into two parts, one for dumping location list and one for dumping the location expression. Reviewed By: probinson Differential Revision: https://reviews.llvm.org/D105613
This commit is contained in:
parent
10658f9d9e
commit
e8ead0fbb2
@ -39,9 +39,12 @@ struct DWARFAttribute {
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/// Identify DWARF attributes that may contain a pointer to a location list.
|
||||
static bool mayHaveLocationList(dwarf::Attribute Attr);
|
||||
|
||||
/// Identifies DWARF attributes that may contain a reference to a
|
||||
/// DWARF expression.
|
||||
static bool mayHaveLocationDescription(dwarf::Attribute Attr);
|
||||
static bool mayHaveLocationExpr(dwarf::Attribute Attr);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -1029,7 +1029,7 @@ unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
|
||||
// buffer using cloneExpression(), otherwise copy the data directly.
|
||||
SmallVector<uint8_t, 32> Buffer;
|
||||
ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
|
||||
if (DWARFAttribute::mayHaveLocationDescription(AttrSpec.Attr) &&
|
||||
if (DWARFAttribute::mayHaveLocationExpr(AttrSpec.Attr) &&
|
||||
(Val.isFormClass(DWARFFormValue::FC_Block) ||
|
||||
Val.isFormClass(DWARFFormValue::FC_Exprloc))) {
|
||||
DWARFUnit &OrigUnit = Unit.getOrigUnit();
|
||||
|
@ -69,39 +69,43 @@ static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
|
||||
}
|
||||
}
|
||||
|
||||
static void dumpLocation(raw_ostream &OS, const DWARFFormValue &FormValue,
|
||||
DWARFUnit *U, unsigned Indent,
|
||||
DIDumpOptions DumpOpts) {
|
||||
static void dumpLocationList(raw_ostream &OS, const DWARFFormValue &FormValue,
|
||||
DWARFUnit *U, unsigned Indent,
|
||||
DIDumpOptions DumpOpts) {
|
||||
assert(FormValue.isFormClass(DWARFFormValue::FC_SectionOffset) &&
|
||||
"bad FORM for location list");
|
||||
DWARFContext &Ctx = U->getContext();
|
||||
const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
|
||||
if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
|
||||
FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) {
|
||||
ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
|
||||
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
|
||||
Ctx.isLittleEndian(), 0);
|
||||
DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
|
||||
.print(OS, DumpOpts, MRI, U);
|
||||
return;
|
||||
uint64_t Offset = *FormValue.getAsSectionOffset();
|
||||
|
||||
if (FormValue.getForm() == DW_FORM_loclistx) {
|
||||
FormValue.dump(OS, DumpOpts);
|
||||
|
||||
if (auto LoclistOffset = U->getLoclistOffset(Offset))
|
||||
Offset = *LoclistOffset;
|
||||
else
|
||||
return;
|
||||
}
|
||||
U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), MRI,
|
||||
Ctx.getDWARFObj(), U, DumpOpts,
|
||||
Indent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
|
||||
uint64_t Offset = *FormValue.getAsSectionOffset();
|
||||
|
||||
if (FormValue.getForm() == DW_FORM_loclistx) {
|
||||
FormValue.dump(OS, DumpOpts);
|
||||
|
||||
if (auto LoclistOffset = U->getLoclistOffset(Offset))
|
||||
Offset = *LoclistOffset;
|
||||
else
|
||||
return;
|
||||
}
|
||||
U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
|
||||
MRI, Ctx.getDWARFObj(), U, DumpOpts,
|
||||
Indent);
|
||||
return;
|
||||
}
|
||||
|
||||
FormValue.dump(OS, DumpOpts);
|
||||
static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
|
||||
DWARFUnit *U, unsigned Indent,
|
||||
DIDumpOptions DumpOpts) {
|
||||
assert((FormValue.isFormClass(DWARFFormValue::FC_Block) ||
|
||||
FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) &&
|
||||
"bad FORM for location expression");
|
||||
DWARFContext &Ctx = U->getContext();
|
||||
const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
|
||||
ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
|
||||
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
|
||||
Ctx.isLittleEndian(), 0);
|
||||
DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
|
||||
.print(OS, DumpOpts, MRI, U);
|
||||
return;
|
||||
}
|
||||
|
||||
/// Dump the name encoded in the type tag.
|
||||
@ -289,9 +293,15 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
|
||||
else
|
||||
FormValue.dump(OS, DumpOpts);
|
||||
}
|
||||
} else if (Form == dwarf::Form::DW_FORM_exprloc ||
|
||||
DWARFAttribute::mayHaveLocationDescription(Attr))
|
||||
dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
|
||||
} else if (DWARFAttribute::mayHaveLocationList(Attr) &&
|
||||
FormValue.isFormClass(DWARFFormValue::FC_SectionOffset))
|
||||
dumpLocationList(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4,
|
||||
DumpOpts);
|
||||
else if (FormValue.isFormClass(DWARFFormValue::FC_Exprloc) ||
|
||||
(DWARFAttribute::mayHaveLocationExpr(Attr) &&
|
||||
FormValue.isFormClass(DWARFFormValue::FC_Block)))
|
||||
dumpLocationExpr(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4,
|
||||
DumpOpts);
|
||||
else
|
||||
FormValue.dump(OS, DumpOpts);
|
||||
|
||||
@ -744,11 +754,29 @@ DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr) {
|
||||
bool DWARFAttribute::mayHaveLocationList(dwarf::Attribute Attr) {
|
||||
switch(Attr) {
|
||||
case DW_AT_location:
|
||||
case DW_AT_string_length:
|
||||
case DW_AT_return_addr:
|
||||
case DW_AT_data_member_location:
|
||||
case DW_AT_frame_base:
|
||||
case DW_AT_static_link:
|
||||
case DW_AT_segment:
|
||||
case DW_AT_use_location:
|
||||
case DW_AT_vtable_elem_location:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DWARFAttribute::mayHaveLocationExpr(dwarf::Attribute Attr) {
|
||||
switch (Attr) {
|
||||
// From the DWARF v5 specification.
|
||||
case DW_AT_location:
|
||||
case DW_AT_byte_size:
|
||||
case DW_AT_bit_offset:
|
||||
case DW_AT_bit_size:
|
||||
case DW_AT_string_length:
|
||||
case DW_AT_lower_bound:
|
||||
@ -764,6 +792,7 @@ bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr) {
|
||||
case DW_AT_vtable_elem_location:
|
||||
case DW_AT_allocated:
|
||||
case DW_AT_associated:
|
||||
case DW_AT_data_location:
|
||||
case DW_AT_byte_stride:
|
||||
case DW_AT_rank:
|
||||
case DW_AT_call_value:
|
||||
|
149
test/tools/llvm-dwarfdump/X86/formclass3.s
Normal file
149
test/tools/llvm-dwarfdump/X86/formclass3.s
Normal file
@ -0,0 +1,149 @@
|
||||
# Source:
|
||||
# unsigned char arr[0x100000];
|
||||
# Compile with:
|
||||
# clang -O2 -gdwarf-3 -S 1.cpp -o 1.s --target=x86_64-pc-linux-gnu
|
||||
|
||||
# RUN: llvm-mc -triple x86_64-pc-linux-gnu -o - -filetype obj < %s | \
|
||||
# RUN: llvm-dwarfdump -debug-info - | FileCheck %s
|
||||
|
||||
# CHECK: DW_AT_count (0x00100000)
|
||||
|
||||
.text
|
||||
.file "1.cpp"
|
||||
.file 1 "/llvm-project" "1.cpp"
|
||||
.type arr,@object # @arr
|
||||
.bss
|
||||
.globl arr
|
||||
.p2align 4
|
||||
arr:
|
||||
.zero 1048576
|
||||
.size arr, 1048576
|
||||
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 12 # DW_FORM_flag
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 10 # DW_FORM_block1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 1 # DW_TAG_array_type
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 33 # DW_TAG_subrange_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 55 # DW_AT_count
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.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 3 # DWARF version number
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.byte 1 # Abbrev [1] 0xb:0x47 DW_TAG_compile_unit
|
||||
.long .Linfo_string0 # DW_AT_producer
|
||||
.short 33 # DW_AT_language
|
||||
.long .Linfo_string1 # DW_AT_name
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.long .Linfo_string2 # DW_AT_comp_dir
|
||||
.byte 2 # Abbrev [2] 0x1e:0x16 DW_TAG_variable
|
||||
.long .Linfo_string3 # DW_AT_name
|
||||
.long 52 # DW_AT_type
|
||||
.byte 1 # DW_AT_external
|
||||
.byte 1 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.byte 9 # DW_AT_location
|
||||
.byte 3
|
||||
.quad arr
|
||||
.byte 3 # Abbrev [3] 0x34:0xf DW_TAG_array_type
|
||||
.long 67 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x39:0x9 DW_TAG_subrange_type
|
||||
.long 74 # DW_AT_type
|
||||
.long 1048576 # DW_AT_count
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 5 # Abbrev [5] 0x43:0x7 DW_TAG_base_type
|
||||
.long .Linfo_string4 # DW_AT_name
|
||||
.byte 8 # DW_AT_encoding
|
||||
.byte 1 # DW_AT_byte_size
|
||||
.byte 6 # Abbrev [6] 0x4a:0x7 DW_TAG_base_type
|
||||
.long .Linfo_string5 # DW_AT_name
|
||||
.byte 8 # DW_AT_byte_size
|
||||
.byte 7 # DW_AT_encoding
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 13.0.0" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "1.cpp" # string offset=21
|
||||
.Linfo_string2:
|
||||
.asciz "/llvm-project" # string offset=27
|
||||
.Linfo_string3:
|
||||
.asciz "arr" # string offset=61
|
||||
.Linfo_string4:
|
||||
.asciz "unsigned char" # string offset=65
|
||||
.Linfo_string5:
|
||||
.asciz "__ARRAY_SIZE_TYPE__" # string offset=79
|
||||
.ident "clang version 13.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
Loading…
Reference in New Issue
Block a user