labath created this revision. labath added reviewers: vsk, dblaikie. Herald added a project: LLDB.
The code changes are very straight-forward -- just handle both DW_AT_GNU and DW_AT_call versions of all tags and attributes. There is just one small gotcha: in the GNU version, DW_AT_low_pc was used both for the "return pc" and the "call pc" values, depending on whether the tag was describing a tail call, while the official scheme uses different attributes for the two things. Depends on D80518 <https://reviews.llvm.org/D80518>. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D80519 Files: lldb/source/Expression/DWARFExpression.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/test/API/functionalities/param_entry_vals/basic_entry_values/TestBasicEntryValues.py lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
Index: lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp =================================================================== --- lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp +++ lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp @@ -18,8 +18,10 @@ use<int &>(dummy); ++global; - //% self.filecheck("image lookup -v -a $pc", "main.cpp", "-check-prefix=FUNC1-DESC") - // FUNC1-DESC: name = "sink", type = "int &", location = DW_OP_entry_value + //% prefix = "FUNC1-GNU" if "GNU" in self.name else "FUNC1-V5" + //% self.filecheck("image lookup -v -a $pc", "main.cpp", "-check-prefix="+prefix) + // FUNC1-GNU: name = "sink", type = "int &", location = DW_OP_GNU_entry_value + // FUNC1-V5: name = "sink", type = "int &", location = DW_OP_entry_value } __attribute__((noinline)) void func2(int &sink, int x) { Index: lldb/test/API/functionalities/param_entry_vals/basic_entry_values/TestBasicEntryValues.py =================================================================== --- lldb/test/API/functionalities/param_entry_vals/basic_entry_values/TestBasicEntryValues.py +++ lldb/test/API/functionalities/param_entry_vals/basic_entry_values/TestBasicEntryValues.py @@ -11,3 +11,7 @@ lldbinline.MakeInlineTest(__file__, globals(), decorators=decorators, name="BasicEntryValues_V5", build_dict=dict(CXXFLAGS_EXTRAS="-O2 -glldb")) + +lldbinline.MakeInlineTest(__file__, globals(), decorators=decorators, + name="BasicEntryValues_GNU", + build_dict=dict(CXXFLAGS_EXTRAS="-O2 -ggdb")) Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3601,7 +3601,8 @@ CallSiteParameterArray parameters; for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid(); child = child.GetSibling()) { - if (child.Tag() != DW_TAG_call_site_parameter) + if (child.Tag() != DW_TAG_call_site_parameter && + child.Tag() != DW_TAG_GNU_call_site_parameter) continue; llvm::Optional<DWARFExpression> LocationInCallee; @@ -3631,7 +3632,7 @@ dw_attr_t attr = attributes.AttributeAtIndex(i); if (attr == DW_AT_location) LocationInCallee = parse_simple_location(i); - if (attr == DW_AT_call_value) + if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value) LocationInCaller = parse_simple_location(i); } @@ -3648,8 +3649,9 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { // Check if the function has a supported call site-related attribute. // TODO: In the future it may be worthwhile to support call_all_source_calls. - uint64_t has_call_edges = - function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0); + bool has_call_edges = + function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0) || + function_die.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites, 0); if (!has_call_edges) return {}; @@ -3665,13 +3667,15 @@ std::vector<std::unique_ptr<CallEdge>> call_edges; for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid(); child = child.GetSibling()) { - if (child.Tag() != DW_TAG_call_site) + if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site) continue; llvm::Optional<DWARFDIE> call_origin; llvm::Optional<DWARFExpression> call_target; addr_t return_pc = LLDB_INVALID_ADDRESS; addr_t call_inst_pc = LLDB_INVALID_ADDRESS; + addr_t low_pc = LLDB_INVALID_ADDRESS; + bool tail_call = false; DWARFAttributes attributes; const size_t num_attributes = child.GetAttributes(attributes); @@ -3684,8 +3688,11 @@ dw_attr_t attr = attributes.AttributeAtIndex(i); + if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call) + tail_call = form_value.Boolean(); + // Extract DW_AT_call_origin (the call target's DIE). - if (attr == DW_AT_call_origin) { + if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) { call_origin = form_value.Reference(); if (!call_origin->IsValid()) { LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}", @@ -3694,6 +3701,9 @@ } } + if (attr == DW_AT_low_pc) + low_pc = form_value.Address(); + // Extract DW_AT_call_return_pc (the PC the call returns to) if it's // available. It should only ever be unavailable for tail call edges, in // which case use LLDB_INVALID_ADDRESS. @@ -3708,7 +3718,7 @@ // Extract DW_AT_call_target (the location of the address of the indirect // call). - if (attr == DW_AT_call_target) { + if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) { if (!DWARFFormValue::IsBlockForm(form_value.Form())) { LLDB_LOG(log, "CollectCallEdges: AT_call_target does not have block form"); @@ -3723,6 +3733,15 @@ child.GetCU()); } } + // In DWARF v4 low_pc is either the address of the call instruction or the + // "return to" address, depending on whether the call is a tail call. + if (child.Tag() == DW_TAG_GNU_call_site) { + if (tail_call) + call_inst_pc = low_pc; + else + return_pc = low_pc; + } + if (!call_origin && !call_target) { LLDB_LOG(log, "CollectCallEdges: call site without any call target"); continue; Index: lldb/source/Expression/DWARFExpression.cpp =================================================================== --- lldb/source/Expression/DWARFExpression.cpp +++ lldb/source/Expression/DWARFExpression.cpp @@ -396,6 +396,7 @@ return offset - data_offset; } + case DW_OP_GNU_entry_value: case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block { uint64_t subexpr_len = data.GetULEB128(&offset); @@ -2522,6 +2523,7 @@ stack.push_back(Scalar(value)); } break; + case DW_OP_GNU_entry_value: case DW_OP_entry_value: { if (!Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx, opcodes, offset, error_ptr, log)) {
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits