Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lldb/include/lldb/Expression/DWARFExpressionList.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
#define LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H

#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Utility/RangeMap.h"
Expand Down Expand Up @@ -59,6 +60,21 @@ class DWARFExpressionList {

lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }

/// Represents an entry in the DWARFExpressionList with all needed metadata.
struct DWARFExpressionEntry {
/// Represents a DWARF location range in the DWARF unit’s file‐address space
std::optional<AddressRange> file_range; ///< None = always-valid single expr
const DWARFExpression *expr;
};

/// Returns a DWARFExpressionEntry whose file_range contains the given
/// load‐address. `func_load_addr` is the load‐address of the function
/// start; `load_addr` is the full runtime PC. On success, `expr` is
/// non-null.
std::optional<DWARFExpressionEntry>
GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
lldb::addr_t load_addr) const;

const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr,
lldb::addr_t load_addr) const;

Expand Down
35 changes: 34 additions & 1 deletion lldb/source/Expression/DWARFExpressionList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
Expand All @@ -20,7 +21,7 @@ bool DWARFExpressionList::IsAlwaysValidSingleExpr() const {
return GetAlwaysValidExpr() != nullptr;
}

const DWARFExpression * DWARFExpressionList::GetAlwaysValidExpr() const {
const DWARFExpression *DWARFExpressionList::GetAlwaysValidExpr() const {
if (m_exprs.GetSize() != 1)
return nullptr;
const auto *expr = m_exprs.GetEntryAtIndex(0);
Expand Down Expand Up @@ -53,6 +54,38 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t func_load_addr,
return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
}

std::optional<DWARFExpressionList::DWARFExpressionEntry>
DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
lldb::addr_t load_addr) const {
if (const DWARFExpression *always = GetAlwaysValidExpr()) {
return DWARFExpressionEntry{std::nullopt, always};
}

if (func_load_addr == LLDB_INVALID_ADDRESS)
func_load_addr = m_func_file_addr;

// Guard against underflow when translating a load address back into file
// space.
if (load_addr < func_load_addr)
return std::nullopt;

// Guard against overflow.
lldb::addr_t delta = load_addr - func_load_addr;
if (delta > std::numeric_limits<lldb::addr_t>::max() - m_func_file_addr)
return std::nullopt;

lldb::addr_t file_pc = (load_addr - func_load_addr) + m_func_file_addr;

if (const auto *entry = m_exprs.FindEntryThatContains(file_pc)) {
AddressRange range_in_file(entry->GetRangeBase(),
entry->GetRangeEnd() - entry->GetRangeBase());
return DWARFExpressionEntry{range_in_file, &entry->data};
}

// No entry covers this PC:
return std::nullopt;
}

const DWARFExpression *
DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t func_load_addr,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity: Do we still need this API, or is it just a subset of the function above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you know the new function GetExpressionEntryAtAddress, does almost exact same thing as this one. I don't see this function being used anywhere else in the lldb code base, so maybe it can be removed, but to be safe I did not want to alter it. But from what I can tell, it should be okay to remove it. We can also choose to keep it and maybe refactor it to just call the GetExpressionEntryAtAddress and just return the DWARFExpression *expr.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's completely unused, and there is no indication that was added in support of any downstream clients (either as a comment or in the commit message) we could consider deleting it in a separate PR. Not urgent.

lldb::addr_t load_addr) const {
Expand Down
Loading