diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -229,6 +229,14 @@ /// \param[in] fallback_style /// The display style for the address. /// + /// \param[in] addr_byte_size + /// The address byte size for the address. + /// + /// \param[in] all_ranges + /// If true, dump all valid ranges and value ranges for the variable that + /// contains the address, otherwise dumping the range that contains the + /// address. + /// /// \return /// Returns \b true if the address was able to be displayed. /// File and load addresses may be unresolved and it may not be @@ -238,7 +246,8 @@ /// \see Address::DumpStyle bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style = DumpStyleInvalid, - uint32_t addr_byte_size = UINT32_MAX) const; + uint32_t addr_byte_size = UINT32_MAX, + bool all_ranges = false) const; AddressClass GetAddressClass() const; diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -15,6 +15,7 @@ #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" +#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h" #include class DWARFUnit; @@ -55,18 +56,10 @@ /// \param[in] level /// The level of verbosity to use. /// - /// \param[in] location_list_base_addr - /// If this is a location list based expression, this is the - /// address of the object that owns it. NOTE: this value is - /// different from the DWARF version of the location list base - /// address which is compile unit relative. This base address - /// is the address of the object that owns the location list. - /// /// \param[in] abi /// An optional ABI plug-in that can be used to resolve register /// names. - void GetDescription(Stream *s, lldb::DescriptionLevel level, - lldb::addr_t location_list_base_addr, ABI *abi) const; + void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const; /// Return true if the location expression contains data bool IsValid() const; @@ -217,6 +210,13 @@ lldb::addr_t func_load_addr, lldb::addr_t address, ABI *abi); + bool DumpLocations(Stream *s, lldb::DescriptionLevel level, + lldb::addr_t func_load_addr, lldb::addr_t addr, ABI *abi); + + bool GetLocationExpressions( + lldb::addr_t load_function_start, + llvm::function_ref callback) const; + bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op); llvm::Optional diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -77,7 +77,9 @@ const DWARFExpression &LocationExpression() const { return m_location; } - bool DumpLocationForAddress(Stream *s, const Address &address); + // When given invalid address, it dumps all locations. Otherwise it only dumps + // the location that contains this address. + bool DumpLocations(Stream *s, const Address &address); size_t MemorySize() const; diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -50,6 +50,7 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Timer.h" +#include "lldb/lldb-private-enumerations.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/FileSystem.h" @@ -1429,7 +1430,8 @@ } static void DumpAddress(ExecutionContextScope *exe_scope, - const Address &so_addr, bool verbose, Stream &strm) { + const Address &so_addr, bool verbose, bool all_ranges, + Stream &strm) { strm.IndentMore(); strm.Indent(" Address: "); so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); @@ -1444,7 +1446,8 @@ // Print out detailed address information when verbose is enabled if (verbose) { strm.EOL(); - so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); + so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext, + Address::DumpStyleInvalid, UINT32_MAX, all_ranges); } strm.IndentLess(); } @@ -1452,7 +1455,7 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, uint32_t resolve_mask, lldb::addr_t raw_addr, lldb::addr_t offset, - bool verbose) { + bool verbose, bool all_ranges) { if (module) { lldb::addr_t addr = raw_addr - offset; Address so_addr; @@ -1470,7 +1473,7 @@ ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); - DumpAddress(exe_scope, so_addr, verbose, strm); + DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm); // strm.IndentMore(); // strm.Indent (" Address: "); // so_addr.Dump (&strm, exe_scope, @@ -1502,7 +1505,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, - bool verbose) { + bool verbose, bool all_ranges) { if (!module) return 0; @@ -1535,7 +1538,7 @@ if (symbol && symbol->ValueIsAddress()) { DumpAddress( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - symbol->GetAddressRef(), verbose, strm); + symbol->GetAddressRef(), verbose, all_ranges, strm); } } strm.IndentLess(); @@ -1545,7 +1548,7 @@ static void DumpSymbolContextList(ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, - bool verbose) { + bool verbose, bool all_ranges) { strm.IndentMore(); const uint32_t num_matches = sc_list.GetSize(); @@ -1557,7 +1560,7 @@ sc.GetAddressRange(eSymbolContextEverything, 0, true, range); - DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm); + DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm); } } strm.IndentLess(); @@ -1567,7 +1570,7 @@ Stream &strm, Module *module, const char *name, bool name_is_regex, const ModuleFunctionSearchOptions &options, - bool verbose) { + bool verbose, bool all_ranges) { if (module && name && name[0]) { SymbolContextList sc_list; size_t num_matches = 0; @@ -1588,7 +1591,7 @@ strm.PutCString(":\n"); DumpSymbolContextList( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - strm, sc_list, verbose); + strm, sc_list, verbose, all_ranges); } return num_matches; } @@ -1693,7 +1696,7 @@ Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines, - bool verbose) { + bool verbose, bool all_ranges) { if (module && file_spec) { SymbolContextList sc_list; const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec( @@ -1710,7 +1713,7 @@ strm.PutCString(":\n"); DumpSymbolContextList( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - strm, sc_list, verbose); + strm, sc_list, verbose, all_ranges); return num_matches; } } @@ -3598,6 +3601,10 @@ case 'r': m_use_regex = true; break; + + case '\x01': + m_all_ranges = true; + break; default: llvm_unreachable("Unimplemented option"); } @@ -3614,6 +3621,7 @@ m_line_number = 0; m_use_regex = false; m_include_inlines = true; + m_all_ranges = false; m_verbose = false; m_print_all = false; } @@ -3632,6 +3640,7 @@ bool m_use_regex; // Name lookups in m_str are regular expressions. bool m_include_inlines; // Check for inline entries when looking up by // file/line. + bool m_all_ranges; // Print all ranges or single range. bool m_verbose; // Enable verbose lookup info bool m_print_all; // Print all matches, even in cases where there's a best // match. @@ -3714,7 +3723,8 @@ (m_options.m_verbose ? static_cast(eSymbolContextVariable) : 0), - m_options.m_addr, m_options.m_offset, m_options.m_verbose)) { + m_options.m_addr, m_options.m_offset, m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3725,7 +3735,8 @@ if (!m_options.m_str.empty()) { if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), - m_options.m_use_regex, m_options.m_verbose)) { + m_options.m_use_regex, m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3737,7 +3748,8 @@ if (LookupFileAndLineInModule( m_interpreter, result.GetOutputStream(), module, m_options.m_file, m_options.m_line_number, - m_options.m_include_inlines, m_options.m_verbose)) { + m_options.m_include_inlines, m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3755,7 +3767,8 @@ if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex, function_options, - m_options.m_verbose)) { + m_options.m_verbose, + m_options.m_all_ranges)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -957,6 +957,9 @@ def target_modules_lookup_type : Option<"type", "t">, Group<6>, Arg<"Name">, Required, Desc<"Lookup a type by name in the debug symbols in one or more " "target modules.">; + def target_modules_lookup_variables_ranges : Option<"show-variable-ranges", + "\\x01">, GroupRange<1, 6>, Desc<"Dump valid ranges of variables (must be " + "used in conjunction with --verbose">; def target_modules_lookup_verbose : Option<"verbose", "v">, Desc<"Enable verbose lookup information.">; def target_modules_lookup_all : Option<"all", "A">, Desc<"Print all matches, " diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -22,6 +22,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Process.h" @@ -403,7 +404,8 @@ } bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, - DumpStyle fallback_style, uint32_t addr_size) const { + DumpStyle fallback_style, uint32_t addr_size, + bool all_ranges) const { // If the section was nullptr, only load address is going to work unless we // are trying to deref a pointer SectionSP section_sp(GetSection()); @@ -720,27 +722,42 @@ bool get_parent_variables = true; bool stop_if_block_is_inlined_function = false; VariableList variable_list; - sc.block->AppendVariables(can_create, get_parent_variables, - stop_if_block_is_inlined_function, - [](Variable *) { return true; }, - &variable_list); - + addr_t file_addr = GetFileAddress(); + sc.block->AppendVariables( + can_create, get_parent_variables, + stop_if_block_is_inlined_function, + [&](Variable *var) { + return var && var->LocationIsValidForAddress(*this); + }, + &variable_list); + ABISP abi = + ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); for (const VariableSP &var_sp : variable_list) { - if (var_sp && var_sp->LocationIsValidForAddress(*this)) { - s->Indent(); - s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"", - var_sp->GetID(), var_sp->GetName().GetCString()); - Type *type = var_sp->GetType(); - if (type) - s->Printf(", type = \"%s\"", type->GetName().GetCString()); - else - s->PutCString(", type = "); - s->PutCString(", location = "); - var_sp->DumpLocationForAddress(s, *this); - s->PutCString(", decl = "); - var_sp->GetDeclaration().DumpStopContext(s, false); - s->EOL(); - } + s->Indent(); + s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"", + var_sp->GetID(), var_sp->GetName().GetCString()); + Type *type = var_sp->GetType(); + if (type) + s->Printf(", type = \"%s\"", type->GetName().GetCString()); + else + s->PutCString(", type = "); + s->PutCString(", valid ranges = "); + if (var_sp->GetScopeRange().IsEmpty()) + s->PutCString(""); + else if (all_ranges) { + for (auto range : var_sp->GetScopeRange()) + DumpAddressRange(s->AsRawOstream(), range.GetRangeBase(), + range.GetRangeEnd(), addr_size); + } else if (auto *range = + var_sp->GetScopeRange().FindEntryThatContains( + file_addr)) + DumpAddressRange(s->AsRawOstream(), range->GetRangeBase(), + range->GetRangeEnd(), addr_size); + s->PutCString(", location = "); + var_sp->DumpLocations(s, all_ranges ? LLDB_INVALID_ADDRESS : *this); + s->PutCString(", decl = "); + var_sp->GetDeclaration().DumpStopContext(s, false); + s->EOL(); } } } diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -129,7 +129,6 @@ } void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level, - addr_t location_list_base_addr, ABI *abi) const { if (IsLocationList()) { // We have a location list @@ -2673,14 +2672,50 @@ return DataExtractor(buffer_sp, byte_order, addr_size); } -llvm::Optional -DWARFExpression::GetLocationExpression(addr_t load_function_start, - addr_t addr) const { +bool DWARFExpression::DumpLocations(Stream *s, lldb::DescriptionLevel level, + addr_t load_function_start, addr_t addr, + ABI *abi) { + if (!IsLocationList()) { + DumpLocation(s, m_data, level, abi); + return true; + } + bool dump_all = addr == LLDB_INVALID_ADDRESS; + llvm::ListSeparator separator; + auto callback = [&](llvm::DWARFLocationExpression loc) -> bool { + if (loc.Range && + (dump_all || (loc.Range->LowPC <= addr && addr < loc.Range->HighPC))) { + uint32_t addr_size = m_data.GetAddressByteSize(); + DataExtractor data = ToDataExtractor(loc, m_data.GetByteOrder(), + m_data.GetAddressByteSize()); + s->AsRawOstream() << separator; + s->PutCString("["); + s->AsRawOstream() << llvm::format_hex(loc.Range->LowPC, + 2 + 2 * addr_size); + s->PutCString(", "); + s->AsRawOstream() << llvm::format_hex(loc.Range->HighPC, + 2 + 2 * addr_size); + s->PutCString(") -> "); + DumpLocation(s, data, level, abi); + return dump_all; + } + return true; + }; + if (!GetLocationExpressions(load_function_start, callback)) + return false; + return true; +} + +bool DWARFExpression::GetLocationExpressions( + addr_t load_function_start, + llvm::function_ref callback) const { + if (load_function_start == LLDB_INVALID_ADDRESS) + return false; + Log *log = GetLog(LLDBLog::Expressions); std::unique_ptr loctable_up = m_dwarf_cu->GetLocationTable(m_data); - llvm::Optional result; + uint64_t offset = 0; auto lookup_addr = [&](uint32_t index) -> llvm::Optional { @@ -2700,19 +2735,32 @@ addr_t slide = load_function_start - m_loclist_addresses->func_file_addr; loc->Range->LowPC += slide; loc->Range->HighPC += slide; - - if (loc->Range->LowPC <= addr && addr < loc->Range->HighPC) - result = ToDataExtractor(*loc, m_data.GetByteOrder(), - m_data.GetAddressByteSize()); } - return !result; + return callback(*loc); }; - llvm::Error E = loctable_up->visitAbsoluteLocationList( + llvm::Error error = loctable_up->visitAbsoluteLocationList( offset, llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, lookup_addr, process_list); - if (E) - LLDB_LOG_ERROR(log, std::move(E), "{0}"); - return result; + if (error) { + LLDB_LOG_ERROR(log, std::move(error), "{0}"); + return false; + } + return true; +} + +llvm::Optional +DWARFExpression::GetLocationExpression(addr_t load_function_start, + addr_t addr) const { + llvm::Optional data; + auto callback = [&](llvm::DWARFLocationExpression loc) { + if (loc.Range && loc.Range->LowPC <= addr && addr < loc.Range->HighPC) { + data = ToDataExtractor(loc, m_data.GetByteOrder(), + m_data.GetAddressByteSize()); + } + return !data; + }; + GetLocationExpressions(load_function_start, callback); + return data; } bool DWARFExpression::MatchesOperand(StackFrame &frame, @@ -2738,7 +2786,8 @@ addr_t pc = frame.GetFrameCodeAddress().GetLoadAddress( frame.CalculateTarget().get()); - if (llvm::Optional expr = GetLocationExpression(load_function_start, pc)) + if (llvm::Optional expr = + GetLocationExpression(load_function_start, pc)) opcodes = std::move(*expr); else return false; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3923,7 +3923,7 @@ if (log) { StreamString call_target_desc; call_target->GetDescription(&call_target_desc, eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + nullptr); LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}", call_target_desc.GetString()); } @@ -3936,11 +3936,9 @@ for (const CallSiteParameter ¶m : parameters) { StreamString callee_loc_desc, caller_loc_desc; param.LocationInCallee.GetDescription(&callee_loc_desc, - eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + eDescriptionLevelBrief, nullptr); param.LocationInCaller.GetDescription(&caller_loc_desc, - eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + eDescriptionLevelBrief, nullptr); LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}", callee_loc_desc.GetString(), caller_loc_desc.GetString()); } diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -147,23 +147,13 @@ if (m_location.IsValid()) { s->PutCString(", location = "); - lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; - if (m_location.IsLocationList()) { - SymbolContext variable_sc; - m_owner_scope->CalculateSymbolContext(&variable_sc); - if (variable_sc.function) - loclist_base_addr = variable_sc.function->GetAddressRange() - .GetBaseAddress() - .GetFileAddress(); - } ABISP abi; if (m_owner_scope) { ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); if (module_sp) abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); } - m_location.GetDescription(s, lldb::eDescriptionLevelBrief, - loclist_base_addr, abi.get()); + m_location.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get()); } if (m_external) @@ -445,36 +435,25 @@ return error; } -bool Variable::DumpLocationForAddress(Stream *s, const Address &address) { - // Be sure to resolve the address to section offset prior to calling this - // function. - if (address.IsSectionOffset()) { - SymbolContext sc; - CalculateSymbolContext(&sc); - if (sc.module_sp == address.GetModule()) { - ABISP abi; - if (m_owner_scope) { - ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); - if (module_sp) - abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); - } +bool Variable::DumpLocations(Stream *s, const Address &address) { + SymbolContext sc; + CalculateSymbolContext(&sc); + ABISP abi; + if (m_owner_scope) { + ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); + if (module_sp) + abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); + } - const addr_t file_addr = address.GetFileAddress(); - if (sc.function) { - if (sc.function->GetAddressRange().ContainsFileAddress(address)) { - addr_t loclist_base_file_addr = - sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); - if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) - return false; - return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief, - loclist_base_file_addr, - file_addr, abi.get()); - } - } - return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, file_addr, - abi.get()); - } + const addr_t file_addr = address.GetFileAddress(); + if (sc.function) { + addr_t loclist_base_file_addr = + sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); + if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) + return false; + return m_location.DumpLocations(s, eDescriptionLevelBrief, + loclist_base_file_addr, file_addr, + abi.get()); } return false; } diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s @@ -2,7 +2,7 @@ # RUN: %lldb %t -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s # CHECK-LABEL: image lookup -v -s lookup_loclists -# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX, +# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX, # CHECK-NOT: Variable: loclists: diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s @@ -8,18 +8,30 @@ # RUN: %lldb %t -o "image lookup -v -a 0" -o "image lookup -v -a 2" \ # RUN: -o "image dump symfile" -o exit | FileCheck %s +# RUN: %lldb %t -o "image lookup -v -a 0 -show-variable-ranges" -o \ +# RUN: "image lookup -v -a 2 -show-variable-ranges" \ +# RUN: -o exit | FileCheck %s --check-prefix=ALL-RANGES + # RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s --defsym LOCLISTS=0 > %t # RUN: %lldb %t -o "image lookup -v -a 0" -o "image lookup -v -a 2" \ # RUN: -o "image dump symfile" -o exit | FileCheck %s --check-prefix=CHECK --check-prefix=LOCLISTS +# ALL-RANGES-LABEL: image lookup -v -a 0 -show-variable-ranges +# ALL-RANGES: Variable: id = {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI, [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX +# ALL-RANGES: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = , location = +# ALL-RANGES-LABEL: image lookup -v -a 2 -show-variable-ranges +# ALL-RANGES: Variable: id = {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI, [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX +# ALL-RANGES: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = , location = +# ALL-RANGES: Variable: id = {{.*}}, name = "x3", type = "int", valid ranges = , location = [0x0000000000000002, 0x0000000000000003) -> DW_OP_reg1 RDX + # CHECK-LABEL: image lookup -v -a 0 -# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg5 RDI, -# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = , +# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI +# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = , location = , # CHECK-LABEL: image lookup -v -a 2 -# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX, -# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = , -# CHECK: Variable: {{.*}}, name = "x3", type = "int", location = DW_OP_reg1 RDX, +# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX +# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = , location = , +# CHECK: Variable: {{.*}}, name = "x3", type = "int", valid ranges = , location = [0x0000000000000002, 0x0000000000000003) -> DW_OP_reg1 RDX # CHECK-LABEL: image dump symfile # CHECK: CompileUnit{0x00000000} diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s @@ -7,10 +7,10 @@ # CHECK-LABEL: image lookup -v -s loc -# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg5 RDI, +# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI, # CHECK-LABEL: image lookup -v -s loclists -# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = DW_OP_reg0 RAX, +# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = , location = [0x0000000000000001, 0x0000000000000002) -> DW_OP_reg0 RAX, loc: diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s @@ -3,8 +3,8 @@ # RUN: %lldb debug_loclists-dwo.o -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s # CHECK-LABEL: image lookup -v -s lookup_loclists -# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX, -# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = DW_OP_reg1 RDX, +# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX, +# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = , location = [0x0000000000000002, 0x0000000000000004) -> DW_OP_reg1 RDX, loclists: nop diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s @@ -6,8 +6,8 @@ # RUN: %lldb %t -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s # CHECK-LABEL: image lookup -v -s lookup_loclists -# CHECK: Variable: id = {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX, -# CHECK: Variable: id = {{.*}}, name = "x1", type = "int", location = DW_OP_reg1 RDX, +# CHECK: Variable: id = {{.*}}, name = "x0", type = "int", valid ranges = , location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX, +# CHECK: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = , location = [0x0000000000000002, 0x0000000000000004) -> DW_OP_reg1 RDX, ## This part is kept in both the main and the dwp file to be able to reference the offsets. loclists: diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s @@ -12,7 +12,7 @@ # CHECK-LABEL: image lookup -v -n F1 # CHECK: CompileUnit: id = {0x00000001}, file = "1.c", language = "" # CHECK: Function: {{.*}}, name = "F1", range = [0x0000000000000001-0x0000000000000002) -# CHECK: Variable: {{.*}}, name = "x", type = "int", location = DW_OP_reg1 RDX +# CHECK: Variable: {{.*}}, name = "x", type = "int", valid ranges = , location = [0x0000000000000001, 0x0000000000000002) -> DW_OP_reg1 RDX # SYMBOLS: Compile units: # SYMBOLS-NEXT: CompileUnit{0x00000000}, language = "", file = '0.c' diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test b/lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test --- a/lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test @@ -14,35 +14,35 @@ # at the inlined function entry. image lookup -v -s break_at_inlined_f_in_main # CHECK-LABEL: image lookup -v -s break_at_inlined_f_in_main -# CHECK: name = "unused1", type = "void *", location = -# CHECK: name = "used", type = "int", location = DW_OP_consts +42 -# CHECK: name = "unused2", type = "int", location = -# CHECK: name = "partial", type = "int", location = DW_OP_reg4 RSI -# CHECK: name = "unused3", type = "int", location = +# CHECK: name = "unused1", type = "void *", valid ranges = , location = +# CHECK: name = "used", type = "int", valid ranges = , location = [0x0000000000000011, 0x0000000000000014) -> DW_OP_consts +42 +# CHECK: name = "unused2", type = "int", valid ranges = , location = +# CHECK: name = "partial", type = "int", valid ranges = , location = [0x0000000000000011, 0x0000000000000019) -> DW_OP_reg4 RSI +# CHECK: name = "unused3", type = "int", valid ranges = , location = # Show variables outsid of the live range of the 'partial' parameter # and verify that the output is as expected. image lookup -v -s break_at_inlined_f_in_main_between_printfs # CHECK-LABEL: image lookup -v -s break_at_inlined_f_in_main_between_printfs -# CHECK: name = "unused1", type = "void *", location = -# CHECK: name = "used", type = "int", location = DW_OP_reg3 RBX -# CHECK: name = "unused2", type = "int", location = +# CHECK: name = "unused1", type = "void *", valid ranges = , location = +# CHECK: name = "used", type = "int", valid ranges = , location = [0x0000000000000014, 0x000000000000001e) -> DW_OP_reg3 RBX +# CHECK: name = "unused2", type = "int", valid ranges = , location = # Note: image lookup does not show variables outside of their # location, so |partial| is missing here. # CHECK-NOT: partial -# CHECK: name = "unused3", type = "int", location = +# CHECK: name = "unused3", type = "int", valid ranges = , location = # Check that we show parameters even if all of them are compiled away. image lookup -v -s break_at_inlined_g_in_main # CHECK-LABEL: image lookup -v -s break_at_inlined_g_in_main -# CHECK: name = "unused", type = "int", location = +# CHECK: name = "unused", type = "int", valid ranges = , location = # Check that even the other inlined instance of f displays the correct # parameters. image lookup -v -s break_at_inlined_f_in_other # CHECK-LABEL: image lookup -v -s break_at_inlined_f_in_other -# CHECK: name = "unused1", type = "void *", location = -# CHECK: name = "used", type = "int", location = DW_OP_consts +1 -# CHECK: name = "unused2", type = "int", location = -# CHECK: name = "partial", type = "int", location = DW_OP_consts +2 -# CHECK: name = "unused3", type = "int", location = +# CHECK: name = "unused1", type = "void *", valid ranges = , location = +# CHECK: name = "used", type = "int", valid ranges = , location = [0x0000000000000001, 0x000000000000000b) -> DW_OP_consts +1 +# CHECK: name = "unused2", type = "int", valid ranges = , location = +# CHECK: name = "partial", type = "int", valid ranges = , location = [0x0000000000000001, 0x0000000000000006) -> DW_OP_consts +2 +# CHECK: name = "unused3", type = "int", valid ranges = , location =