[Lldb-commits] [lldb] 15983c2 - [LLDB] Dump valid ranges of variables

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Wed Mar 2 13:44:27 PST 2022


Author: Zequan Wu
Date: 2022-03-02T13:44:19-08:00
New Revision: 15983c28aa819031e08a2b3fe49d02c41839b22c

URL: https://github.com/llvm/llvm-project/commit/15983c28aa819031e08a2b3fe49d02c41839b22c
DIFF: https://github.com/llvm/llvm-project/commit/15983c28aa819031e08a2b3fe49d02c41839b22c.diff

LOG: [LLDB] Dump valid ranges of variables

This allows `image lookup -a ... -v` to print variables only if the given
address is covered by the valid ranges of the variables. Since variables created
in dwarf plugin always has empty scope range, print the variable if it has
empty scope.

Differential Revision: https://reviews.llvm.org/D119963

Added: 
    

Modified: 
    lldb/include/lldb/Core/Address.h
    lldb/include/lldb/Expression/DWARFExpression.h
    lldb/include/lldb/Symbol/Variable.h
    lldb/source/Commands/CommandObjectTarget.cpp
    lldb/source/Commands/Options.td
    lldb/source/Core/Address.cpp
    lldb/source/Expression/DWARFExpression.cpp
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/source/Symbol/Variable.cpp
    lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s
    lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
    lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s
    lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
    lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s
    lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
    lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h
index f77ffc2fd25e6..4121f6c07ae2b 100644
--- a/lldb/include/lldb/Core/Address.h
+++ b/lldb/include/lldb/Core/Address.h
@@ -229,6 +229,14 @@ class Address {
   /// \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 @@ class Address {
   /// \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
index 1490ac2d614a8..96a0e8e02da13 100644
--- 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 <functional>
 
 class DWARFUnit;
@@ -55,18 +56,10 @@ class DWARFExpression {
   /// \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
-  ///     
diff erent 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 @@ class DWARFExpression {
                               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<bool(llvm::DWARFLocationExpression)> callback) const;
+
   bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
 
   llvm::Optional<DataExtractor>

diff  --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h
index ccd5072c3d234..88a975df39928 100644
--- a/lldb/include/lldb/Symbol/Variable.h
+++ b/lldb/include/lldb/Symbol/Variable.h
@@ -77,7 +77,9 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
 
   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
index 38aa841e50400..3af2c73b113cb 100644
--- 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 bool DumpModuleSymbolFile(Stream &strm, Module *module) {
 }
 
 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 @@ static void DumpAddress(ExecutionContextScope *exe_scope,
   // 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 void DumpAddress(ExecutionContextScope *exe_scope,
 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 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
 
     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 bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
 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 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
       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 uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
 
 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 @@ static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
 
       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 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
                                      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 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
       strm.PutCString(":\n");
       DumpSymbolContextList(
           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
-          strm, sc_list, verbose);
+          strm, sc_list, verbose, all_ranges);
     }
     return num_matches;
   }
@@ -1693,7 +1696,7 @@ static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
                                           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 @@ static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
       strm.PutCString(":\n");
       DumpSymbolContextList(
           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
-          strm, sc_list, verbose);
+          strm, sc_list, verbose, all_ranges);
       return num_matches;
     }
   }
@@ -3598,6 +3601,10 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
       case 'r':
         m_use_regex = true;
         break;
+
+      case '\x01':
+        m_all_ranges = true;
+        break;
       default:
         llvm_unreachable("Unimplemented option");
       }
@@ -3614,6 +3621,7 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
       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 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
     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 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
                     (m_options.m_verbose
                          ? static_cast<int>(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 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
       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 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
         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 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
         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
index 269c937296d5d..a1548cb6b443f 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -957,6 +957,9 @@ let Command = "target modules lookup" in {
   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
index 122bed924b420..0d4808a036d1d 100644
--- 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::GetDescription(Stream &s, Target &target,
 }
 
 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 Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
           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 = <unknown>");
-              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 = <unknown>");
+            s->PutCString(", valid ranges = ");
+            if (var_sp->GetScopeRange().IsEmpty())
+              s->PutCString("<block>");
+            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
index bcb23210f584d..572c3488311c7 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -129,7 +129,6 @@ class DummyDWARFObject final: public llvm::DWARFObject {
 }
 
 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 @@ static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc,
   return DataExtractor(buffer_sp, byte_order, addr_size);
 }
 
-llvm::Optional<DataExtractor>
-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<bool(llvm::DWARFLocationExpression)> callback) const {
+  if (load_function_start == LLDB_INVALID_ADDRESS)
+    return false;
+
   Log *log = GetLog(LLDBLog::Expressions);
 
   std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
       m_dwarf_cu->GetLocationTable(m_data);
-  llvm::Optional<DataExtractor> result;
+
   uint64_t offset = 0;
   auto lookup_addr =
       [&](uint32_t index) -> llvm::Optional<llvm::object::SectionedAddress> {
@@ -2700,19 +2735,32 @@ DWARFExpression::GetLocationExpression(addr_t load_function_start,
       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<DataExtractor>
+DWARFExpression::GetLocationExpression(addr_t load_function_start,
+                                       addr_t addr) const {
+  llvm::Optional<DataExtractor> 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 @@ bool DWARFExpression::MatchesOperand(StackFrame &frame,
     addr_t pc = frame.GetFrameCodeAddress().GetLoadAddress(
         frame.CalculateTarget().get());
 
-    if (llvm::Optional<DataExtractor> expr = GetLocationExpression(load_function_start, pc))
+    if (llvm::Optional<DataExtractor> 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
index 995215b208094..ffca5ca427529 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3923,7 +3923,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
       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 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
       for (const CallSiteParameter &param : 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
index 89682fc39141a..190fdbee9e842 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -147,23 +147,13 @@ void Variable::Dump(Stream *s, bool show_context) const {
 
   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 @@ Status Variable::GetValuesForVariableExpressionPath(
   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
index d83d0cb2bde3e..fa89a8f8b25a0 100644
--- 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 = <block>, 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
index 5b8d1bc328559..2daf816d300c8 100644
--- 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 = <block>, location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI, [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX
+# ALL-RANGES: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>
+# ALL-RANGES-LABEL: image lookup -v -a 2 -show-variable-ranges
+# ALL-RANGES:  Variable: id = {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI, [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX
+# ALL-RANGES: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>
+# ALL-RANGES: Variable: id = {{.*}}, name = "x3", type = "int", valid ranges = <block>, 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 = <empty>,
+# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI
+# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>,
 
 # 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 = <empty>,
-# CHECK: Variable: {{.*}}, name = "x3", type = "int", location = DW_OP_reg1 RDX,
+# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX
+# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>,
+# CHECK: Variable: {{.*}}, name = "x3", type = "int", valid ranges = <block>, 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
index 72de2b0c67823..25df188e3db7f 100644
--- 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 = <block>, 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 = <block>, 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
index 741db0b7df0f2..393c045456304 100644
--- 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 = <block>, location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX,
+# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = <block>, 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
index 2cc344a09325a..f96460d81a0fe 100644
--- 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 = <block>, location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX,
+# CHECK: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = <block>, 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
index cf23a2a3c585e..c5f89b04a18dc 100644
--- 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 = "<not loaded>"
 # 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 = <block>, location = [0x0000000000000001, 0x0000000000000002) -> DW_OP_reg1 RDX
 
 # SYMBOLS:      Compile units:
 # SYMBOLS-NEXT: CompileUnit{0x00000000}, language = "<not loaded>", 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
index e63ab80012532..5a1c777bf92cf 100644
--- 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 = <empty>
-# CHECK: name = "used", type = "int", location = DW_OP_consts +42
-# CHECK: name = "unused2", type = "int", location = <empty>
-# CHECK: name = "partial", type = "int", location = DW_OP_reg4 RSI
-# CHECK: name = "unused3", type = "int", location = <empty>
+# CHECK: name = "unused1", type = "void *", valid ranges = <block>, location = <empty>
+# CHECK: name = "used", type = "int", valid ranges = <block>, location = [0x0000000000000011, 0x0000000000000014) -> DW_OP_consts +42
+# CHECK: name = "unused2", type = "int", valid ranges = <block>, location = <empty>
+# CHECK: name = "partial", type = "int", valid ranges = <block>, location = [0x0000000000000011, 0x0000000000000019) -> DW_OP_reg4 RSI
+# CHECK: name = "unused3", type = "int", valid ranges = <block>, location = <empty>
 
 # 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 = <empty>
-# CHECK: name = "used", type = "int", location = DW_OP_reg3 RBX
-# CHECK: name = "unused2", type = "int", location = <empty>
+# CHECK: name = "unused1", type = "void *", valid ranges = <block>, location = <empty>
+# CHECK: name = "used", type = "int", valid ranges = <block>, location = [0x0000000000000014, 0x000000000000001e) -> DW_OP_reg3 RBX
+# CHECK: name = "unused2", type = "int", valid ranges = <block>, location = <empty>
 # 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 = <empty>
+# CHECK: name = "unused3", type = "int", valid ranges = <block>, location = <empty>
 
 # 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 = <empty>
+# CHECK: name = "unused", type = "int", valid ranges = <block>, location = <empty>
 
 # 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 = <empty>
-# CHECK: name = "used", type = "int", location = DW_OP_consts +1
-# CHECK: name = "unused2", type = "int", location = <empty>
-# CHECK: name = "partial", type = "int", location =  DW_OP_consts +2
-# CHECK: name = "unused3", type = "int", location = <empty>
+# CHECK: name = "unused1", type = "void *", valid ranges = <block>, location = <empty>
+# CHECK: name = "used", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x000000000000000b) -> DW_OP_consts +1
+# CHECK: name = "unused2", type = "int", valid ranges = <block>, location = <empty>
+# CHECK: name = "partial", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x0000000000000006) -> DW_OP_consts +2
+# CHECK: name = "unused3", type = "int", valid ranges = <block>, location = <empty>


        


More information about the lldb-commits mailing list