[Lldb-commits] [lldb] e4c5bca - Revert "[LLDB][NFC] Decouple dwarf location table from DWARFExpression."
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 7 16:37:54 PDT 2022
Author: Jonas Devlieghere
Date: 2022-07-07T16:36:10-07:00
New Revision: e4c5bca597a6f12e8f789a53e862387b9808ff48
URL: https://github.com/llvm/llvm-project/commit/e4c5bca597a6f12e8f789a53e862387b9808ff48
DIFF: https://github.com/llvm/llvm-project/commit/e4c5bca597a6f12e8f789a53e862387b9808ff48.diff
LOG: Revert "[LLDB][NFC] Decouple dwarf location table from DWARFExpression."
This reverts commit 227dffd0b6d78154516ace45f6ed28259c7baa48 and its
follow up 562c3467a6738aa89203f72fc1d1343e5baadf3c because it breaks a
bunch of tests on GreenDragon:
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/45155/
Added:
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:
lldb/include/lldb/Expression/DWARFExpressionList.h
lldb/source/Expression/DWARFExpressionList.cpp
################################################################################
diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 49e51d51f211c..96a0e8e02da13 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -42,14 +42,49 @@ class DWARFExpression {
/// \param[in] data
/// A data extractor configured to read the DWARF location expression's
/// bytecode.
- DWARFExpression(const DataExtractor &data);
+ DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
+ const DWARFUnit *dwarf_cu);
/// 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
@@ -58,9 +93,6 @@ 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.
@@ -72,22 +104,36 @@ 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(const DWARFUnit *dwarf_cu,
- uint32_t op_addr_idx, bool &error) const;
+ lldb::addr_t GetLocation_DW_OP_addr(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
- lldb::RegisterKind GetRegisterKind() const;
+ int GetRegisterKind();
/// Set the call-frame-info style register kind
///
@@ -95,6 +141,20 @@ 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
@@ -134,32 +194,72 @@ 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 module_sp, const DataExtractor &opcodes,
+ lldb::ModuleSP opcode_ctx, 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;
}
- void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
+ 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;
- bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const;
+ bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
+
+ llvm::Optional<DataExtractor>
+ GetLocationExpression(lldb::addr_t load_function_start,
+ lldb::addr_t addr) 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
deleted file mode 100644
index 34cd217b8fe4a..0000000000000
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ /dev/null
@@ -1,132 +0,0 @@
-//===-- 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 3eb4f5d7dedf4..83f9979c3c529 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/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.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 {
- DWARFExpressionList LocationInCallee;
- DWARFExpressionList LocationInCaller;
+ DWARFExpression LocationInCallee;
+ DWARFExpression 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(DWARFExpressionList call_target, AddrType caller_address_type,
+ IndirectCallEdge(DWARFExpression 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.
- DWARFExpressionList call_target;
+ DWARFExpression 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.
- DWARFExpressionList &GetFrameBaseExpression() { return m_frame_base; }
+ DWARFExpression &GetFrameBaseExpression() { return m_frame_base; }
/// Get const accessor for the frame base location.
///
/// \return
/// A const compile unit object pointer.
- const DWARFExpressionList &GetFrameBaseExpression() const { return m_frame_base; }
+ const DWARFExpression &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.
- DWARFExpressionList m_frame_base;
+ DWARFExpression m_frame_base;
Flags m_flags;
diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h
index c437624d1ea6d..88a975df39928 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/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.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 DWARFExpressionList &location,
- bool external, bool artificial, bool location_is_constant_data,
+ Declaration *decl, const DWARFExpression &location, bool external,
+ bool artificial, bool location_is_constant_data,
bool static_member = false);
virtual ~Variable();
@@ -73,11 +73,9 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
bool IsStaticMember() const { return m_static_member; }
- DWARFExpressionList &LocationExpressionList() { return m_location_list; }
+ DWARFExpression &LocationExpression() { return m_location; }
- const DWARFExpressionList &LocationExpressionList() const {
- return m_location_list;
- }
+ const DWARFExpression &LocationExpression() const { return m_location; }
// When given invalid address, it dumps all locations. Otherwise it only dumps
// the location that contains this address.
@@ -130,7 +128,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().
- DWARFExpressionList m_location_list;
+ DWARFExpression m_location;
/// 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 7c4340de4de06..1b0485b22cacb 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 DWARFExpressionList corresponding to the Canonical Frame Address.
+ /// Get the DWARFExpression 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.
- DWARFExpressionList *GetFrameBaseExpression(Status *error_ptr);
+ DWARFExpression *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 257b177c70927..7eb0cab8084c7 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -627,10 +627,6 @@ 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 c51e1850338ff..487b2f20792b9 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -66,7 +66,6 @@ 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 7f0e86b9294da..8e89503a8a76b 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/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -127,20 +127,22 @@ bool ValueObjectVariable::UpdateValue() {
m_error.Clear();
Variable *variable = m_variable_sp.get();
- DWARFExpressionList &expr_list = variable->LocationExpressionList();
+ DWARFExpression &expr = variable->LocationExpression();
if (variable->GetLocationIsConstantValueData()) {
// expr doesn't contain DWARF bytes, it contains the constant variable
// value bytes themselves...
- if (expr_list.GetExpressionData(m_data)) {
- if (m_data.GetDataStart() && m_data.GetByteSize())
+ if (expr.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();
@@ -149,8 +151,17 @@ 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_list.Evaluate(&exe_ctx, nullptr, nullptr, nullptr, m_value, &m_error)) {
+ if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
+ nullptr, m_value, &m_error)) {
m_resolved_value = m_value;
m_value.SetContext(Value::ContextType::Variable, variable);
@@ -235,7 +246,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 54414fb2a7c4f..c935e1b1c04b9 100644
--- a/lldb/source/Expression/CMakeLists.txt
+++ b/lldb/source/Expression/CMakeLists.txt
@@ -1,7 +1,6 @@
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 fff5f60bc3abf..1f11907dc64c4 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -45,10 +45,29 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
-// DWARFExpression constructor
-DWARFExpression::DWARFExpression() : m_data() {}
+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::DWARFExpression(const DataExtractor &data) : m_data(data) {}
+// 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;
+}
// Destructor
DWARFExpression::~DWARFExpression() = default;
@@ -67,19 +86,71 @@ void DWARFExpression::UpdateValue(uint64_t const_value,
m_data.SetAddressByteSize(addr_byte_size);
}
-void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
+void DWARFExpression::DumpLocation(Stream *s, const DataExtractor &data,
+ lldb::DescriptionLevel level,
ABI *abi) const {
- llvm::DWARFExpression(m_data.GetAsLLVM(), m_data.GetAddressByteSize())
+ llvm::DWARFExpression(data.GetAsLLVM(), data.GetAddressByteSize())
.print(s->AsRawOstream(), llvm::DIDumpOptions(),
abi ? &abi->GetMCRegisterInfo() : nullptr, nullptr);
}
-RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
+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; }
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,
@@ -338,10 +409,11 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data,
return LLDB_INVALID_OFFSET;
}
-lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
- uint32_t op_addr_idx,
+lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(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)) {
@@ -351,18 +423,19 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
if (curr_op_addr_idx == op_addr_idx)
return op_file_addr;
- ++curr_op_addr_idx;
+ else
+ ++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 (!dwarf_cu) {
+ if (!m_dwarf_cu) {
error = true;
break;
}
- return dwarf_cu->ReadAddressFromDebugAddrSection(index);
- }
- ++curr_op_addr_idx;
+ return ReadAddressFromDebugAddrSection(m_dwarf_cu, index);
+ } else
+ ++curr_op_addr_idx;
} else {
const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
if (op_arg_size == LLDB_INVALID_OFFSET) {
@@ -376,6 +449,8 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
}
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);
@@ -412,6 +487,11 @@ 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);
@@ -421,18 +501,27 @@ bool DWARFExpression::ContainsThreadLocalStorage() const {
const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
if (op_arg_size == LLDB_INVALID_OFFSET)
return false;
- offset += op_arg_size;
+ else
+ 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(),
@@ -504,10 +593,42 @@ 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,
@@ -703,9 +824,10 @@ 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 DWARFExpressionList ¶m_expr = matched_param->LocationInCaller;
+ const DWARFExpression ¶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,
@@ -717,6 +839,63 @@ 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
@@ -2491,7 +2670,7 @@ bool DWARFExpression::Evaluate(
return false;
}
uint64_t index = opcodes.GetULEB128(&offset);
- lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
+ lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
stack.push_back(Scalar(value));
stack.back().SetValueType(Value::ValueType::FileAddress);
} break;
@@ -2511,7 +2690,7 @@ bool DWARFExpression::Evaluate(
return false;
}
uint64_t index = opcodes.GetULEB128(&offset);
- lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
+ lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
stack.push_back(Scalar(value));
} break;
@@ -2564,16 +2743,61 @@ bool DWARFExpression::Evaluate(
return true; // Return true on success
}
-bool DWARFExpression::ParseDWARFLocationList(
- const DWARFUnit *dwarf_cu, const DataExtractor &data,
- DWARFExpressionList *location_list) {
- location_list->Clear();
- std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
- dwarf_cu->GetLocationTable(data);
+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);
+
+ std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
+ m_dwarf_cu->GetLocationTable(m_data);
+
+ uint64_t offset = 0;
auto lookup_addr =
[&](uint32_t index) -> llvm::Optional<llvm::object::SectionedAddress> {
- addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index);
+ addr_t address = ReadAddressFromDebugAddrSection(m_dwarf_cu, index);
if (address == LLDB_INVALID_ADDRESS)
return llvm::None;
return llvm::object::SectionedAddress{address};
@@ -2583,17 +2807,18 @@ bool DWARFExpression::ParseDWARFLocationList(
LLDB_LOG_ERROR(log, loc.takeError(), "{0}");
return true;
}
- 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;
+ 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);
};
llvm::Error error = loctable_up->visitAbsoluteLocationList(
- 0, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()},
+ offset, llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr},
lookup_addr, process_list);
- location_list->Sort();
if (error) {
LLDB_LOG_ERROR(log, std::move(error), "{0}");
return false;
@@ -2601,8 +2826,23 @@ bool DWARFExpression::ParseDWARFLocationList(
return true;
}
-bool DWARFExpression::MatchesOperand(
- StackFrame &frame, const Instruction::Operand &operand) const {
+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) {
using namespace OperandMatchers;
RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
@@ -2610,7 +2850,28 @@ bool DWARFExpression::MatchesOperand(
return false;
}
- DataExtractor opcodes(m_data);
+ 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;
+
lldb::offset_t op_offset = 0;
uint8_t opcode = opcodes.GetU8(&op_offset);
@@ -2618,7 +2879,7 @@ bool DWARFExpression::MatchesOperand(
if (opcode == DW_OP_fbreg) {
int64_t offset = opcodes.GetSLEB128(&op_offset);
- DWARFExpressionList *fb_expr = frame.GetFrameBaseExpression(nullptr);
+ DWARFExpression *fb_expr = frame.GetFrameBaseExpression(nullptr);
if (!fb_expr) {
return false;
}
diff --git a/lldb/source/Expression/DWARFExpressionList.cpp b/lldb/source/Expression/DWARFExpressionList.cpp
deleted file mode 100644
index 68e3e8c611b9f..0000000000000
--- a/lldb/source/Expression/DWARFExpressionList.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-//===-- 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) {
- if (error_ptr)
- error_ptr->SetErrorString("variable not available");
- 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 965a96b7f909d..9ee2d983ddfc6 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->LocationExpressionList().IsValid()) {
+ !m_variable_sp->LocationExpression().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 6fb7d92244f90..cc45871bcd71a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1485,14 +1485,15 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
return false;
}
- DWARFExpressionList &var_location_list = var->LocationExpressionList();
+ DWARFExpression &var_location_expr = var->LocationExpression();
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Status err;
if (var->GetLocationIsConstantValueData()) {
DataExtractor const_value_extractor;
- if (var_location_list.GetExpressionData(const_value_extractor)) {
+
+ if (var_location_expr.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 4b9354371bda3..2aacac3692be5 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;
- DWARFExpressionList frame_base;
+ DWARFExpression 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 06cdd877f7dcd..ec074be581b54 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::DWARFExpressionList *frame_base) const {
+ lldb_private::DWARFExpression *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 7ce9550a081e9..5ee44a7632049 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -85,12 +85,11 @@ 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::DWARFExpressionList *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::DWARFExpression *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 c1d49c5f23d7c..95c0cb6472c59 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -231,10 +231,11 @@ 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,
- DWARFExpressionList *frame_base) const {
+ DWARFExpression *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);
@@ -344,17 +345,21 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- *frame_base =
- DWARFExpressionList(module,
- DWARFExpression(DataExtractor(
- data, block_offset, block_length)),
- cu);
+ *frame_base = DWARFExpression(
+ module, 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);
- DWARFExpression::ParseDWARFLocationList(cu, data, frame_base);
+ *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;
+ }
}
}
}
@@ -376,6 +381,12 @@ 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 32f653e99a705..64e86c71ac09e 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::DWARFExpressionList *frame_base = nullptr) const;
+ lldb_private::DWARFExpression *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 7b4a5d8eca3ed..903cd2e38f769 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -579,17 +579,6 @@ 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 40a1943b847a0..265e28b51c991 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -166,8 +166,6 @@ 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 ab61a699c3edf..c0bf13e0281d3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -9,7 +9,6 @@
#include "SymbolFileDWARF.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
@@ -1886,13 +1885,11 @@ 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 DWARFExpressionList &location =
- var_sp->LocationExpressionList();
+ const DWARFExpression &location = var_sp->LocationExpression();
Value location_result;
Status error;
- ExecutionContext exe_ctx;
- if (location.Evaluate(&exe_ctx, nullptr, nullptr, nullptr,
- location_result, &error)) {
+ if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr,
+ nullptr, location_result, &error)) {
if (location_result.GetValueType() ==
Value::ValueType::FileAddress) {
lldb::addr_t file_addr =
@@ -3166,7 +3163,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
const char *mangled = nullptr;
Declaration decl;
DWARFFormValue type_die_form;
- DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU());
+ DWARFExpression location;
bool is_external = false;
bool is_artificial = false;
DWARFFormValue const_value_form, location_form;
@@ -3232,15 +3229,16 @@ 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 = location_form.IsValid();
+ bool has_explicit_location = false;
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_list = DWARFExpressionList(
+ location = DWARFExpression(
module, DataExtractor(data, block_offset, block_length), die.GetCU());
} else {
DataExtractor data = die.GetCU()->GetLocationData();
@@ -3249,8 +3247,10 @@ 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);
- const DWARFUnit *dwarf_cu = location_form.GetUnit();
- DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, &location_list);
+ location = DWARFExpression(module, data, die.GetCU());
+ assert(func_low_pc != LLDB_INVALID_ADDRESS);
+ location.SetLocationListAddresses(
+ location_form.GetUnit()->GetBaseAddress(), func_low_pc);
}
}
} 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_list = DWARFExpressionList(
+ location = DWARFExpression(
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_list = DWARFExpressionList(
+ location = DWARFExpression(
module,
DataExtractor(str, string_length, die.GetCU()->GetByteOrder(),
die.GetCU()->GetAddressByteSize()),
@@ -3323,19 +3323,16 @@ 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_list.IsValid());
+ has_explicit_mangled || (has_explicit_location && !location.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;
- const DWARFExpression* location = location_list.GetAlwaysValidExpr();
- if (location)
- location_DW_OP_addr = location->GetLocation_DW_OP_addr(
- location_form.GetUnit(), 0, op_error);
+ location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
if (op_error) {
StreamString strm;
- location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
+ location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
+ nullptr);
GetObjectFile()->GetModule()->ReportError(
"0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
die.GetTagAsCString(), strm.GetData());
@@ -3348,7 +3345,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_list.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
+ location.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
if (is_static_lifetime) {
if (is_external)
@@ -3389,9 +3386,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
const addr_t exe_file_addr =
exe_symbol->GetAddressRef().GetFileAddress();
if (exe_file_addr != LLDB_INVALID_ADDRESS) {
- DWARFExpression *location =
- location_list.GetMutableExpressionAtAddress();
- if (location->Update_DW_OP_addr(exe_file_addr)) {
+ if (location.Update_DW_OP_addr(exe_file_addr)) {
linked_oso_file_addr = true;
symbol_context_scope = exe_symbol;
}
@@ -3409,9 +3404,7 @@ 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
- DWARFExpression *location =
- location_list.GetMutableExpressionAtAddress();
- location->Update_DW_OP_addr(exe_file_addr);
+ location.Update_DW_OP_addr(exe_file_addr);
} else {
// Variable didn't make it into the final executable
return nullptr;
@@ -3426,8 +3419,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_list.ContainsThreadLocalStorage()) {
- location_list.LinkThreadLocalStorage(
+ if (location.ContainsThreadLocalStorage()) {
+ location.LinkThreadLocalStorage(
debug_map_symfile->GetObjectFile()->GetModule(),
[this, debug_map_symfile](
lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
@@ -3470,17 +3463,14 @@ 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()) {
- DWARFExpression *location = location_list.GetMutableExpressionAtAddress();
- location->UpdateValue(
- const_value_form.Unsigned(),
- type_sp->GetType()->GetByteSize(nullptr).getValueOr(0),
- die.GetCU()->GetAddressByteSize());
- }
+ 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());
return std::make_shared<Variable>(
die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
- scope_ranges, &decl, location_list, is_external, is_artificial,
+ scope_ranges, &decl, location, is_external, is_artificial,
location_is_const_value_data, is_static_member);
}
@@ -3765,8 +3755,8 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
child.Tag() != DW_TAG_GNU_call_site_parameter)
continue;
- llvm::Optional<DWARFExpressionList> LocationInCallee;
- llvm::Optional<DWARFExpressionList> LocationInCaller;
+ llvm::Optional<DWARFExpression> LocationInCallee;
+ llvm::Optional<DWARFExpression> LocationInCaller;
DWARFAttributes attributes;
const size_t num_attributes = child.GetAttributes(attributes);
@@ -3774,7 +3764,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<DWARFExpressionList> {
+ [&](int attr_index) -> llvm::Optional<DWARFExpression> {
DWARFFormValue form_value;
if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
return {};
@@ -3783,9 +3773,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 DWARFExpressionList(
- module, DataExtractor(data, block_offset, block_length),
- child.GetCU());
+ return DWARFExpression(module,
+ DataExtractor(data, block_offset, block_length),
+ child.GetCU());
};
for (size_t i = 0; i < num_attributes; ++i) {
@@ -3830,7 +3820,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
continue;
llvm::Optional<DWARFDIE> call_origin;
- llvm::Optional<DWARFExpressionList> call_target;
+ llvm::Optional<DWARFExpression> call_target;
addr_t return_pc = LLDB_INVALID_ADDRESS;
addr_t call_inst_pc = LLDB_INVALID_ADDRESS;
addr_t low_pc = LLDB_INVALID_ADDRESS;
@@ -3891,7 +3881,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 = DWARFExpressionList(
+ call_target = DWARFExpression(
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 cfd18f02053b4..2403ee2624ea1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -21,7 +21,6 @@
#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 3166c8ae65c6c..3ba0079c96e6a 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(extractor);
+ DWARFExpression result(module, extractor, nullptr);
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(extractor);
+ DWARFExpression result(nullptr, extractor, nullptr);
return result;
}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index d94ba6b3531a6..7dc99818c2443 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -823,10 +823,8 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
m_ast->GetOrCreateVariableDecl(var_id);
- ModuleSP module_sp = GetObjectFile()->GetModule();
- DWARFExpressionList location(
- module_sp, MakeGlobalLocationExpression(section, offset, module_sp),
- nullptr);
+ DWARFExpression location = MakeGlobalLocationExpression(
+ section, offset, GetObjectFile()->GetModule());
std::string global_name("::");
global_name += name;
@@ -857,10 +855,8 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
Declaration decl;
Variable::RangeList ranges;
ModuleSP module = GetObjectFile()->GetModule();
- DWARFExpressionList location(module,
- MakeConstantLocationExpression(
- constant.Type, tpi, constant.Value, module),
- nullptr);
+ DWARFExpression location = MakeConstantLocationExpression(
+ constant.Type, tpi, constant.Value, module);
bool external = false;
bool artificial = false;
@@ -1715,8 +1711,7 @@ 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,
- DWARFExpressionList(module, *var_info.location, nullptr), external,
+ &block, *var_info.ranges, &decl, *var_info.location, 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 94023737b2a2e..96e9de704e414 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(extractor);
+ DWARFExpression result(module, extractor, nullptr);
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 baa48532864bb..bd3d16aad6c2e 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1023,11 +1023,8 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();
bool is_constant;
- ModuleSP module_sp = GetObjectFile()->GetModule();
- DWARFExpressionList location(module_sp,
- ConvertPDBLocationToDWARFExpression(
- module_sp, pdb_data, ranges, is_constant),
- nullptr);
+ DWARFExpression location = ConvertPDBLocationToDWARFExpression(
+ GetObjectFile()->GetModule(), pdb_data, ranges, is_constant);
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 54c562eb1bdd9..648a12524aed1 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -197,6 +197,7 @@ 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 285e32d21ce23..b92c866544969 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 DWARFExpressionList &location_list, bool external,
+ const DWARFExpression &location, 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_list(location_list), m_external(external),
+ m_declaration(decl_ptr), m_location(location), 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_list.IsValid()) {
+ if (m_location.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_list.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
+ m_location.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
}
if (m_external)
@@ -212,8 +212,31 @@ void Variable::CalculateSymbolContext(SymbolContext *sc) {
}
bool Variable::LocationIsValidForFrame(StackFrame *frame) {
- return m_location_list.ContainsAddress(
- frame->GetFrameCodeAddress().GetFileAddress());
+ // 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;
}
bool Variable::LocationIsValidForAddress(const Address &address) {
@@ -221,7 +244,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(
@@ -231,10 +254,22 @@ bool Variable::LocationIsValidForAddress(const Address &address) {
SymbolContext sc;
CalculateSymbolContext(&sc);
if (sc.module_sp == address.GetModule()) {
- // 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());
+ // 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());
+ }
}
}
return false;
@@ -419,8 +454,16 @@ bool Variable::DumpLocations(Stream *s, const Address &address) {
}
const addr_t file_addr = address.GetFileAddress();
- return m_location_list.DumpLocations(s, eDescriptionLevelBrief, file_addr,
- abi.get());
+ 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;
}
static void PrivateAutoComplete(
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index bca7eec5e939e..e98aed7e15552 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/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.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;
- DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
- dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
- unwindplan_registerkind);
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+ dwarfexpr.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, &cfa_val, nullptr, result, &error)) {
+ if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result,
+ &error)) {
addr_t val;
val = result.GetScalar().ULongLong();
if (unwindplan_regloc.IsDWARFExpression()) {
@@ -2006,12 +2006,11 @@ bool RegisterContextUnwind::ReadFrameAddress(
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
- DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
- dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
- row_register_kind);
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+ dwarfexpr.SetRegisterKind(row_register_kind);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, this, nullptr, nullptr, result,
+ if (dwarfexpr.Evaluate(&exe_ctx, this, 0, 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 28c8dfde72a8d..1e3dbc73a04ed 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1086,9 +1086,15 @@ 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, nullptr, nullptr, expr_value,
- &m_frame_base_error)) {
+ &exe_ctx, nullptr, loclist_base_addr, 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())
@@ -1110,7 +1116,7 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
return m_frame_base_error.Success();
}
-DWARFExpressionList *StackFrame::GetFrameBaseExpression(Status *error_ptr) {
+DWARFExpression *StackFrame::GetFrameBaseExpression(Status *error_ptr) {
if (!m_sc.function) {
if (error_ptr) {
error_ptr->SetErrorString("No function in symbol context.");
@@ -1194,7 +1200,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();
@@ -1411,7 +1417,7 @@ ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
Status error;
ValueObjectSP pointee = base->Dereference(error);
-
+
if (!pointee) {
return ValueObjectSP();
}
@@ -1499,7 +1505,7 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
Instruction::Operand::BuildRegister(reg));
for (VariableSP var_sp : variables) {
- if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
+ if (var_sp->LocationExpression().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 f8e8bfba970f0..2daf816d300c8 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
+# CHECK: Variable{{.*}}, name = "x2", {{.*}}, scope = parameter, location = 0x00000000: error: unexpected end of data
# CHECK: Variable{{.*}}, name = "x3", {{.*}}, scope = parameter, location =
# CHECK-NEXT: [0x0000000000000002, 0x0000000000000003): DW_OP_reg1 RDX
-# LOCLISTS: Variable{{.*}}, name = "x4", {{.*}}, scope = parameter
-# LOCLISTS-EMPTY:
+# LOCLISTS: Variable{{.*}}, name = "x4", {{.*}}, scope = parameter, location =
+# LOCLISTS-NEXT: DW_LLE_startx_length (0x000000000000dead, 0x0000000000000001): DW_OP_reg2 RCX
.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 c8eead3d28d29..a921641bcec54 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: [0x0000000000000000, 0x0000000000000001): DW_OP_reg0 RAX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000001, 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: [0x0000000000000001, 0x0000000000000002): DW_OP_reg1 RDX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000003, 0x0000000000000001): 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: [0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000005, 0x0000000000000001): 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: [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX
+# SYMBOLS-NEXT: Variable{{.*}}, name = "x", {{.*}}, location =
+# SYMBOLS-NEXT: DW_LLE_startx_length (0x0000000000000007, 0x0000000000000001): 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 62d7335384216..f58874f794eec 100644
--- a/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
@@ -23,7 +23,6 @@ static_library("Expression") {
include_dirs = [ ".." ]
sources = [
"DWARFExpression.cpp",
- "DWARFExpressionList.cpp",
"DiagnosticManager.cpp",
"Expression.cpp",
"ExpressionVariable.cpp",
More information about the lldb-commits
mailing list