Skip to content
Closed
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
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/Variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
return m_location_list;
}

bool IsThreadLocal() const;

// When given invalid address, it dumps all locations. Otherwise it only dumps
// the location that contains this address.
bool DumpLocations(Stream *s, const Address &address);
Expand Down
33 changes: 32 additions & 1 deletion lldb/source/Core/ValueObjectVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,38 @@ bool ValueObjectVariable::UpdateValue() {
m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
}
}

if (m_error.Fail() && variable->IsThreadLocal()) {
ExecutionContext exe_ctx(GetExecutionContextRef());
Thread *thread = exe_ctx.GetThreadPtr();
lldb::ModuleSP module_sp = GetModule();
if (!thread) {
m_error = Status::FromErrorString("no thread to evaluate TLS within");
return m_error.Success();
}
std::vector<uint32_t> symbol_indexes;
module_sp->GetSymtab()->FindAllSymbolsWithNameAndType(
ConstString(variable->GetName()), lldb::SymbolType::eSymbolTypeAny,
symbol_indexes);
Symbol *symbol = module_sp->GetSymtab()->SymbolAtIndex(symbol_indexes[0]);
lldb::addr_t tls_file_addr =
symbol->GetAddress().GetOffset() +
symbol->GetAddress().GetSection()->GetFileAddress();
const lldb::addr_t tls_load_addr =
thread->GetThreadLocalData(module_sp, tls_file_addr);
if (tls_load_addr == LLDB_INVALID_ADDRESS)
m_error = Status::FromErrorString(
"no TLS data currently exists for this thread");
else {
Value old_value(m_value);
m_value.GetScalar() = tls_load_addr;
m_value.SetContext(Value::ContextType::Variable, variable);
m_value.SetValueType(Value::ValueType::LoadAddress);
m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
m_value.GetScalar() != old_value.GetScalar());
SetValueIsValid(m_error.Success());
}
}
return m_error.Success();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -771,9 +771,12 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
"GetThreadLocalData info: link_map=0x%" PRIx64
", thread info metadata: "
"modid_offset=0x%" PRIx32 ", dtv_offset=0x%" PRIx32
", tls_offset=0x%" PRIx32 ", dtv_slot_size=%" PRIx32 "\n",
", tls_offset=0x%" PRIx32 ", dtv_slot_size=%" PRIx32
", tls_file_addr=0x%" PRIx64 ", module name=%s "
"\n",
link_map, metadata.modid_offset, metadata.dtv_offset,
metadata.tls_offset, metadata.dtv_slot_size);
metadata.tls_offset, metadata.dtv_slot_size, tls_file_addr,
module_sp->GetFileSpec().GetFilename().AsCString());

// Get the thread pointer.
addr_t tp = thread->GetThreadPointer();
Expand All @@ -790,9 +793,12 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
LLDB_LOGF(log, "GetThreadLocalData error: fail to read modid");
return LLDB_INVALID_ADDRESS;
}

const llvm::Triple &triple_ref =
m_process->GetTarget().GetArchitecture().GetTriple();
// Lookup the DTV structure for this thread.
addr_t dtv_ptr = tp + metadata.dtv_offset;
addr_t dtv_ptr = tp;
if (triple_ref.getArch() != llvm::Triple::aarch64)
dtv_ptr = dtv_ptr + metadata.dtv_offset;
addr_t dtv = ReadPointer(dtv_ptr);
if (dtv == LLDB_INVALID_ADDRESS) {
LLDB_LOGF(log, "GetThreadLocalData error: fail to read dtv");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,20 @@
#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT

static lldb_private::RegisterInfo g_register_infos_pauth[] = {
DEFINE_EXTENSION_REG(data_mask), DEFINE_EXTENSION_REG(code_mask)};
DEFINE_EXTENSION_REG(data_mask, KIND_ALL_INVALID),
DEFINE_EXTENSION_REG(code_mask, KIND_ALL_INVALID)};

static lldb_private::RegisterInfo g_register_infos_mte[] = {
DEFINE_EXTENSION_REG(mte_ctrl)};
DEFINE_EXTENSION_REG(mte_ctrl, KIND_ALL_INVALID)};

static lldb_private::RegisterInfo g_register_infos_tls[] = {
DEFINE_EXTENSION_REG(tpidr),
DEFINE_EXTENSION_REG(tpidr, GENERIC_KIND(LLDB_REGNUM_GENERIC_TP)),
// Only present when SME is present
DEFINE_EXTENSION_REG(tpidr2)};
DEFINE_EXTENSION_REG(tpidr2, KIND_ALL_INVALID)};

static lldb_private::RegisterInfo g_register_infos_sme[] = {
DEFINE_EXTENSION_REG(svcr),
DEFINE_EXTENSION_REG(svg),
DEFINE_EXTENSION_REG(svcr, KIND_ALL_INVALID),
DEFINE_EXTENSION_REG(svg, KIND_ALL_INVALID),
// 16 is a default size we will change later.
{"za", nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8,
KIND_ALL_INVALID, nullptr, nullptr, nullptr}};
Expand All @@ -95,7 +96,7 @@ static lldb_private::RegisterInfo g_register_infos_sme2[] = {
KIND_ALL_INVALID, nullptr, nullptr, nullptr}};

static lldb_private::RegisterInfo g_register_infos_fpmr[] = {
DEFINE_EXTENSION_REG(fpmr)};
DEFINE_EXTENSION_REG(fpmr, KIND_ALL_INVALID)};

// Number of register sets provided by this context.
enum {
Expand Down
11 changes: 9 additions & 2 deletions lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,13 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
LLDB_INVALID_REGNUM, lldb_kind \
}

// Generates register kinds array for registers with only generic kind
#define GENERIC_KIND(generic_kind) \
{ \
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic_kind, \
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM \
}

// Generates register kinds array for registers with only lldb kind
#define KIND_ALL_INVALID \
{ \
Expand Down Expand Up @@ -535,10 +542,10 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
}

// Defines pointer authentication mask registers
#define DEFINE_EXTENSION_REG(reg) \
#define DEFINE_EXTENSION_REG(reg, kind) \
{ \
#reg, nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \
KIND_ALL_INVALID, nullptr, nullptr, nullptr, \
kind, nullptr, nullptr, nullptr, \
}

static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
Expand Down
7 changes: 2 additions & 5 deletions lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
const char *mangled_cstr = nullptr;
bool is_declaration = false;
bool has_address = false;
bool has_location_or_const_value = false;
bool is_global_or_static_variable = false;

DWARFFormValue specification_die_form;
Expand Down Expand Up @@ -269,9 +268,6 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,

case DW_AT_location:
case DW_AT_const_value:
has_location_or_const_value = true;
is_global_or_static_variable = die.IsGlobalOrStaticScopeVariable();

break;

case DW_AT_specification:
Expand Down Expand Up @@ -363,7 +359,8 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
break;

case DW_TAG_variable:
if (name && has_location_or_const_value && is_global_or_static_variable) {
is_global_or_static_variable = die.IsGlobalOrStaticScopeVariable();
if (name && is_global_or_static_variable) {
set.globals.Insert(ConstString(name), ref);
// Be sure to include variables by their mangled and demangled names if
// they have any since a variable can have a basename "i", a mangled
Expand Down
9 changes: 9 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3499,6 +3499,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
DWARFFormValue type_die_form;
bool is_external = false;
bool is_artificial = false;
bool is_declaration = false;
DWARFFormValue const_value_form, location_form;
Variable::RangeList scope_ranges;

Expand Down Expand Up @@ -3545,6 +3546,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
is_artificial = form_value.Boolean();
break;
case DW_AT_declaration:
is_declaration = form_value.Boolean();
break;
case DW_AT_description:
case DW_AT_endianity:
case DW_AT_segment:
Expand All @@ -3557,6 +3560,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}
}

// If It's a declaration then symbol not present in this symbolfile
// return early to try other linked objects.
if (is_declaration) {
return nullptr;
}

// Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
// for static constexpr member variables -- DW_AT_const_value and
// DW_AT_location will both be present in the DIE defining the member.
Expand Down
13 changes: 13 additions & 0 deletions lldb/source/Symbol/Variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,19 @@ Status Variable::GetValuesForVariableExpressionPath(
return error;
}

bool Variable::IsThreadLocal() const {
ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
// Give the symbol vendor a chance to add to the unified section list.
module_sp->GetSymbolFile();
std::vector<uint32_t> symbol_indexes;
module_sp->GetSymtab()->FindAllSymbolsWithNameAndType(
ConstString(GetName()), lldb::SymbolType::eSymbolTypeAny, symbol_indexes);
if (symbol_indexes.empty())
return false;
Symbol *symbol = module_sp->GetSymtab()->SymbolAtIndex(symbol_indexes[0]);
return symbol->GetAddress().GetSection()->IsThreadSpecific();
}

bool Variable::DumpLocations(Stream *s, const Address &address) {
SymbolContext sc;
CalculateSymbolContext(&sc);
Expand Down