[Lldb-commits] [lldb] 227dffd - [LLDB][NFC] Decouple dwarf location table from DWARFExpression.
Zequan Wu via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 7 10:27:07 PDT 2022
Author: Zequan Wu
Date: 2022-07-07T10:26:58-07:00
New Revision: 227dffd0b6d78154516ace45f6ed28259c7baa48
URL: https://github.com/llvm/llvm-project/commit/227dffd0b6d78154516ace45f6ed28259c7baa48
DIFF: https://github.com/llvm/llvm-project/commit/227dffd0b6d78154516ace45f6ed28259c7baa48.diff
LOG: [LLDB][NFC] Decouple dwarf location table from DWARFExpression.
Differential Revision: https://reviews.llvm.org/D125509
Added:
lldb/include/lldb/Expression/DWARFExpressionList.h
lldb/source/Expression/DWARFExpressionList.cpp
Modified:
lldb/include/lldb/Expression/DWARFExpression.h
lldb/include/lldb/Symbol/Function.h
lldb/include/lldb/Symbol/Variable.h
lldb/include/lldb/Target/StackFrame.h
lldb/include/lldb/Utility/RangeMap.h
lldb/include/lldb/lldb-forward.h
lldb/source/Core/ValueObjectVariable.cpp
lldb/source/Expression/CMakeLists.txt
lldb/source/Expression/DWARFExpression.cpp
lldb/source/Expression/Materializer.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
lldb/source/Symbol/Function.cpp
lldb/source/Symbol/Variable.cpp
lldb/source/Target/RegisterContextUnwind.cpp
lldb/source/Target/StackFrame.cpp
lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
Removed:
################################################################################
diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 96a0e8e02da13..49e51d51f211c 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -42,49 +42,14 @@ class DWARFExpression {
/// \param[in] data
/// A data extractor configured to read the DWARF location expression's
/// bytecode.
- DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
- const DWARFUnit *dwarf_cu);
+ DWARFExpression(const DataExtractor &data);
/// Destructor
virtual ~DWARFExpression();
- /// Print the description of the expression to a stream
- ///
- /// \param[in] s
- /// The stream to print to.
- ///
- /// \param[in] level
- /// The level of verbosity to use.
- ///
- /// \param[in] abi
- /// An optional ABI plug-in that can be used to resolve register
- /// names.
- void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
-
/// Return true if the location expression contains data
bool IsValid() const;
- /// Return true if a location list was provided
- bool IsLocationList() const;
-
- /// Search for a load address in the location list
- ///
- /// \param[in] func_load_addr
- /// The actual address of the function containing this location list.
- ///
- /// \param[in] addr
- /// The address to resolve
- ///
- /// \return
- /// True if IsLocationList() is true and the address was found;
- /// false otherwise.
- // bool
- // LocationListContainsLoadAddress (Process* process, const Address &addr)
- // const;
- //
- bool LocationListContainsAddress(lldb::addr_t func_load_addr,
- lldb::addr_t addr) const;
-
/// If a location is not a location list, return true if the location
/// contains a DW_OP_addr () opcode in the stream that matches \a file_addr.
/// If file_addr is LLDB_INVALID_ADDRESS, the this function will return true
@@ -93,6 +58,9 @@ class DWARFExpression {
/// static variable since there is no other indication from DWARF debug
/// info.
///
+ /// \param[in] dwarf_cu
+ /// The dwarf unit this expression belongs to.
+ ///
/// \param[in] op_addr_idx
/// The DW_OP_addr index to retrieve in case there is more than
/// one DW_OP_addr opcode in the location byte stream.
@@ -104,36 +72,22 @@ class DWARFExpression {
/// \return
/// LLDB_INVALID_ADDRESS if the location doesn't contain a
/// DW_OP_addr for \a op_addr_idx, otherwise a valid file address
- lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const;
+ lldb::addr_t GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
+ uint32_t op_addr_idx, bool &error) const;
bool Update_DW_OP_addr(lldb::addr_t file_addr);
void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
uint8_t addr_byte_size);
- void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
-
bool ContainsThreadLocalStorage() const;
bool LinkThreadLocalStorage(
- lldb::ModuleSP new_module_sp,
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
&link_address_callback);
- /// Tells the expression that it refers to a location list.
- ///
- /// \param[in] cu_file_addr
- /// The base address to use for interpreting relative location list
- /// entries.
- /// \param[in] func_file_addr
- /// The file address of the function containing this location list. This
- /// address will be used to relocate the location list on the fly (in
- /// conjuction with the func_load_addr arguments).
- void SetLocationListAddresses(lldb::addr_t cu_file_addr,
- lldb::addr_t func_file_addr);
-
/// Return the call-frame-info style register kind
- int GetRegisterKind();
+ lldb::RegisterKind GetRegisterKind() const;
/// Set the call-frame-info style register kind
///
@@ -141,20 +95,6 @@ class DWARFExpression {
/// The register kind.
void SetRegisterKind(lldb::RegisterKind reg_kind);
- /// Wrapper for the static evaluate function that accepts an
- /// ExecutionContextScope instead of an ExecutionContext and uses member
- /// variables to populate many operands
- bool Evaluate(ExecutionContextScope *exe_scope, lldb::addr_t func_load_addr,
- const Value *initial_value_ptr, const Value *object_address_ptr,
- Value &result, Status *error_ptr) const;
-
- /// Wrapper for the static evaluate function that uses member variables to
- /// populate many operands
- bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
- lldb::addr_t loclist_base_load_addr,
- const Value *initial_value_ptr, const Value *object_address_ptr,
- Value &result, Status *error_ptr) const;
-
/// Evaluate a DWARF location expression in a particular context
///
/// \param[in] exe_ctx
@@ -194,72 +134,32 @@ class DWARFExpression {
/// True on success; false otherwise. If error_ptr is non-NULL,
/// details of the failure are provided through it.
static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
- lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
+ lldb::ModuleSP module_sp, const DataExtractor &opcodes,
const DWARFUnit *dwarf_cu,
const lldb::RegisterKind reg_set,
const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
Status *error_ptr);
+ static bool ParseDWARFLocationList(const DWARFUnit *dwarf_cu,
+ const DataExtractor &data,
+ DWARFExpressionList *loc_list);
+
bool GetExpressionData(DataExtractor &data) const {
data = m_data;
return data.GetByteSize() > 0;
}
- bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level,
- 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;
+ void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
- bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
-
- llvm::Optional<DataExtractor>
- GetLocationExpression(lldb::addr_t load_function_start,
- lldb::addr_t addr) const;
+ bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const;
private:
- /// Pretty-prints the location expression to a stream
- ///
- /// \param[in] s
- /// The stream to use for pretty-printing.
- ///
- /// \param[in] data
- /// The data extractor.
- ///
- /// \param[in] level
- /// The level of detail to use in pretty-printing.
- ///
- /// \param[in] abi
- /// An optional ABI plug-in that can be used to resolve register
- /// names.
- void DumpLocation(Stream *s, const DataExtractor &data,
- lldb::DescriptionLevel level, ABI *abi) const;
-
- /// Module which defined this expression.
- lldb::ModuleWP m_module_wp;
-
/// A data extractor capable of reading opcode bytes
DataExtractor m_data;
- /// The DWARF compile unit this expression belongs to. It is used to evaluate
- /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
- /// DW_OP_GNU_const_index)
- const DWARFUnit *m_dwarf_cu = nullptr;
-
/// One of the defines that starts with LLDB_REGKIND_
lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF;
-
- struct LoclistAddresses {
- lldb::addr_t cu_file_addr;
- lldb::addr_t func_file_addr;
- };
- llvm::Optional<LoclistAddresses> m_loclist_addresses;
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h b/lldb/include/lldb/Expression/DWARFExpressionList.h
new file mode 100644
index 0000000000000..34cd217b8fe4a
--- /dev/null
+++ b/lldb/include/lldb/Expression/DWARFExpressionList.h
@@ -0,0 +1,132 @@
+//===-- DWARFExpressionList.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
+#define LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
+
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Utility/RangeMap.h"
+#include "lldb/lldb-private.h"
+#include "llvm/ADT/Optional.h"
+
+class DWARFUnit;
+
+namespace lldb_private {
+
+/// \class DWARFExpressionList DWARFExpressionList.h
+/// "lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file
+/// address range to a single DWARF location expression.
+class DWARFExpressionList {
+public:
+ DWARFExpressionList() = default;
+
+ DWARFExpressionList(lldb::ModuleSP module_sp, const DWARFUnit *dwarf_cu)
+ : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu) {}
+
+ DWARFExpressionList(lldb::ModuleSP module_sp, DWARFExpression expr,
+ const DWARFUnit *dwarf_cu)
+ : DWARFExpressionList(module_sp, dwarf_cu) {
+ AddExpression(0, LLDB_INVALID_ADDRESS, expr);
+ }
+
+ /// Return true if the location expression contains data
+ bool IsValid() const { return !m_exprs.IsEmpty(); }
+
+ void Clear() { m_exprs.Clear(); }
+
+ // Return true if the location expression is always valid.
+ bool IsAlwaysValidSingleExpr() const;
+
+ bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr);
+
+ /// Get the expression data at the file address.
+ bool GetExpressionData(DataExtractor &data, lldb::addr_t file_addr = 0) const;
+
+ /// Sort m_expressions.
+ void Sort() { m_exprs.Sort(); }
+
+ const DWARFExpression *GetExpressionAtAddress(lldb::addr_t file_addr) const;
+
+ const DWARFExpression *GetAlwaysValidExpr() const {
+ return GetExpressionAtAddress(0);
+ }
+
+ DWARFExpression *GetMutableExpressionAtAddress(lldb::addr_t file_addr = 0);
+
+ size_t GetSize() const { return m_exprs.GetSize(); }
+
+ bool ContainsThreadLocalStorage() const;
+
+ bool LinkThreadLocalStorage(
+ lldb::ModuleSP new_module_sp,
+ std::function<lldb::addr_t(lldb::addr_t file_addr)> const
+ &link_address_callback);
+
+ bool MatchesOperand(StackFrame &frame,
+ const Instruction::Operand &operand) const;
+
+ /// Dump locations that contains file_addr if it's valid. Otherwise. dump all
+ /// locations.
+ bool DumpLocations(Stream *s, lldb::DescriptionLevel level,
+ lldb::addr_t file_addr, ABI *abi) const;
+
+ /// Dump all locaitons with each seperated by new line.
+ void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
+
+ /// Search for a load address in the location list
+ ///
+ /// \param[in] file_addr
+ /// The file address to resolve
+ ///
+ /// \return
+ /// True if IsLocationList() is true and the address was found;
+ /// false otherwise.
+ // bool
+ // LocationListContainsLoadAddress (Process* process, const Address &addr)
+ // const;
+ //
+ bool ContainsAddress(lldb::addr_t file_addr) const;
+
+ void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
+
+ bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
+ const Value *initial_value_ptr, const Value *object_address_ptr,
+ Value &result, Status *error_ptr) const;
+
+private:
+ // RangeDataVector requires a comparator for DWARFExpression, but it doesn't
+ // make sense to do so.
+ struct DWARFExpressionCompare {
+ public:
+ bool operator()(const DWARFExpression &lhs,
+ const DWARFExpression &rhs) const {
+ return false;
+ }
+ };
+ using ExprVec = RangeDataVector<lldb::addr_t, lldb::addr_t, DWARFExpression,
+ 0, DWARFExpressionCompare>;
+ using Entry = ExprVec::Entry;
+
+ // File address range mapping to single dwarf expression.
+ ExprVec m_exprs;
+
+ /// Module which defined this expression.
+ lldb::ModuleWP m_module_wp;
+
+ /// The DWARF compile unit this expression belongs to. It is used to evaluate
+ /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
+ /// DW_OP_GNU_const_index)
+ const DWARFUnit *m_dwarf_cu = nullptr;
+
+ using const_iterator = ExprVec::Collection::const_iterator;
+ const_iterator begin() const { return m_exprs.begin(); }
+ const_iterator end() const { return m_exprs.end(); }
+};
+} // namespace lldb_private
+
+#endif // LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h
index 83f9979c3c529..3eb4f5d7dedf4 100644
--- a/lldb/include/lldb/Symbol/Function.h
+++ b/lldb/include/lldb/Symbol/Function.h
@@ -12,7 +12,7 @@
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Declaration.h"
#include "lldb/Core/Mangled.h"
-#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Utility/UserID.h"
#include "llvm/ADT/ArrayRef.h"
@@ -253,8 +253,8 @@ class Function;
/// Represent the locations of a parameter at a call site, both in the caller
/// and in the callee.
struct CallSiteParameter {
- DWARFExpression LocationInCallee;
- DWARFExpression LocationInCaller;
+ DWARFExpressionList LocationInCallee;
+ DWARFExpressionList LocationInCaller;
};
/// A vector of \c CallSiteParameter.
@@ -370,7 +370,7 @@ class IndirectCallEdge : public CallEdge {
public:
/// Construct a call edge using a DWARFExpression to identify the callee, and
/// a return PC within the calling function to identify a specific call site.
- IndirectCallEdge(DWARFExpression call_target, AddrType caller_address_type,
+ IndirectCallEdge(DWARFExpressionList call_target, AddrType caller_address_type,
lldb::addr_t caller_address, bool is_tail_call,
CallSiteParameterArray &¶meters)
: CallEdge(caller_address_type, caller_address, is_tail_call,
@@ -383,7 +383,7 @@ class IndirectCallEdge : public CallEdge {
// Used to describe an indirect call.
//
// Specifies the location of the callee address in the calling frame.
- DWARFExpression call_target;
+ DWARFExpressionList call_target;
};
/// \class Function Function.h "lldb/Symbol/Function.h"
@@ -521,13 +521,13 @@ class Function : public UserID, public SymbolContextScope {
/// \return
/// A location expression that describes the function frame
/// base.
- DWARFExpression &GetFrameBaseExpression() { return m_frame_base; }
+ DWARFExpressionList &GetFrameBaseExpression() { return m_frame_base; }
/// Get const accessor for the frame base location.
///
/// \return
/// A const compile unit object pointer.
- const DWARFExpression &GetFrameBaseExpression() const { return m_frame_base; }
+ const DWARFExpressionList &GetFrameBaseExpression() const { return m_frame_base; }
ConstString GetName() const;
@@ -659,7 +659,7 @@ class Function : public UserID, public SymbolContextScope {
/// The frame base expression for variables that are relative to the frame
/// pointer.
- DWARFExpression m_frame_base;
+ DWARFExpressionList m_frame_base;
Flags m_flags;
diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h
index 88a975df39928..c437624d1ea6d 100644
--- a/lldb/include/lldb/Symbol/Variable.h
+++ b/lldb/include/lldb/Symbol/Variable.h
@@ -11,7 +11,7 @@
#include "lldb/Core/Declaration.h"
#include "lldb/Core/Mangled.h"
-#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/UserID.h"
@@ -32,8 +32,8 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
Variable(lldb::user_id_t uid, const char *name, const char *mangled,
const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope,
SymbolContextScope *owner_scope, const RangeList &scope_range,
- Declaration *decl, const DWARFExpression &location, bool external,
- bool artificial, bool location_is_constant_data,
+ Declaration *decl, const DWARFExpressionList &location,
+ bool external, bool artificial, bool location_is_constant_data,
bool static_member = false);
virtual ~Variable();
@@ -73,9 +73,11 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
bool IsStaticMember() const { return m_static_member; }
- DWARFExpression &LocationExpression() { return m_location; }
+ DWARFExpressionList &LocationExpressionList() { return m_location_list; }
- const DWARFExpression &LocationExpression() const { return m_location; }
+ const DWARFExpressionList &LocationExpressionList() const {
+ return m_location_list;
+ }
// When given invalid address, it dumps all locations. Otherwise it only dumps
// the location that contains this address.
@@ -128,7 +130,7 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
Declaration m_declaration;
/// The location of this variable that can be fed to
/// DWARFExpression::Evaluate().
- DWARFExpression m_location;
+ DWARFExpressionList m_location_list;
/// Visible outside the containing compile unit?
unsigned m_external : 1;
/// Non-zero if the variable is not explicitly declared in source.
diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h
index 1b0485b22cacb..7c4340de4de06 100644
--- a/lldb/include/lldb/Target/StackFrame.h
+++ b/lldb/include/lldb/Target/StackFrame.h
@@ -202,7 +202,7 @@ class StackFrame : public ExecutionContextScope,
/// frames may be unable to provide this value; they will return false.
bool GetFrameBaseValue(Scalar &value, Status *error_ptr);
- /// Get the DWARFExpression corresponding to the Canonical Frame Address.
+ /// Get the DWARFExpressionList corresponding to the Canonical Frame Address.
///
/// Often a register (bp), but sometimes a register + offset.
///
@@ -212,7 +212,7 @@ class StackFrame : public ExecutionContextScope,
///
/// \return
/// Returns the corresponding DWARF expression, or NULL.
- DWARFExpression *GetFrameBaseExpression(Status *error_ptr);
+ DWARFExpressionList *GetFrameBaseExpression(Status *error_ptr);
/// Get the current lexical scope block for this StackFrame, if possible.
///
diff --git a/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h
index 7eb0cab8084c7..257b177c70927 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -627,6 +627,10 @@ class RangeDataVector {
return (m_entries.empty() ? nullptr : &m_entries.back());
}
+ using const_iterator = typename Collection::const_iterator;
+ const_iterator begin() const { return m_entries.begin(); }
+ const_iterator end() const { return m_entries.end(); }
+
protected:
Collection m_entries;
Compare m_compare;
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 487b2f20792b9..c51e1850338ff 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -66,6 +66,7 @@ class ConstStringTable;
class DWARFCallFrameInfo;
class DWARFDataExtractor;
class DWARFExpression;
+class DWARFExpressionList;
class DataBuffer;
class WritableDataBuffer;
class DataBufferHeap;
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index 8e89503a8a76b..7f0e86b9294da 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -13,7 +13,7 @@
#include "lldb/Core/Declaration.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -127,22 +127,20 @@ bool ValueObjectVariable::UpdateValue() {
m_error.Clear();
Variable *variable = m_variable_sp.get();
- DWARFExpression &expr = variable->LocationExpression();
+ DWARFExpressionList &expr_list = variable->LocationExpressionList();
if (variable->GetLocationIsConstantValueData()) {
// expr doesn't contain DWARF bytes, it contains the constant variable
// value bytes themselves...
- if (expr.GetExpressionData(m_data)) {
- if (m_data.GetDataStart() && m_data.GetByteSize())
+ if (expr_list.GetExpressionData(m_data)) {
+ if (m_data.GetDataStart() && m_data.GetByteSize())
m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
m_value.SetContext(Value::ContextType::Variable, variable);
- }
- else
+ } else
m_error.SetErrorString("empty constant data");
// constant bytes can't be edited - sorry
m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
} else {
- lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
ExecutionContext exe_ctx(GetExecutionContextRef());
Target *target = exe_ctx.GetTargetPtr();
@@ -151,17 +149,8 @@ bool ValueObjectVariable::UpdateValue() {
m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
}
- if (expr.IsLocationList()) {
- SymbolContext sc;
- variable->CalculateSymbolContext(&sc);
- if (sc.function)
- loclist_base_load_addr =
- sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
- target);
- }
Value old_value(m_value);
- if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
- nullptr, m_value, &m_error)) {
+ if (expr_list.Evaluate(&exe_ctx, nullptr, nullptr, nullptr, m_value, &m_error)) {
m_resolved_value = m_value;
m_value.SetContext(Value::ContextType::Variable, variable);
@@ -246,7 +235,7 @@ bool ValueObjectVariable::UpdateValue() {
m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
}
}
-
+
return m_error.Success();
}
diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt
index c935e1b1c04b9..54414fb2a7c4f 100644
--- a/lldb/source/Expression/CMakeLists.txt
+++ b/lldb/source/Expression/CMakeLists.txt
@@ -1,6 +1,7 @@
add_lldb_library(lldbExpression
DiagnosticManager.cpp
DWARFExpression.cpp
+ DWARFExpressionList.cpp
Expression.cpp
ExpressionVariable.cpp
FunctionCaller.cpp
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 1f11907dc64c4..fff5f60bc3abf 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -45,29 +45,10 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
-static lldb::addr_t
-ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu,
- uint32_t index) {
- uint32_t index_size = dwarf_cu->GetAddressByteSize();
- dw_offset_t addr_base = dwarf_cu->GetAddrBase();
- lldb::offset_t offset = addr_base + index * index_size;
- const DWARFDataExtractor &data =
- dwarf_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadAddrData();
- if (data.ValidOffsetForDataOfSize(offset, index_size))
- return data.GetMaxU64_unchecked(&offset, index_size);
- return LLDB_INVALID_ADDRESS;
-}
-
// DWARFExpression constructor
-DWARFExpression::DWARFExpression() : m_module_wp(), m_data() {}
-
-DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp,
- const DataExtractor &data,
- const DWARFUnit *dwarf_cu)
- : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu) {
- if (module_sp)
- m_module_wp = module_sp;
-}
+DWARFExpression::DWARFExpression() : m_data() {}
+
+DWARFExpression::DWARFExpression(const DataExtractor &data) : m_data(data) {}
// Destructor
DWARFExpression::~DWARFExpression() = default;
@@ -86,71 +67,19 @@ void DWARFExpression::UpdateValue(uint64_t const_value,
m_data.SetAddressByteSize(addr_byte_size);
}
-void DWARFExpression::DumpLocation(Stream *s, const DataExtractor &data,
- lldb::DescriptionLevel level,
+void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
ABI *abi) const {
- llvm::DWARFExpression(data.GetAsLLVM(), data.GetAddressByteSize())
+ llvm::DWARFExpression(m_data.GetAsLLVM(), m_data.GetAddressByteSize())
.print(s->AsRawOstream(), llvm::DIDumpOptions(),
abi ? &abi->GetMCRegisterInfo() : nullptr, nullptr);
}
-void DWARFExpression::SetLocationListAddresses(addr_t cu_file_addr,
- addr_t func_file_addr) {
- m_loclist_addresses = LoclistAddresses{cu_file_addr, func_file_addr};
-}
-
-int DWARFExpression::GetRegisterKind() { return m_reg_kind; }
+RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {
m_reg_kind = reg_kind;
}
-bool DWARFExpression::IsLocationList() const {
- return bool(m_loclist_addresses);
-}
-
-namespace {
-/// Implement enough of the DWARFObject interface in order to be able to call
-/// DWARFLocationTable::dumpLocationList. We don't have access to a real
-/// DWARFObject here because DWARFExpression is used in non-DWARF scenarios too.
-class DummyDWARFObject final: public llvm::DWARFObject {
-public:
- DummyDWARFObject(bool IsLittleEndian) : IsLittleEndian(IsLittleEndian) {}
-
- bool isLittleEndian() const override { return IsLittleEndian; }
-
- llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
- uint64_t Pos) const override {
- return llvm::None;
- }
-private:
- bool IsLittleEndian;
-};
-}
-
-void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level,
- ABI *abi) const {
- if (IsLocationList()) {
- // We have a location list
- lldb::offset_t offset = 0;
- std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
- m_dwarf_cu->GetLocationTable(m_data);
-
- llvm::MCRegisterInfo *MRI = abi ? &abi->GetMCRegisterInfo() : nullptr;
- llvm::DIDumpOptions DumpOpts;
- DumpOpts.RecoverableErrorHandler = [&](llvm::Error E) {
- s->AsRawOstream() << "error: " << toString(std::move(E));
- };
- loctable_up->dumpLocationList(
- &offset, s->AsRawOstream(),
- llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, MRI,
- DummyDWARFObject(m_data.GetByteOrder() == eByteOrderLittle), nullptr,
- DumpOpts, s->GetIndentLevel() + 2);
- } else {
- // We have a normal location that contains DW_OP location opcodes
- DumpLocation(s, m_data, level, abi);
- }
-}
static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
lldb::RegisterKind reg_kind,
@@ -409,11 +338,10 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data,
return LLDB_INVALID_OFFSET;
}
-lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx,
+lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
+ uint32_t op_addr_idx,
bool &error) const {
error = false;
- if (IsLocationList())
- return LLDB_INVALID_ADDRESS;
lldb::offset_t offset = 0;
uint32_t curr_op_addr_idx = 0;
while (m_data.ValidOffset(offset)) {
@@ -423,19 +351,18 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx,
const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
if (curr_op_addr_idx == op_addr_idx)
return op_file_addr;
- else
- ++curr_op_addr_idx;
+ ++curr_op_addr_idx;
} else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {
uint64_t index = m_data.GetULEB128(&offset);
if (curr_op_addr_idx == op_addr_idx) {
- if (!m_dwarf_cu) {
+ if (!dwarf_cu) {
error = true;
break;
}
- return ReadAddressFromDebugAddrSection(m_dwarf_cu, index);
- } else
- ++curr_op_addr_idx;
+ return dwarf_cu->ReadAddressFromDebugAddrSection(index);
+ }
+ ++curr_op_addr_idx;
} else {
const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
if (op_arg_size == LLDB_INVALID_OFFSET) {
@@ -449,8 +376,6 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx,
}
bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
- if (IsLocationList())
- return false;
lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset)) {
const uint8_t op = m_data.GetU8(&offset);
@@ -487,11 +412,6 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
}
bool DWARFExpression::ContainsThreadLocalStorage() const {
- // We are assuming for now that any thread local variable will not have a
- // location list. This has been true for all thread local variables we have
- // seen so far produced by any compiler.
- if (IsLocationList())
- return false;
lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset)) {
const uint8_t op = m_data.GetU8(&offset);
@@ -501,27 +421,18 @@ bool DWARFExpression::ContainsThreadLocalStorage() const {
const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
if (op_arg_size == LLDB_INVALID_OFFSET)
return false;
- else
- offset += op_arg_size;
+ offset += op_arg_size;
}
return false;
}
bool DWARFExpression::LinkThreadLocalStorage(
- lldb::ModuleSP new_module_sp,
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
&link_address_callback) {
- // We are assuming for now that any thread local variable will not have a
- // location list. This has been true for all thread local variables we have
- // seen so far produced by any compiler.
- if (IsLocationList())
- return false;
-
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
// We have to make a copy of the data as we don't know if this data is from a
// read only memory mapped buffer, so we duplicate all of the data first,
// then modify it, and if all goes well, we then replace the data for this
// expression.
-
// Make en encoder that contains a copy of the location expression data so we
// can write the address into the buffer using the correct byte order.
DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
@@ -593,42 +504,10 @@ bool DWARFExpression::LinkThreadLocalStorage(
}
}
- // If we linked the TLS address correctly, update the module so that when the
- // expression is evaluated it can resolve the file address to a load address
- // and read the
- // TLS data
- m_module_wp = new_module_sp;
m_data.SetData(encoder.GetDataBuffer());
return true;
}
-bool DWARFExpression::LocationListContainsAddress(addr_t func_load_addr,
- lldb::addr_t addr) const {
- if (func_load_addr == LLDB_INVALID_ADDRESS || addr == LLDB_INVALID_ADDRESS)
- return false;
-
- if (!IsLocationList())
- return false;
-
- return GetLocationExpression(func_load_addr, addr) != llvm::None;
-}
-
-bool DWARFExpression::DumpLocationForAddress(Stream *s,
- lldb::DescriptionLevel level,
- addr_t func_load_addr,
- addr_t address, ABI *abi) {
- if (!IsLocationList()) {
- DumpLocation(s, m_data, level, abi);
- return true;
- }
- if (llvm::Optional<DataExtractor> expr =
- GetLocationExpression(func_load_addr, address)) {
- DumpLocation(s, *expr, level, abi);
- return true;
- }
- return false;
-}
-
static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
ExecutionContext *exe_ctx,
RegisterContext *reg_ctx,
@@ -824,10 +703,9 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
// TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value
// subexpresion whenever llvm does.
Value result;
- const DWARFExpression ¶m_expr = matched_param->LocationInCaller;
+ const DWARFExpressionList ¶m_expr = matched_param->LocationInCaller;
if (!param_expr.Evaluate(&parent_exe_ctx,
parent_frame->GetRegisterContext().get(),
- /*loclist_base_load_addr=*/LLDB_INVALID_ADDRESS,
/*initial_value_ptr=*/nullptr,
/*object_address_ptr=*/nullptr, result, error_ptr)) {
LLDB_LOG(log,
@@ -839,63 +717,6 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
return true;
}
-bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope,
- lldb::addr_t loclist_base_load_addr,
- const Value *initial_value_ptr,
- const Value *object_address_ptr, Value &result,
- Status *error_ptr) const {
- ExecutionContext exe_ctx(exe_scope);
- return Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, initial_value_ptr,
- object_address_ptr, result, error_ptr);
-}
-
-bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
- RegisterContext *reg_ctx,
- lldb::addr_t func_load_addr,
- const Value *initial_value_ptr,
- const Value *object_address_ptr, Value &result,
- Status *error_ptr) const {
- ModuleSP module_sp = m_module_wp.lock();
-
- if (IsLocationList()) {
- Address pc;
- StackFrame *frame = nullptr;
- if (!reg_ctx || !reg_ctx->GetPCForSymbolication(pc)) {
- frame = exe_ctx->GetFramePtr();
- if (!frame)
- return false;
- RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
- if (!reg_ctx_sp)
- return false;
- reg_ctx_sp->GetPCForSymbolication(pc);
- }
-
- if (func_load_addr != LLDB_INVALID_ADDRESS) {
- if (!pc.IsValid()) {
- if (error_ptr)
- error_ptr->SetErrorString("Invalid PC in frame.");
- return false;
- }
-
- Target *target = exe_ctx->GetTargetPtr();
- if (llvm::Optional<DataExtractor> expr = GetLocationExpression(
- func_load_addr, pc.GetLoadAddress(target))) {
- return DWARFExpression::Evaluate(
- exe_ctx, reg_ctx, module_sp, *expr, m_dwarf_cu, m_reg_kind,
- initial_value_ptr, object_address_ptr, result, error_ptr);
- }
- }
- if (error_ptr)
- error_ptr->SetErrorString("variable not available");
- return false;
- }
-
- // Not a location list, just a single expression.
- return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, m_data,
- m_dwarf_cu, m_reg_kind, initial_value_ptr,
- object_address_ptr, result, error_ptr);
-}
-
namespace {
/// The location description kinds described by the DWARF v5
/// specification. Composite locations are handled out-of-band and
@@ -2670,7 +2491,7 @@ bool DWARFExpression::Evaluate(
return false;
}
uint64_t index = opcodes.GetULEB128(&offset);
- lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
+ lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
stack.push_back(Scalar(value));
stack.back().SetValueType(Value::ValueType::FileAddress);
} break;
@@ -2690,7 +2511,7 @@ bool DWARFExpression::Evaluate(
return false;
}
uint64_t index = opcodes.GetULEB128(&offset);
- lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
+ lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
stack.push_back(Scalar(value));
} break;
@@ -2743,61 +2564,16 @@ bool DWARFExpression::Evaluate(
return true; // Return true on success
}
-static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc,
- ByteOrder byte_order, uint32_t addr_size) {
- auto buffer_sp =
- std::make_shared<DataBufferHeap>(loc.Expr.data(), loc.Expr.size());
- return DataExtractor(buffer_sp, byte_order, addr_size);
-}
-
-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);
-
+bool DWARFExpression::ParseDWARFLocationList(
+ const DWARFUnit *dwarf_cu, const DataExtractor &data,
+ DWARFExpressionList *location_list) {
+ location_list->Clear();
std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
- m_dwarf_cu->GetLocationTable(m_data);
-
- uint64_t offset = 0;
+ dwarf_cu->GetLocationTable(data);
+ Log *log = GetLog(LLDBLog::Expressions);
auto lookup_addr =
[&](uint32_t index) -> llvm::Optional<llvm::object::SectionedAddress> {
- addr_t address = ReadAddressFromDebugAddrSection(m_dwarf_cu, index);
+ addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index);
if (address == LLDB_INVALID_ADDRESS)
return llvm::None;
return llvm::object::SectionedAddress{address};
@@ -2807,18 +2583,17 @@ bool DWARFExpression::GetLocationExpressions(
LLDB_LOG_ERROR(log, loc.takeError(), "{0}");
return true;
}
- if (loc->Range) {
- // This relocates low_pc and high_pc by adding the
diff erence between the
- // function file address, and the actual address it is loaded in memory.
- addr_t slide = load_function_start - m_loclist_addresses->func_file_addr;
- loc->Range->LowPC += slide;
- loc->Range->HighPC += slide;
- }
- return callback(*loc);
+ auto buffer_sp =
+ std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size());
+ DWARFExpression expr = DWARFExpression(DataExtractor(
+ buffer_sp, data.GetByteOrder(), data.GetAddressByteSize()));
+ location_list->AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr);
+ return true;
};
llvm::Error error = loctable_up->visitAbsoluteLocationList(
- offset, llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr},
+ 0, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()},
lookup_addr, process_list);
+ location_list->Sort();
if (error) {
LLDB_LOG_ERROR(log, std::move(error), "{0}");
return false;
@@ -2826,23 +2601,8 @@ bool DWARFExpression::GetLocationExpressions(
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,
- const Instruction::Operand &operand) {
+bool DWARFExpression::MatchesOperand(
+ StackFrame &frame, const Instruction::Operand &operand) const {
using namespace OperandMatchers;
RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
@@ -2850,28 +2610,7 @@ bool DWARFExpression::MatchesOperand(StackFrame &frame,
return false;
}
- DataExtractor opcodes;
- if (IsLocationList()) {
- SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction);
- if (!sc.function)
- return false;
-
- addr_t load_function_start =
- sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
- if (load_function_start == LLDB_INVALID_ADDRESS)
- return false;
-
- addr_t pc = frame.GetFrameCodeAddressForSymbolication().GetLoadAddress(
- frame.CalculateTarget().get());
-
- if (llvm::Optional<DataExtractor> expr =
- GetLocationExpression(load_function_start, pc))
- opcodes = std::move(*expr);
- else
- return false;
- } else
- opcodes = m_data;
-
+ DataExtractor opcodes(m_data);
lldb::offset_t op_offset = 0;
uint8_t opcode = opcodes.GetU8(&op_offset);
@@ -2879,7 +2618,7 @@ bool DWARFExpression::MatchesOperand(StackFrame &frame,
if (opcode == DW_OP_fbreg) {
int64_t offset = opcodes.GetSLEB128(&op_offset);
- DWARFExpression *fb_expr = frame.GetFrameBaseExpression(nullptr);
+ DWARFExpressionList *fb_expr = frame.GetFrameBaseExpression(nullptr);
if (!fb_expr) {
return false;
}
diff --git a/lldb/source/Expression/DWARFExpressionList.cpp b/lldb/source/Expression/DWARFExpressionList.cpp
new file mode 100644
index 0000000000000..e13a2931644be
--- /dev/null
+++ b/lldb/source/Expression/DWARFExpressionList.cpp
@@ -0,0 +1,216 @@
+//===-- DWARFExpressionList.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Expression/DWARFExpressionList.h"
+#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+bool DWARFExpressionList::IsAlwaysValidSingleExpr() const {
+ if (m_exprs.GetSize() != 1)
+ return false;
+ const Entry expr = m_exprs.GetEntryRef(0);
+ return expr.base == 0 && expr.size == LLDB_INVALID_ADDRESS;
+}
+
+bool DWARFExpressionList::AddExpression(addr_t base, addr_t end,
+ DWARFExpression expr) {
+ if (IsAlwaysValidSingleExpr() || base >= end)
+ return false;
+ m_exprs.Append({base, end - base, expr});
+ return true;
+}
+
+bool DWARFExpressionList::GetExpressionData(DataExtractor &data,
+ lldb::addr_t file_addr) const {
+ if (const DWARFExpression *expr = GetExpressionAtAddress(file_addr))
+ return expr->GetExpressionData(data);
+ return false;
+}
+
+bool DWARFExpressionList::ContainsAddress(lldb::addr_t file_addr) const {
+ return m_exprs.FindEntryThatContains(file_addr) != nullptr;
+}
+
+const DWARFExpression *
+DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t file_addr) const {
+ uint32_t index = m_exprs.FindEntryIndexThatContains(file_addr);
+ if (index == UINT32_MAX)
+ return nullptr;
+ return &m_exprs.GetEntryAtIndex(index)->data;
+}
+
+DWARFExpression *
+DWARFExpressionList::GetMutableExpressionAtAddress(lldb::addr_t file_addr) {
+ uint32_t index = m_exprs.FindEntryIndexThatContains(file_addr);
+ if (index == UINT32_MAX)
+ return nullptr;
+ return &m_exprs.GetMutableEntryAtIndex(index)->data;
+}
+
+bool DWARFExpressionList::ContainsThreadLocalStorage() const {
+ // We are assuming for now that any thread local variable will not have a
+ // location list. This has been true for all thread local variables we have
+ // seen so far produced by any compiler.
+ if (!IsAlwaysValidSingleExpr())
+ return false;
+
+ const DWARFExpression &expr = m_exprs.GetEntryRef(0).data;
+ return expr.ContainsThreadLocalStorage();
+}
+
+bool DWARFExpressionList::LinkThreadLocalStorage(
+ lldb::ModuleSP new_module_sp,
+ std::function<lldb::addr_t(lldb::addr_t file_addr)> const
+ &link_address_callback) {
+ // We are assuming for now that any thread local variable will not have a
+ // location list. This has been true for all thread local variables we have
+ // seen so far produced by any compiler.
+ if (!IsAlwaysValidSingleExpr())
+ return false;
+
+ DWARFExpression &expr = m_exprs.GetEntryRef(0).data;
+ // If we linked the TLS address correctly, update the module so that when the
+ // expression is evaluated it can resolve the file address to a load address
+ // and read the TLS data
+ if (expr.LinkThreadLocalStorage(link_address_callback))
+ m_module_wp = new_module_sp;
+ return true;
+}
+
+bool DWARFExpressionList::MatchesOperand(
+ StackFrame &frame, const Instruction::Operand &operand) const {
+ RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
+ if (!reg_ctx_sp) {
+ return false;
+ }
+ const DWARFExpression *expr = nullptr;
+ if (IsAlwaysValidSingleExpr())
+ expr = &m_exprs.GetEntryAtIndex(0)->data;
+ else {
+ SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction);
+ if (!sc.function)
+ return false;
+
+ addr_t load_function_start =
+ sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
+ if (load_function_start == LLDB_INVALID_ADDRESS)
+ return false;
+
+ addr_t pc = frame.GetFrameCodeAddressForSymbolication().GetFileAddress();
+ expr = GetExpressionAtAddress(pc);
+ }
+ if (!expr)
+ return false;
+ return expr->MatchesOperand(frame, operand);
+}
+
+bool DWARFExpressionList::DumpLocations(Stream *s, lldb::DescriptionLevel level,
+ lldb::addr_t file_addr,
+ ABI *abi) const {
+ llvm::raw_ostream &os = s->AsRawOstream();
+ llvm::ListSeparator separator;
+ for (const Entry &entry : *this) {
+ if (file_addr != LLDB_INVALID_ADDRESS &&
+ (file_addr < entry.GetRangeBase() || file_addr >= entry.GetRangeEnd()))
+ continue;
+ const auto &expr = entry.data;
+ DataExtractor data;
+ expr.GetExpressionData(data);
+ uint32_t addr_size = data.GetAddressByteSize();
+ if (entry.GetRangeEnd() == LLDB_INVALID_ADDRESS) {
+ expr.DumpLocation(s, level, abi);
+ break;
+ }
+
+ os << separator;
+ os << "[";
+ os << llvm::format_hex(entry.GetRangeBase(), 2 + 2 * addr_size);
+ os << ", ";
+ os << llvm::format_hex(entry.GetRangeEnd(), 2 + 2 * addr_size);
+ os << ") -> ";
+ expr.DumpLocation(s, level, abi);
+ if (file_addr != LLDB_INVALID_ADDRESS)
+ break;
+ }
+ return true;
+}
+
+void DWARFExpressionList::GetDescription(Stream *s,
+ lldb::DescriptionLevel level,
+ ABI *abi) const {
+ llvm::raw_ostream &os = s->AsRawOstream();
+ if (IsAlwaysValidSingleExpr()) {
+ m_exprs.Back()->data.DumpLocation(s, level, abi);
+ return;
+ }
+ os << llvm::format("0x%8.8" PRIx64 ": ", 0);
+ for (const Entry &entry : *this) {
+ const auto &expr = entry.data;
+ DataExtractor data;
+ expr.GetExpressionData(data);
+ uint32_t addr_size = data.GetAddressByteSize();
+ os << "\n";
+ os.indent(s->GetIndentLevel() + 2);
+ os << "[";
+ llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeBase());
+ os << ", ";
+ llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeEnd());
+ os << "): ";
+ expr.DumpLocation(s, level, abi);
+ }
+}
+
+bool DWARFExpressionList::Evaluate(ExecutionContext *exe_ctx,
+ RegisterContext *reg_ctx,
+ const Value *initial_value_ptr,
+ const Value *object_address_ptr,
+ Value &result, Status *error_ptr) const {
+ ModuleSP module_sp = m_module_wp.lock();
+ DataExtractor data;
+ RegisterKind reg_kind;
+ DWARFExpression expr;
+ if (IsAlwaysValidSingleExpr()) {
+ expr = m_exprs.Back()->data;
+ } else {
+ Address pc;
+ StackFrame *frame = nullptr;
+ if (!reg_ctx || !reg_ctx->GetPCForSymbolication(pc)) {
+ if (exe_ctx)
+ frame = exe_ctx->GetFramePtr();
+ if (!frame)
+ return false;
+ RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
+ if (!reg_ctx_sp)
+ return false;
+ reg_ctx_sp->GetPCForSymbolication(pc);
+ }
+
+ if (!pc.IsValid()) {
+ if (error_ptr)
+ error_ptr->SetErrorString("Invalid PC in frame.");
+ return false;
+ }
+ addr_t addr = pc.GetFileAddress();
+ const auto *entry = m_exprs.FindEntryThatContains(addr);
+ if (!entry)
+ return false;
+ expr = entry->data;
+ }
+ expr.GetExpressionData(data);
+ reg_kind = expr.GetRegisterKind();
+ return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, data,
+ m_dwarf_cu, reg_kind, initial_value_ptr,
+ object_address_ptr, result, error_ptr);
+}
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 9ee2d983ddfc6..965a96b7f909d 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -520,7 +520,7 @@ class EntityVariable : public Materializer::Entity {
if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize(scope)) {
if (data.GetByteSize() == 0 &&
- !m_variable_sp->LocationExpression().IsValid()) {
+ !m_variable_sp->LocationExpressionList().IsValid()) {
err.SetErrorStringWithFormat("the variable '%s' has no location, "
"it may have been optimized out",
m_variable_sp->GetName().AsCString());
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index cc45871bcd71a..6fb7d92244f90 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1485,15 +1485,14 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
return false;
}
- DWARFExpression &var_location_expr = var->LocationExpression();
+ DWARFExpressionList &var_location_list = var->LocationExpressionList();
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Status err;
if (var->GetLocationIsConstantValueData()) {
DataExtractor const_value_extractor;
-
- if (var_location_expr.GetExpressionData(const_value_extractor)) {
+ if (var_location_list.GetExpressionData(const_value_extractor)) {
var_location = Value(const_value_extractor.GetDataStart(),
const_value_extractor.GetByteSize());
var_location.SetValueType(Value::ValueType::HostAddress);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 2aacac3692be5..4b9354371bda3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2292,7 +2292,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
int call_file = 0;
int call_line = 0;
int call_column = 0;
- DWARFExpression frame_base;
+ DWARFExpressionList frame_base;
const dw_tag_t tag = die.Tag();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index ec074be581b54..06cdd877f7dcd 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -441,7 +441,7 @@ bool DWARFDIE::GetDIENamesAndRanges(
const char *&name, const char *&mangled, DWARFRangeList &ranges,
int &decl_file, int &decl_line, int &decl_column, int &call_file,
int &call_line, int &call_column,
- lldb_private::DWARFExpression *frame_base) const {
+ lldb_private::DWARFExpressionList *frame_base) const {
if (IsValid()) {
return m_die->GetDIENamesAndRanges(
GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 5ee44a7632049..7ce9550a081e9 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -85,11 +85,12 @@ class DWARFDIE : public DWARFBaseDIE {
DWARFDIE
GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
- bool GetDIENamesAndRanges(const char *&name, const char *&mangled,
- DWARFRangeList &ranges, int &decl_file,
- int &decl_line, int &decl_column, int &call_file,
- int &call_line, int &call_column,
- lldb_private::DWARFExpression *frame_base) const;
+ bool
+ GetDIENamesAndRanges(const char *&name, const char *&mangled,
+ DWARFRangeList &ranges, int &decl_file, int &decl_line,
+ int &decl_column, int &call_file, int &call_line,
+ int &call_column,
+ lldb_private::DWARFExpressionList *frame_base) const;
/// The range of all the children of this DIE.
llvm::iterator_range<child_iterator> children() const;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 95c0cb6472c59..c1d49c5f23d7c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -231,11 +231,10 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
DWARFUnit *cu, const char *&name, const char *&mangled,
DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
int &call_file, int &call_line, int &call_column,
- DWARFExpression *frame_base) const {
+ DWARFExpressionList *frame_base) const {
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
std::vector<DWARFDIE> dies;
- bool set_frame_base_loclist_addr = false;
const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
@@ -345,21 +344,17 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- *frame_base = DWARFExpression(
- module, DataExtractor(data, block_offset, block_length), cu);
+ *frame_base =
+ DWARFExpressionList(module,
+ DWARFExpression(DataExtractor(
+ data, block_offset, block_length)),
+ cu);
} else {
DataExtractor data = cu->GetLocationData();
const dw_offset_t offset = form_value.Unsigned();
if (data.ValidOffset(offset)) {
data = DataExtractor(data, offset, data.GetByteSize() - offset);
- *frame_base = DWARFExpression(module, data, cu);
- if (lo_pc != LLDB_INVALID_ADDRESS) {
- assert(lo_pc >= cu->GetBaseAddress());
- frame_base->SetLocationListAddresses(cu->GetBaseAddress(),
- lo_pc);
- } else {
- set_frame_base_loclist_addr = true;
- }
+ DWARFExpression::ParseDWARFLocationList(cu, data, frame_base);
}
}
}
@@ -381,12 +376,6 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
}
}
- if (set_frame_base_loclist_addr) {
- dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
- assert(lowest_range_pc >= cu->GetBaseAddress());
- frame_base->SetLocationListAddresses(cu->GetBaseAddress(), lowest_range_pc);
- }
-
if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
for (const DWARFDIE &die : dies) {
if (die) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 64e86c71ac09e..32f653e99a705 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -104,7 +104,7 @@ class DWARFDebugInfoEntry {
DWARFUnit *cu, const char *&name, const char *&mangled,
DWARFRangeList &rangeList, int &decl_file, int &decl_line,
int &decl_column, int &call_file, int &call_line, int &call_column,
- lldb_private::DWARFExpression *frame_base = nullptr) const;
+ lldb_private::DWARFExpressionList *frame_base = nullptr) const;
const DWARFAbbreviationDeclaration *
GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 903cd2e38f769..7b4a5d8eca3ed 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -579,6 +579,17 @@ void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) {
m_str_offsets_base = str_offsets_base;
}
+dw_addr_t DWARFUnit::ReadAddressFromDebugAddrSection(uint32_t index) const {
+ uint32_t index_size = GetAddressByteSize();
+ dw_offset_t addr_base = GetAddrBase();
+ dw_addr_t offset = addr_base + index * index_size;
+ const DWARFDataExtractor &data =
+ m_dwarf.GetDWARFContext().getOrLoadAddrData();
+ if (data.ValidOffsetForDataOfSize(offset, index_size))
+ return data.GetMaxU64_unchecked(&offset, index_size);
+ return LLDB_INVALID_ADDRESS;
+}
+
// It may be called only with m_die_array_mutex held R/W.
void DWARFUnit::ClearDIEsRWLocked() {
m_die_array.clear();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 265e28b51c991..40a1943b847a0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -166,6 +166,8 @@ class DWARFUnit : public lldb_private::UserID {
void SetStrOffsetsBase(dw_offset_t str_offsets_base);
virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0;
+ dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const;
+
lldb::ByteOrder GetByteOrder() const;
const DWARFDebugAranges &GetFunctionAranges();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index c0bf13e0281d3..ab61a699c3edf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -9,6 +9,7 @@
#include "SymbolFileDWARF.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
@@ -1885,11 +1886,13 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
for (size_t g = 0; g < num_globals; ++g) {
VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
- const DWARFExpression &location = var_sp->LocationExpression();
+ const DWARFExpressionList &location =
+ var_sp->LocationExpressionList();
Value location_result;
Status error;
- if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr,
- nullptr, location_result, &error)) {
+ ExecutionContext exe_ctx;
+ if (location.Evaluate(&exe_ctx, nullptr, nullptr, nullptr,
+ location_result, &error)) {
if (location_result.GetValueType() ==
Value::ValueType::FileAddress) {
lldb::addr_t file_addr =
@@ -3163,7 +3166,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
const char *mangled = nullptr;
Declaration decl;
DWARFFormValue type_die_form;
- DWARFExpression location;
+ DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU());
bool is_external = false;
bool is_artificial = false;
DWARFFormValue const_value_form, location_form;
@@ -3229,16 +3232,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
// present in the class declaration and DW_AT_location in the DIE defining
// the member.
bool location_is_const_value_data = false;
- bool has_explicit_location = false;
+ bool has_explicit_location = location_form.IsValid();
bool use_type_size_for_value = false;
if (location_form.IsValid()) {
- has_explicit_location = true;
if (DWARFFormValue::IsBlockForm(location_form.Form())) {
const DWARFDataExtractor &data = die.GetData();
uint32_t block_offset = location_form.BlockData() - data.GetDataStart();
uint32_t block_length = location_form.Unsigned();
- location = DWARFExpression(
+ location_list = DWARFExpressionList(
module, DataExtractor(data, block_offset, block_length), die.GetCU());
} else {
DataExtractor data = die.GetCU()->GetLocationData();
@@ -3247,10 +3249,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1);
if (data.ValidOffset(offset)) {
data = DataExtractor(data, offset, data.GetByteSize() - offset);
- location = DWARFExpression(module, data, die.GetCU());
- assert(func_low_pc != LLDB_INVALID_ADDRESS);
- location.SetLocationListAddresses(
- location_form.GetUnit()->GetBaseAddress(), func_low_pc);
+ const DWARFUnit *dwarf_cu = location_form.GetUnit();
+ DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, &location_list);
}
}
} else if (const_value_form.IsValid()) {
@@ -3263,7 +3263,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
const_value_form.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = const_value_form.Unsigned();
- location = DWARFExpression(
+ location_list = DWARFExpressionList(
module, DataExtractor(debug_info_data, block_offset, block_length),
die.GetCU());
} else if (DWARFFormValue::IsDataForm(const_value_form.Form())) {
@@ -3273,7 +3273,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
use_type_size_for_value = true;
} else if (const char *str = const_value_form.AsCString()) {
uint32_t string_length = strlen(str) + 1;
- location = DWARFExpression(
+ location_list = DWARFExpressionList(
module,
DataExtractor(str, string_length, die.GetCU()->GetByteOrder(),
die.GetCU()->GetAddressByteSize()),
@@ -3323,16 +3323,19 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
// with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
// so we need to look through the whole expression.
bool is_static_lifetime =
- has_explicit_mangled || (has_explicit_location && !location.IsValid());
+ has_explicit_mangled ||
+ (has_explicit_location && !location_list.IsValid());
// Check if the location has a DW_OP_addr with any address value...
lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
if (!location_is_const_value_data) {
bool op_error = false;
- location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
+ const DWARFExpression* location = location_list.GetAlwaysValidExpr();
+ if (location)
+ location_DW_OP_addr = location->GetLocation_DW_OP_addr(
+ location_form.GetUnit(), 0, op_error);
if (op_error) {
StreamString strm;
- location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
- nullptr);
+ location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
GetObjectFile()->GetModule()->ReportError(
"0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
die.GetTagAsCString(), strm.GetData());
@@ -3345,7 +3348,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
// Set the module of the expression to the linked module
// instead of the object file so the relocated address can be
// found there.
- location.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
+ location_list.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
if (is_static_lifetime) {
if (is_external)
@@ -3386,7 +3389,9 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
const addr_t exe_file_addr =
exe_symbol->GetAddressRef().GetFileAddress();
if (exe_file_addr != LLDB_INVALID_ADDRESS) {
- if (location.Update_DW_OP_addr(exe_file_addr)) {
+ DWARFExpression *location =
+ location_list.GetMutableExpressionAtAddress();
+ if (location->Update_DW_OP_addr(exe_file_addr)) {
linked_oso_file_addr = true;
symbol_context_scope = exe_symbol;
}
@@ -3404,7 +3409,9 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
if (exe_file_addr != LLDB_INVALID_ADDRESS) {
// Update the file address for this variable
- location.Update_DW_OP_addr(exe_file_addr);
+ DWARFExpression *location =
+ location_list.GetMutableExpressionAtAddress();
+ location->Update_DW_OP_addr(exe_file_addr);
} else {
// Variable didn't make it into the final executable
return nullptr;
@@ -3419,8 +3426,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
scope = eValueTypeVariableLocal;
if (debug_map_symfile) {
// We need to check for TLS addresses that we need to fixup
- if (location.ContainsThreadLocalStorage()) {
- location.LinkThreadLocalStorage(
+ if (location_list.ContainsThreadLocalStorage()) {
+ location_list.LinkThreadLocalStorage(
debug_map_symfile->GetObjectFile()->GetModule(),
[this, debug_map_symfile](
lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
@@ -3463,14 +3470,17 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
auto type_sp = std::make_shared<SymbolFileType>(
*this, GetUID(type_die_form.Reference()));
- if (use_type_size_for_value && type_sp->GetType())
- location.UpdateValue(const_value_form.Unsigned(),
- type_sp->GetType()->GetByteSize(nullptr).value_or(0),
- die.GetCU()->GetAddressByteSize());
+ if (use_type_size_for_value && type_sp->GetType()) {
+ DWARFExpression *location = location_list.GetMutableExpressionAtAddress();
+ location->UpdateValue(
+ const_value_form.Unsigned(),
+ type_sp->GetType()->GetByteSize(nullptr).getValueOr(0),
+ die.GetCU()->GetAddressByteSize());
+ }
return std::make_shared<Variable>(
die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
- scope_ranges, &decl, location, is_external, is_artificial,
+ scope_ranges, &decl, location_list, is_external, is_artificial,
location_is_const_value_data, is_static_member);
}
@@ -3755,8 +3765,8 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
child.Tag() != DW_TAG_GNU_call_site_parameter)
continue;
- llvm::Optional<DWARFExpression> LocationInCallee;
- llvm::Optional<DWARFExpression> LocationInCaller;
+ llvm::Optional<DWARFExpressionList> LocationInCallee;
+ llvm::Optional<DWARFExpressionList> LocationInCaller;
DWARFAttributes attributes;
const size_t num_attributes = child.GetAttributes(attributes);
@@ -3764,7 +3774,7 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
// Parse the location at index \p attr_index within this call site parameter
// DIE, or return None on failure.
auto parse_simple_location =
- [&](int attr_index) -> llvm::Optional<DWARFExpression> {
+ [&](int attr_index) -> llvm::Optional<DWARFExpressionList> {
DWARFFormValue form_value;
if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
return {};
@@ -3773,9 +3783,9 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
auto data = child.GetData();
uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- return DWARFExpression(module,
- DataExtractor(data, block_offset, block_length),
- child.GetCU());
+ return DWARFExpressionList(
+ module, DataExtractor(data, block_offset, block_length),
+ child.GetCU());
};
for (size_t i = 0; i < num_attributes; ++i) {
@@ -3820,7 +3830,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
continue;
llvm::Optional<DWARFDIE> call_origin;
- llvm::Optional<DWARFExpression> call_target;
+ llvm::Optional<DWARFExpressionList> call_target;
addr_t return_pc = LLDB_INVALID_ADDRESS;
addr_t call_inst_pc = LLDB_INVALID_ADDRESS;
addr_t low_pc = LLDB_INVALID_ADDRESS;
@@ -3881,7 +3891,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
auto data = child.GetData();
uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- call_target = DWARFExpression(
+ call_target = DWARFExpressionList(
module, DataExtractor(data, block_offset, block_length),
child.GetCU());
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 2403ee2624ea1..cfd18f02053b4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -21,6 +21,7 @@
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Core/dwarf.h"
+#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 3ba0079c96e6a..3166c8ae65c6c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -122,7 +122,7 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr);
+ DWARFExpression result(extractor);
result.SetRegisterKind(register_kind);
return result;
@@ -247,7 +247,7 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
.take_front(size);
buffer->CopyData(bytes.data(), size);
DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
- DWARFExpression result(nullptr, extractor, nullptr);
+ DWARFExpression result(extractor);
return result;
}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 7dc99818c2443..d94ba6b3531a6 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -823,8 +823,10 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
m_ast->GetOrCreateVariableDecl(var_id);
- DWARFExpression location = MakeGlobalLocationExpression(
- section, offset, GetObjectFile()->GetModule());
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ DWARFExpressionList location(
+ module_sp, MakeGlobalLocationExpression(section, offset, module_sp),
+ nullptr);
std::string global_name("::");
global_name += name;
@@ -855,8 +857,10 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
Declaration decl;
Variable::RangeList ranges;
ModuleSP module = GetObjectFile()->GetModule();
- DWARFExpression location = MakeConstantLocationExpression(
- constant.Type, tpi, constant.Value, module);
+ DWARFExpressionList location(module,
+ MakeConstantLocationExpression(
+ constant.Type, tpi, constant.Value, module),
+ nullptr);
bool external = false;
bool artificial = false;
@@ -1711,7 +1715,8 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
bool static_member = false;
VariableSP var_sp = std::make_shared<Variable>(
toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
- &block, *var_info.ranges, &decl, *var_info.location, external,
+ &block, *var_info.ranges, &decl,
+ DWARFExpressionList(module, *var_info.location, nullptr), external,
artificial, location_is_constant_data, static_member);
if (!is_param)
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 96e9de704e414..94023737b2a2e 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -175,7 +175,7 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr);
+ DWARFExpression result(extractor);
result.SetRegisterKind(register_kind);
return result;
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index bd3d16aad6c2e..baa48532864bb 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1023,8 +1023,11 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();
bool is_constant;
- DWARFExpression location = ConvertPDBLocationToDWARFExpression(
- GetObjectFile()->GetModule(), pdb_data, ranges, is_constant);
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ DWARFExpressionList location(module_sp,
+ ConvertPDBLocationToDWARFExpression(
+ module_sp, pdb_data, ranges, is_constant),
+ nullptr);
var_sp = std::make_shared<Variable>(
var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 648a12524aed1..54c562eb1bdd9 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -197,7 +197,6 @@ Function *IndirectCallEdge::GetCallee(ModuleList &images,
Status error;
Value callee_addr_val;
if (!call_target.Evaluate(&exe_ctx, exe_ctx.GetRegisterContext(),
- /*loclist_base_load_addr=*/LLDB_INVALID_ADDRESS,
/*initial_value_ptr=*/nullptr,
/*object_address_ptr=*/nullptr, callee_addr_val,
&error)) {
diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index b92c866544969..285e32d21ce23 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -39,13 +39,13 @@ Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled,
const lldb::SymbolFileTypeSP &symfile_type_sp,
ValueType scope, SymbolContextScope *context,
const RangeList &scope_range, Declaration *decl_ptr,
- const DWARFExpression &location, bool external,
+ const DWARFExpressionList &location_list, bool external,
bool artificial, bool location_is_constant_data,
bool static_member)
: UserID(uid), m_name(name), m_mangled(ConstString(mangled)),
m_symfile_type_sp(symfile_type_sp), m_scope(scope),
m_owner_scope(context), m_scope_range(scope_range),
- m_declaration(decl_ptr), m_location(location), m_external(external),
+ m_declaration(decl_ptr), m_location_list(location_list), m_external(external),
m_artificial(artificial), m_loc_is_const_data(location_is_constant_data),
m_static_member(static_member) {}
@@ -145,7 +145,7 @@ void Variable::Dump(Stream *s, bool show_context) const {
bool show_fullpaths = false;
m_declaration.Dump(s, show_fullpaths);
- if (m_location.IsValid()) {
+ if (m_location_list.IsValid()) {
s->PutCString(", location = ");
ABISP abi;
if (m_owner_scope) {
@@ -153,7 +153,7 @@ void Variable::Dump(Stream *s, bool show_context) const {
if (module_sp)
abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
}
- m_location.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
+ m_location_list.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
}
if (m_external)
@@ -212,31 +212,8 @@ void Variable::CalculateSymbolContext(SymbolContext *sc) {
}
bool Variable::LocationIsValidForFrame(StackFrame *frame) {
- // Is the variable is described by a single location?
- if (!m_location.IsLocationList()) {
- // Yes it is, the location is valid.
- return true;
- }
-
- if (frame) {
- Function *function =
- frame->GetSymbolContext(eSymbolContextFunction).function;
- if (function) {
- TargetSP target_sp(frame->CalculateTarget());
-
- addr_t loclist_base_load_addr =
- function->GetAddressRange().GetBaseAddress().GetLoadAddress(
- target_sp.get());
- if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
- return false;
- // It is a location list. We just need to tell if the location list
- // contains the current address when converted to a load address
- return m_location.LocationListContainsAddress(
- loclist_base_load_addr,
- frame->GetFrameCodeAddress().GetLoadAddress(target_sp.get()));
- }
- }
- return false;
+ return m_location_list.ContainsAddress(
+ frame->GetFrameCodeAddress().GetFileAddress());
}
bool Variable::LocationIsValidForAddress(const Address &address) {
@@ -244,7 +221,7 @@ bool Variable::LocationIsValidForAddress(const Address &address) {
// function.
if (address.IsSectionOffset()) {
// We need to check if the address is valid for both scope range and value
- // range.
+ // range.
// Empty scope range means block range.
bool valid_in_scope_range =
GetScopeRange().IsEmpty() || GetScopeRange().FindEntryThatContains(
@@ -254,22 +231,10 @@ bool Variable::LocationIsValidForAddress(const Address &address) {
SymbolContext sc;
CalculateSymbolContext(&sc);
if (sc.module_sp == address.GetModule()) {
- // Is the variable is described by a single location?
- if (!m_location.IsLocationList()) {
- // Yes it is, the location is valid.
- return true;
- }
-
- if (sc.function) {
- addr_t loclist_base_file_addr =
- sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
- if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
- return false;
- // It is a location list. We just need to tell if the location list
- // contains the current address when converted to a load address
- return m_location.LocationListContainsAddress(loclist_base_file_addr,
- address.GetFileAddress());
- }
+ // Empty location list means we have missing value range info, but it's in
+ // the scope.
+ return m_location_list.GetSize() == 0 ||
+ m_location_list.ContainsAddress(address.GetFileAddress());
}
}
return false;
@@ -454,16 +419,8 @@ bool Variable::DumpLocations(Stream *s, const Address &address) {
}
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;
+ return m_location_list.DumpLocations(s, eDescriptionLevelBrief, file_addr,
+ abi.get());
}
static void PrivateAutoComplete(
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index e98aed7e15552..bca7eec5e939e 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -11,7 +11,7 @@
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/CallFrameInfo.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
@@ -381,7 +381,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
// symbol/function information - just stick in some reasonable defaults and
// hope we can unwind past this frame. If we're above a trap handler,
// we may be at a bogus address because we jumped through a bogus function
- // pointer and trapped, so don't force the arch default unwind plan in that
+ // pointer and trapped, so don't force the arch default unwind plan in that
// case.
ModuleSP pc_module_sp(m_current_pc.GetModule());
if ((!m_current_pc.IsValid() || !pc_module_sp) &&
@@ -1286,7 +1286,7 @@ RegisterContextUnwind::SavedLocationForRegister(
// arch default unwind plan is used as the Fast Unwind Plan, we
// need to recognize this & switch over to the Full Unwind Plan
// to see what unwind rule that (more knoweldgeable, probably)
- // UnwindPlan has. If the full UnwindPlan says the register
+ // UnwindPlan has. If the full UnwindPlan says the register
// location is Undefined, then it really is.
if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
unwindplan_regloc) &&
@@ -1335,13 +1335,13 @@ RegisterContextUnwind::SavedLocationForRegister(
m_full_unwind_plan_sp->GetReturnAddressRegister() !=
LLDB_INVALID_REGNUM) {
// If this is a trap handler frame, we should have access to
- // the complete register context when the interrupt/async
+ // the complete register context when the interrupt/async
// signal was received, we should fetch the actual saved $pc
// value instead of the Return Address register.
// If $pc is not available, fall back to the RA reg.
UnwindPlan::Row::RegisterLocation scratch;
if (m_frame_type == eTrapHandlerFrame &&
- active_row->GetRegisterInfo
+ active_row->GetRegisterInfo
(pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) {
UnwindLogMsg("Providing pc register instead of rewriting to "
"RA reg because this is a trap handler and there is "
@@ -1642,14 +1642,14 @@ RegisterContextUnwind::SavedLocationForRegister(
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
- dwarfexpr.SetRegisterKind(unwindplan_registerkind);
+ DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+ dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
+ unwindplan_registerkind);
Value cfa_val = Scalar(m_cfa);
cfa_val.SetValueType(Value::ValueType::LoadAddress);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result,
- &error)) {
+ if (dwarfexpr.Evaluate(&exe_ctx, this, &cfa_val, nullptr, result, &error)) {
addr_t val;
val = result.GetScalar().ULongLong();
if (unwindplan_regloc.IsDWARFExpression()) {
@@ -2006,11 +2006,12 @@ bool RegisterContextUnwind::ReadFrameAddress(
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
- dwarfexpr.SetRegisterKind(row_register_kind);
+ DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+ dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
+ row_register_kind);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
+ if (dwarfexpr.Evaluate(&exe_ctx, this, nullptr, nullptr, result,
&error)) {
address = result.GetScalar().ULongLong();
if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 1e3dbc73a04ed..28c8dfde72a8d 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1086,15 +1086,9 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
m_flags.Set(GOT_FRAME_BASE);
ExecutionContext exe_ctx(shared_from_this());
Value expr_value;
- addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
- if (m_sc.function->GetFrameBaseExpression().IsLocationList())
- loclist_base_addr =
- m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
- exe_ctx.GetTargetPtr());
-
if (!m_sc.function->GetFrameBaseExpression().Evaluate(
- &exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr,
- expr_value, &m_frame_base_error)) {
+ &exe_ctx, nullptr, nullptr, nullptr, expr_value,
+ &m_frame_base_error)) {
// We should really have an error if evaluate returns, but in case we
// don't, lets set the error to something at least.
if (m_frame_base_error.Success())
@@ -1116,7 +1110,7 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
return m_frame_base_error.Success();
}
-DWARFExpression *StackFrame::GetFrameBaseExpression(Status *error_ptr) {
+DWARFExpressionList *StackFrame::GetFrameBaseExpression(Status *error_ptr) {
if (!m_sc.function) {
if (error_ptr) {
error_ptr->SetErrorString("No function in symbol context.");
@@ -1200,7 +1194,7 @@ lldb::LanguageType StackFrame::GuessLanguage() {
LanguageType lang_type = GetLanguage();
if (lang_type == eLanguageTypeUnknown) {
- SymbolContext sc = GetSymbolContext(eSymbolContextFunction
+ SymbolContext sc = GetSymbolContext(eSymbolContextFunction
| eSymbolContextSymbol);
if (sc.function) {
lang_type = sc.function->GetMangled().GuessLanguage();
@@ -1417,7 +1411,7 @@ ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
Status error;
ValueObjectSP pointee = base->Dereference(error);
-
+
if (!pointee) {
return ValueObjectSP();
}
@@ -1505,7 +1499,7 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
Instruction::Operand::BuildRegister(reg));
for (VariableSP var_sp : variables) {
- if (var_sp->LocationExpression().MatchesOperand(frame, op))
+ if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
}
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
index 2daf816d300c8..f8e8bfba970f0 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
@@ -40,11 +40,11 @@
# CHECK-NEXT: [0x0000000000000000, 0x0000000000000001): DW_OP_reg5 RDI
# CHECK-NEXT: [0x0000000000000001, 0x0000000000000006): DW_OP_reg0 RAX
# CHECK: Variable{{.*}}, name = "x1", {{.*}}, scope = parameter
-# CHECK: Variable{{.*}}, name = "x2", {{.*}}, scope = parameter, location = 0x00000000: error: unexpected end of data
+# CHECK: Variable{{.*}}, name = "x2", {{.*}}, scope = parameter
# CHECK: Variable{{.*}}, name = "x3", {{.*}}, scope = parameter, location =
# CHECK-NEXT: [0x0000000000000002, 0x0000000000000003): DW_OP_reg1 RDX
-# LOCLISTS: Variable{{.*}}, name = "x4", {{.*}}, scope = parameter, location =
-# LOCLISTS-NEXT: DW_LLE_startx_length (0x000000000000dead, 0x0000000000000001): DW_OP_reg2 RCX
+# LOCLISTS: Variable{{.*}}, name = "x4", {{.*}}, scope = parameter
+# LOCLISTS-EMPTY:
.ifdef LOC
.macro OFFSET_PAIR lo hi
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
index a921641bcec54..c8eead3d28d29 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
@@ -19,29 +19,29 @@
# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x0
# SYMBOLS-NEXT: Function{{.*}}, demangled = F0
# SYMBOLS-NEXT: Block{{.*}}, ranges = [0x00000000-0x00000001)
-# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000001): DW_OP_reg0 RAX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: [0x0000000000000000, 0x0000000000000001): DW_OP_reg0 RAX
# SYMBOLS-EMPTY:
# SYMBOLS-NEXT: CompileUnit{0x00000001}, language = "<not loaded>", file = '1.c'
# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x2
# SYMBOLS-NEXT: Function{{.*}}, demangled = F1
# SYMBOLS-NEXT: Block{{.*}}, ranges = [0x00000001-0x00000002)
-# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000003, 0x0000000000000001): DW_OP_reg1 RDX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: [0x0000000000000001, 0x0000000000000002): DW_OP_reg1 RDX
# SYMBOLS-EMPTY:
# SYMBOLS-NEXT: CompileUnit{0x00000002}, language = "<not loaded>", file = '2.c'
# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x4
# SYMBOLS-NEXT: Function{{.*}}, demangled = F2
# SYMBOLS-NEXT: Block{{.*}}, ranges = [0x00000002-0x00000003)
-# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000005, 0x0000000000000001): DW_OP_reg2 RCX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: [0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX
# SYMBOLS-EMPTY:
# SYMBOLS-NEXT: CompileUnit{0x00000003}, language = "<not loaded>", file = '3.c'
# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x6
# SYMBOLS-NEXT: Function{{.*}}, demangled = F3
# SYMBOLS-NEXT: Block{{.*}}, ranges = [0x00000003-0x00000004)
-# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000007, 0x0000000000000001): DW_OP_reg3 RBX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX
# SYMBOLS-EMPTY:
# SYMBOLS-NEXT: CompileUnit{0x00000004}, language = "<not loaded>", file = ''
# SYMBOLS-EMPTY:
@@ -116,7 +116,7 @@ F\I:
.Lloc\I:
.byte 3 # DW_LLE_startx_length
.uleb128 \I*2+1
- .long 1
+ .long 1
.short 1 # Expression size
.byte 80+\I # super-register DW_OP_reg0+\I
.byte 0 # DW_LLE_end_of_list
diff --git a/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
index f58874f794eec..62d7335384216 100644
--- a/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
@@ -23,6 +23,7 @@ static_library("Expression") {
include_dirs = [ ".." ]
sources = [
"DWARFExpression.cpp",
+ "DWARFExpressionList.cpp",
"DiagnosticManager.cpp",
"Expression.cpp",
"ExpressionVariable.cpp",
More information about the lldb-commits
mailing list