kkcode0 updated this revision to Diff 555572.
kkcode0 added a comment.
formatting
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D143698/new/
https://reviews.llvm.org/D143698
Files:
lldb/include/lldb/Host/common/NativeRegisterContext.h
lldb/include/lldb/Target/RegisterContext.h
lldb/include/lldb/Utility/StringExtractorGDBRemote.h
lldb/source/Host/common/NativeRegisterContext.cpp
lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
lldb/source/Target/RegisterContext.cpp
lldb/source/Target/Thread.cpp
lldb/source/Utility/StringExtractorGDBRemote.cpp
lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
Index: lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
===================================================================
--- lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
+++ lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
@@ -37,11 +37,7 @@
# TLS works differently on Windows, this would need to be implemented
# separately.
- @skipIfWindows
- @expectedFailureAll(
- bugnumber="llvm.org/pr28392",
- oslist=no_match(lldbplatformutil.getDarwinOSTriples()),
- )
+ @skipIf(archs=no_match(['x86_64']), oslist=no_match(['linux']))
def test(self):
"""Test thread-local storage."""
self.build()
Index: lldb/source/Utility/StringExtractorGDBRemote.cpp
===================================================================
--- lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -210,6 +210,8 @@
return eServerPacketType_qGetProfileData;
if (PACKET_MATCHES("qGDBServerVersion"))
return eServerPacketType_qGDBServerVersion;
+ if (PACKET_STARTS_WITH("qGetTLSAddr"))
+ return eServerPacketType_qGetTLSAddr;
break;
case 'H':
Index: lldb/source/Target/Thread.cpp
===================================================================
--- lldb/source/Target/Thread.cpp
+++ lldb/source/Target/Thread.cpp
@@ -1623,7 +1623,11 @@
void Thread::SettingsTerminate() {}
-lldb::addr_t Thread::GetThreadPointer() { return LLDB_INVALID_ADDRESS; }
+lldb::addr_t Thread::GetThreadPointer() {
+ RegisterContext *reg_ctx = this->GetRegisterContext().get();
+ auto tp = reg_ctx->GetThreadPointer();
+ return tp;
+}
addr_t Thread::GetThreadLocalData(const ModuleSP module,
lldb::addr_t tls_file_addr) {
Index: lldb/source/Target/RegisterContext.cpp
===================================================================
--- lldb/source/Target/RegisterContext.cpp
+++ lldb/source/Target/RegisterContext.cpp
@@ -29,6 +29,10 @@
RegisterContext::~RegisterContext() = default;
+uint64_t RegisterContext::GetThreadPointer() {
+ return UINT64_MAX;
+}
+
void RegisterContext::InvalidateIfNeeded(bool force) {
ProcessSP process_sp(m_thread.GetProcess());
bool invalidate = force;
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -55,6 +55,8 @@
const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+ uint64_t GetThreadPointer() override;
+
size_t GetRegisterSetCount() override;
const RegisterSet *GetRegisterSet(size_t reg_set) override;
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -80,6 +80,19 @@
return m_reg_info_sp->GetRegisterSet(reg_set);
}
+uint64_t GDBRemoteRegisterContext::GetThreadPointer() {
+ ExecutionContext exe_ctx(CalculateThread());
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == nullptr || thread == nullptr)
+ return LLDB_INVALID_ADDRESS;
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
+ uint64_t tid = thread->GetProtocolID();
+ // Return thread pointer here, offset and link_map will be filled by GetThreadLocalData in DYLD
+ return gdb_comm.GetQGetTLSAddr(tid, LLDB_INVALID_ADDRESS /* offset */, LLDB_INVALID_ADDRESS /* lm */);
+}
+
bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) {
// Read the register
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -185,6 +185,8 @@
PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet);
+ PacketResult Handle_qGetTLSAddr(StringExtractorGDBRemote &packet);
+
PacketResult Handle_p(StringExtractorGDBRemote &packet);
PacketResult Handle_P(StringExtractorGDBRemote &packet);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -148,6 +148,9 @@
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
&GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qGetTLSAddr,
+ &GDBRemoteCommunicationServerLLGS::Handle_qGetTLSAddr);
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
&GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
@@ -2108,6 +2111,30 @@
return SendPacketNoLock("l");
}
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qGetTLSAddr(
+ StringExtractorGDBRemote &packet) {
+ llvm::StringRef s = packet.GetStringRef();
+ if (!s.consume_front("qGetTLSAddr:"))
+ return SendErrorResponse(8);
+ llvm::SmallVector<llvm::StringRef, 16> argv;
+ s.split(argv, ',');
+ lldb::tid_t tid = StringExtractor(argv[0]).GetU64(LLDB_INVALID_ADDRESS, 16);
+ lldb::addr_t offset = StringExtractor(argv[1]).GetU64(LLDB_INVALID_ADDRESS, 16);
+ lldb::addr_t lm = StringExtractor(argv[2]).GetU64(LLDB_INVALID_ADDRESS, 16);
+ (void) offset;
+ (void) lm;
+ NativeThreadProtocol *ntp = m_current_process->GetThreadByID(tid);
+ NativeRegisterContext ®_ctx = ntp->GetRegisterContext();
+ lldb::addr_t tp = LLDB_INVALID_ADDRESS;
+ StreamGDBRemote response;
+ if(!reg_ctx.ReadThreadPointer(tp).Fail()) {
+ response.PutHex64(tp, lldb::eByteOrderBig);
+ return SendPacketNoLock(response.GetString());
+ } else
+ return SendErrorResponse(8);
+}
+
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) {
Log *log = GetLog(LLDBLog::Thread);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -442,7 +442,9 @@
/// executable. If successful, the returned structure will contain at least
/// one value in the offsets field.
std::optional<QOffsets> GetQOffsets();
-
+
+ lldb::addr_t GetQGetTLSAddr(lldb::tid_t tid, lldb::addr_t offset, lldb::addr_t lms);
+
bool GetModuleInfo(const FileSpec &module_file_spec,
const ArchSpec &arch_spec, ModuleSpec &module_spec);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3752,6 +3752,28 @@
return std::nullopt;
}
+lldb::addr_t GDBRemoteCommunicationClient::GetQGetTLSAddr(lldb::tid_t tid, lldb::addr_t offset, lldb::addr_t lm) {
+ StreamString packet;
+ packet.PutCString("qGetTLSAddr:");
+ packet.PutHex64(tid, lldb::eByteOrderBig);
+ packet.PutCString(",");
+ packet.PutHex64(offset, lldb::eByteOrderBig);
+ packet.PutCString(",");
+ packet.PutHex64(lm, lldb::eByteOrderBig);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
+ PacketResult::Success)
+ return LLDB_INVALID_ADDRESS;
+ if (response.IsErrorResponse())
+ return LLDB_INVALID_ADDRESS;
+ if (response.IsUnsupportedResponse())
+ return LLDB_INVALID_ADDRESS;
+ llvm::StringRef ref = response.GetStringRef();
+ uint64_t addr = LLDB_INVALID_ADDRESS;
+ ref.consumeInteger(16, addr);
+ return addr;
+}
+
bool GDBRemoteCommunicationClient::GetModuleInfo(
const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
ModuleSpec &module_spec) {
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -37,6 +37,8 @@
uint32_t GetUserRegisterCount() const override;
+ Status ReadThreadPointer(uint64_t &tp) override;
+
Status ReadRegister(const RegisterInfo *reg_info,
RegisterValue ®_value) override;
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -13,6 +13,7 @@
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/linux/Ptrace.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
@@ -373,6 +374,16 @@
m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
}
+Status NativeRegisterContextLinux_x86_64::ReadThreadPointer(uint64_t& tp) {
+ Status error;
+ errno = 0;
+ auto ret= ptrace(static_cast<__ptrace_request>(PTRACE_ARCH_PRCTL), m_thread.GetID(),
+ &tp, (void *)ARCH_GET_FS, 0);
+ if (ret == -1)
+ error.SetErrorToErrno();
+ return error;
+}
+
// CONSIDER after local and llgs debugging are merged, register set support can
// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -82,6 +82,8 @@
"Architecture does not support memory tagging");
}
+ virtual Status ReadThreadPointer(uint64_t &tp) override;
+
protected:
// NB: This constructor is here only because gcc<=6.5 requires a virtual base
// class initializer on abstract class (even though it is never used). It can
@@ -105,7 +107,6 @@
virtual Status ReadGPR();
virtual Status WriteGPR();
-
virtual Status ReadFPR();
virtual Status WriteFPR();
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -112,6 +112,12 @@
GetFPRSize());
}
+Status NativeRegisterContextLinux::ReadThreadPointer(uint64_t &tp) {
+ tp = LLDB_INVALID_ADDRESS;
+ Status error;
+ return error;
+}
+
Status NativeRegisterContextLinux::WriteFPR() {
return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
nullptr, GetFPRBuffer(),
Index: lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -183,14 +183,7 @@
LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
__FUNCTION__);
-
- if (!SetRendezvousBreakpoint()) {
- // If we cannot establish rendezvous breakpoint right now we'll try again
- // at entry point.
- ProbeEntry();
- }
-
- LoadVDSO();
+ ProbeEntry();
m_process->GetTarget().ModulesDidLoad(module_list);
}
}
@@ -200,7 +193,7 @@
void DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module,
addr_t link_map_addr,
addr_t base_addr,
- bool base_addr_is_offset) {
+ bool base_addr_is_offset) {
m_loaded_modules[module] = link_map_addr;
UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
}
@@ -731,48 +724,48 @@
if (it == m_loaded_modules.end())
return LLDB_INVALID_ADDRESS;
- addr_t link_map = it->second;
- if (link_map == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
- if (!metadata.valid)
- return LLDB_INVALID_ADDRESS;
-
- // Get the thread pointer.
- addr_t tp = thread->GetThreadPointer();
- if (tp == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the module's modid.
- int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
- int64_t modid = ReadUnsignedIntWithSizeInBytes(
- link_map + metadata.modid_offset, modid_size);
- if (modid == -1)
- return LLDB_INVALID_ADDRESS;
-
- // Lookup the DTV structure for this thread.
- addr_t dtv_ptr = tp + metadata.dtv_offset;
- addr_t dtv = ReadPointer(dtv_ptr);
- if (dtv == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the TLS block for this module.
- addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
- addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
-
- Log *log = GetLog(LLDBLog::DynamicLoader);
- LLDB_LOGF(log,
- "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
- ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
- module_sp->GetObjectName().AsCString(""), link_map, tp,
- (int64_t)modid, tls_block);
-
- if (tls_block == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
- else
- return tls_block + tls_file_addr;
+ addr_t link_map = it->second;
+ if (link_map == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
+ if (!metadata.valid)
+ return LLDB_INVALID_ADDRESS;
+
+ // Get the thread pointer.
+ addr_t tp = thread->GetThreadPointer();
+ if (tp == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the module's modid.
+ int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
+ int64_t modid = ReadUnsignedIntWithSizeInBytes(
+ link_map + metadata.modid_offset, modid_size);
+ if (modid == -1)
+ return LLDB_INVALID_ADDRESS;
+
+ // Lookup the DTV structure for this thread.
+ addr_t dtv_ptr = tp + metadata.dtv_offset;
+ addr_t dtv = ReadPointer(dtv_ptr);
+ if (dtv == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the TLS block for this module.
+ addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
+ addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
+
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
+ module_sp->GetObjectName().AsCString(""), link_map, tp,
+ (int64_t)modid, tls_block);
+
+ if (tls_block == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ else
+ return tls_block + tls_file_addr;
}
void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
Index: lldb/source/Host/common/NativeRegisterContext.cpp
===================================================================
--- lldb/source/Host/common/NativeRegisterContext.cpp
+++ lldb/source/Host/common/NativeRegisterContext.cpp
@@ -120,6 +120,12 @@
return nullptr;
}
+Status NativeRegisterContext::ReadThreadPointer(uint64_t& tp) {
+ tp = LLDB_INVALID_ADDRESS;
+ Status error;
+ return error;
+}
+
lldb::addr_t NativeRegisterContext::GetPC(lldb::addr_t fail_value) {
Log *log = GetLog(LLDBLog::Thread);
Index: lldb/include/lldb/Utility/StringExtractorGDBRemote.h
===================================================================
--- lldb/include/lldb/Utility/StringExtractorGDBRemote.h
+++ lldb/include/lldb/Utility/StringExtractorGDBRemote.h
@@ -109,6 +109,7 @@
eServerPacketType_jThreadsInfo,
eServerPacketType_qsThreadInfo,
eServerPacketType_qfThreadInfo,
+ eServerPacketType_qGetTLSAddr,
eServerPacketType_qGetPid,
eServerPacketType_qGetProfileData,
eServerPacketType_qGDBServerVersion,
Index: lldb/include/lldb/Target/RegisterContext.h
===================================================================
--- lldb/include/lldb/Target/RegisterContext.h
+++ lldb/include/lldb/Target/RegisterContext.h
@@ -37,6 +37,15 @@
virtual lldb::ByteOrder GetByteOrder();
+ /// Retrieves the per-thread data area.
+ /// Most OSs maintain a per-thread pointer (e.g. the FS register on
+ /// x64), which we return the value of here.
+ ///
+ /// \return
+ /// LLDB_INVALID_ADDRESS if not supported, otherwise the thread
+ /// pointer value.
+ virtual uint64_t GetThreadPointer();
+
virtual bool ReadRegister(const RegisterInfo *reg_info,
RegisterValue ®_value) = 0;
Index: lldb/include/lldb/Host/common/NativeRegisterContext.h
===================================================================
--- lldb/include/lldb/Host/common/NativeRegisterContext.h
+++ lldb/include/lldb/Host/common/NativeRegisterContext.h
@@ -48,6 +48,8 @@
virtual Status ReadRegister(const RegisterInfo *reg_info,
RegisterValue ®_value) = 0;
+ virtual Status ReadThreadPointer(uint64_t &tp);
+
virtual Status WriteRegister(const RegisterInfo *reg_info,
const RegisterValue ®_value) = 0;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits