Index: lit/Breakpoint/Inputs/implicit_const_form_support.yaml =================================================================== --- lit/Breakpoint/Inputs/implicit_const_form_support.yaml +++ lit/Breakpoint/Inputs/implicit_const_form_support.yaml @@ -0,0 +1,41 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x00000000004004A0 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00000000004004A0 + AddressAlign: 0x0000000000000010 + Content: 31ED4989D15E4889E24883E4F0505449C7C01006400048C7C1A005400048C7C77E054000E8B7FFFFFFF4660F1F440000B820204000483D202040007413B8000000004885C07409BF20204000FFE06690C30F1F440000662E0F1F840000000000BE202040004881EE2020400048C1FE034889F048C1E83F4801C648D1FE7411B8000000004885C07407BF20204000FFE0C30F1F440000662E0F1F840000000000803DD91A0000007517554889E5E87EFFFFFFC605C71A0000015DC30F1F440000C30F1F440000662E0F1F840000000000EB8EB800000000C3B800000000C3554889E5534883EC08E8E6FFFFFF89C3E8E5FFFFFF01D84883C4085B5DC30F1F4000415741564189FF415541544C8D251618000055488D2D16180000534989F64989D54C29E54883EC0848C1FD03E877FEFFFF4885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3 + - Name: .debug_frame + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000008 + Content: 14000000FFFFFFFF03000178100C0708900100000000000014000000000000007205400000000000060000000000000014000000000000007805400000000000060000000000000034000000000000007E054000000000001E0000000000000004010000000E10860204030000000D060405000000830304140000000C070800 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 900000000500010800000000023A00000021310000000000000072054000000000002A0000000000000000000000039A0000000109054C0000007E054000000000001E00000000000000019C040405696E7400012C000000059F0000004C00000078054000000000000600000000000000019C018C00000001910000004C00000072054000000000000600000000000000019C00 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 012E003F19030E3A21013B0B3921056E0E49131101120740187A190000021101250E130B030E1B0E1101120710170000032E003F19030E3A0B3B0B390B49131101120740187C1900000424000B0B3E0B0308000000 + - Name: .debug_aranges + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 2C00000002000000000008000000000072054000000000002A0000000000000000000000000000000000000000000000 + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 5600000002001F0000000101FB0E0D00010101010000000100000100746573742E6370700000000000050C000902720540000000000001050913050159050C22050913050159050C22050D9105167405175805012F0207000101 + - Name: .debug_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 2F686F6D652F756D622F74657374735F323031382F3130315F696D706C696369745F636F6E73742F6E657700666F6F3200746573742E63707000474E5520432B2B313420382E302E3120323031383033313920286578706572696D656E74616C29202D6D74756E653D67656E65726963202D6D617263683D7838362D3634202D67202D6764776172662D3500666F6F31005F5A34666F6F3176006D61696E005F5A34666F6F327600 +Symbols: +... Index: lit/Breakpoint/implicit_const_form_support.test =================================================================== --- lit/Breakpoint/implicit_const_form_support.test +++ lit/Breakpoint/implicit_const_form_support.test @@ -0,0 +1,33 @@ +# RUN: yaml2obj %p/Inputs/implicit_const_form_support.yaml > %ttest +# RUN: lldb-test breakpoints %ttest %s | FileCheck %s + +## The intention of the test is to check that DW_FORM_implicit_const +## is supported and handled properly. + +## About implicit_const_form_support.yaml: +## The following invocation and code were used to produce the binary +## which was converted to yaml and reduced: +## gcc version 8.0.1 20180319 (experimental) (GCC) +## +## g++ test.cpp -g -gdwarf-5 -o test +## +## // test.cpp +## int foo1() { +## return 0; +## } +## +## int foo2() { +## return 0; +## } +## +## int main() { +## return foo1() + foo2(); +## } + +b foo1 +# CHECK-LABEL: b foo1 +# CHECK: Address: {{.*}}foo1() at test.cpp:2:9 + +b foo2 +# CHECK-LABEL: b foo2 +# CHECK: Address: {{.*}}foo2() at test.cpp:6:9 Index: source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h @@ -46,9 +46,10 @@ } // idx is assumed to be valid when calling GetAttrAndFormByIndexUnchecked() - void GetAttrAndFormByIndexUnchecked(uint32_t idx, dw_attr_t &attr, - dw_form_t &form) const { - m_attributes[idx].get(attr, form); + void GetAttrAndFormByIndexUnchecked( + uint32_t idx, dw_attr_t &attr, dw_form_t &form, + DWARFFormValue::ValueType *val = nullptr) const { + m_attributes[idx].get(attr, form, val); } dw_form_t GetFormByIndexUnchecked(uint32_t idx) const { return m_attributes[idx].get_form(); Index: source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -41,9 +41,13 @@ while (data.ValidOffset(*offset_ptr)) { dw_attr_t attr = data.GetULEB128(offset_ptr); dw_form_t form = data.GetULEB128(offset_ptr); + DWARFFormValue::ValueType val; + + if (form == DW_FORM_implicit_const) + val.value.sval = data.GetULEB128(offset_ptr); if (attr && form) - m_attributes.push_back(DWARFAttribute(attr, form)); + m_attributes.push_back(DWARFAttribute(attr, form, val)); else break; } Index: source/Plugins/SymbolFile/DWARF/DWARFAttribute.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -11,15 +11,17 @@ #define SymbolFileDWARF_DWARFAttribute_h_ #include "DWARFDefines.h" +#include "DWARFFormValue.h" #include "llvm/ADT/SmallVector.h" #include class DWARFUnit; -class DWARFFormValue; class DWARFAttribute { public: - DWARFAttribute(dw_attr_t attr, dw_form_t form) : m_attr(attr), m_form(form) {} + DWARFAttribute(dw_attr_t attr, dw_form_t form, + DWARFFormValue::ValueType value) + : m_attr(attr), m_form(form), m_value(value) {} void set(dw_attr_t attr, dw_form_t form) { m_attr = attr; @@ -29,9 +31,12 @@ void set_form(dw_form_t form) { m_form = form; } dw_attr_t get_attr() const { return m_attr; } dw_form_t get_form() const { return m_form; } - void get(dw_attr_t &attr, dw_form_t &form) const { + void get(dw_attr_t &attr, dw_form_t &form, + DWARFFormValue::ValueType *val = nullptr) const { attr = m_attr; form = m_form; + if (val) + *val = m_value; } bool operator==(const DWARFAttribute &rhs) const { return m_attr == rhs.m_attr && m_form == rhs.m_form; @@ -43,6 +48,7 @@ protected: dw_attr_t m_attr; dw_form_t m_form; + DWARFFormValue::ValueType m_value; }; class DWARFAttributes { Index: source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -26,10 +26,10 @@ return UINT32_MAX; } -void DWARFAttributes::Append(const DWARFUnit *cu, - dw_offset_t attr_die_offset, dw_attr_t attr, - dw_form_t form) { - AttributeValue attr_value = {cu, attr_die_offset, {attr, form}}; +void DWARFAttributes::Append(const DWARFUnit *cu, dw_offset_t attr_die_offset, + dw_attr_t attr, dw_form_t form) { + AttributeValue attr_value = { + cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}}; m_infos.push_back(attr_value); } Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -174,6 +174,10 @@ debug_info_data.GetU32(&offset); break; + case DW_FORM_implicit_const: + form_size = 0; + break; + default: *offset_ptr = m_offset; return false; @@ -287,6 +291,7 @@ // 0 sized form case DW_FORM_flag_present: + case DW_FORM_implicit_const: form_size = 0; break; @@ -378,6 +383,13 @@ Dump(dwarf2Data, cu, s, recurse_depth); } +static void setUnsignedOrSigned(int &dest, DWARFFormValue &val) { + if (val.Form() == DW_FORM_implicit_const) + dest = val.Signed(); + else + dest = val.Unsigned(); +} + //---------------------------------------------------------------------- // GetDIENamesAndRanges // @@ -420,11 +432,13 @@ uint32_t i; dw_attr_t attr; dw_form_t form; + DWARFFormValue::ValueType val; bool do_offset = false; for (i = 0; i < numAttributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - DWARFFormValue form_value(cu, form); + abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form, &val); + DWARFFormValue form_value(cu, form, val); + if (form_value.ExtractValue(debug_info_data, &offset)) { switch (attr) { case DW_AT_low_pc: @@ -491,32 +505,32 @@ case DW_AT_decl_file: if (decl_file == 0) - decl_file = form_value.Unsigned(); + setUnsignedOrSigned(decl_file, form_value); break; case DW_AT_decl_line: - if (decl_line == 0) - decl_line = form_value.Unsigned(); + if (decl_line != 0) + setUnsignedOrSigned(decl_line, form_value); break; case DW_AT_decl_column: - if (decl_column == 0) - decl_column = form_value.Unsigned(); + if (decl_column != 0) + setUnsignedOrSigned(decl_column, form_value); break; case DW_AT_call_file: - if (call_file == 0) - call_file = form_value.Unsigned(); + if (call_file != 0) + setUnsignedOrSigned(call_file, form_value); break; case DW_AT_call_line: if (call_line == 0) - call_line = form_value.Unsigned(); + setUnsignedOrSigned(call_line, form_value); break; case DW_AT_call_column: if (call_column == 0) - call_column = form_value.Unsigned(); + setUnsignedOrSigned(call_column, form_value); break; case DW_AT_frame_base: Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -56,7 +56,8 @@ }; DWARFFormValue(); - DWARFFormValue(const DWARFUnit *cu, dw_form_t form); + DWARFFormValue(const DWARFUnit *cu, dw_form_t form, + ValueType val = ValueType()); const DWARFUnit *GetCompileUnit() const { return m_cu; } void SetCompileUnit(const DWARFUnit *cu) { m_cu = cu; } dw_form_t Form() const { return m_form; } Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -154,8 +154,9 @@ DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {} -DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form) - : m_cu(cu), m_form(form), m_value() {} +DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form, + ValueType val) + : m_cu(cu), m_form(form), m_value(val) {} void DWARFFormValue::Clear() { m_cu = nullptr; @@ -165,6 +166,9 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, lldb::offset_t *offset_ptr) { + if (m_form == DW_FORM_implicit_const) + return true; + bool indirect = false; bool is_block = false; m_value.data = NULL; @@ -366,6 +370,7 @@ // 0 bytes values (implied from DW_FORM) case DW_FORM_flag_present: + case DW_FORM_implicit_const: return true; // 1 byte values @@ -822,6 +827,7 @@ case DW_FORM_ref_sig8: case DW_FORM_GNU_str_index: case DW_FORM_GNU_addr_index: + case DW_FORM_implicit_const: return true; default: break;