@@ -118,6 +118,12 @@ void DynamicLoaderDumpWithModuleList::LoadAllModules(
118118 LoadModuleCallback callback) {
119119
120120 if (m_rendezvous.Resolve ()) {
121+ // The rendezvous class doesn't enumerate the main module, so track that
122+ // ourselves here.
123+ ModuleSP executable = GetTargetExecutable ();
124+ if (executable)
125+ m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress ();
126+
121127 DYLDRendezvous::iterator I;
122128 DYLDRendezvous::iterator E;
123129 for (I = m_rendezvous.begin (), E = m_rendezvous.end (); I != E; ++I) {
@@ -127,7 +133,7 @@ void DynamicLoaderDumpWithModuleList::LoadAllModules(
127133 GetModuleInfo (I->base_addr );
128134 if (mod_info_opt.has_value ())
129135 (*mod_info_opt).get_size (module_size);
130- callback (I->file_spec .GetPath (), I->base_addr , module_size);
136+ callback (I->file_spec .GetPath (), I->base_addr , module_size, I-> link_addr );
131137 }
132138
133139 DetectModuleListMismatch ();
@@ -159,7 +165,7 @@ void DynamicLoaderDumpWithModuleList::LoadAllModules(
159165 !mod_info.get_size (module_size) || !ShouldLoadModule (name))
160166 continue ;
161167
162- callback (SanitizeName (name), base_addr, module_size);
168+ callback (SanitizeName (name), base_addr, module_size, /* link_map_addr= */ 0 );
163169 }
164170 }
165171}
@@ -196,12 +202,11 @@ void DynamicLoaderDumpWithModuleList::DidAttach() {
196202
197203 ModuleList module_list;
198204 LoadAllModules ([&](const std::string &name, addr_t base_addr,
199- addr_t module_size) {
205+ addr_t module_size, addr_t link_map_addr ) {
200206 // vdso module has already been loaded.
201207 if (base_addr == m_vdso_base)
202208 return ;
203209
204- addr_t link_map_addr = 0 ;
205210 FileSpec file (name, m_process->GetTarget ().GetArchitecture ().GetTriple ());
206211 const bool base_addr_is_offset = false ;
207212 ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress (
@@ -224,6 +229,7 @@ void DynamicLoaderDumpWithModuleList::DidAttach() {
224229 base_addr_is_offset);
225230 m_process->GetTarget ().GetImages ().Append (module_sp, /* notify*/ true );
226231 }
232+ m_loaded_modules[module_sp] = link_map_addr;
227233 });
228234
229235 m_process->GetTarget ().ModulesDidLoad (module_list);
@@ -260,3 +266,82 @@ void DynamicLoaderDumpWithModuleList::LoadVDSO() {
260266lldb_private::Status DynamicLoaderDumpWithModuleList::CanLoadImage () {
261267 return Status ();
262268}
269+
270+ // TODO: refactor and merge this implementation with
271+ // DynamicLoaderPOSIXDYLD::GetThreadLocalData
272+ lldb::addr_t DynamicLoaderDumpWithModuleList::GetThreadLocalData (
273+ const lldb::ModuleSP module_sp, const lldb::ThreadSP thread,
274+ lldb::addr_t tls_file_addr) {
275+ Log *log = GetLog (LLDBLog::DynamicLoader);
276+ auto it = m_loaded_modules.find (module_sp);
277+ if (it == m_loaded_modules.end ()) {
278+ LLDB_LOGF (
279+ log, " GetThreadLocalData error: module(%s) not found in loaded modules" ,
280+ module_sp->GetObjectName ().AsCString ());
281+ return LLDB_INVALID_ADDRESS;
282+ }
283+
284+ addr_t link_map = it->second ;
285+ if (link_map == LLDB_INVALID_ADDRESS || link_map == 0 ) {
286+ LLDB_LOGF (log,
287+ " GetThreadLocalData error: invalid link map address=0x%" PRIx64,
288+ link_map);
289+ return LLDB_INVALID_ADDRESS;
290+ }
291+
292+ const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo ();
293+ if (!metadata.valid ) {
294+ LLDB_LOGF (log,
295+ " GetThreadLocalData error: fail to read thread info metadata" );
296+ return LLDB_INVALID_ADDRESS;
297+ }
298+
299+ LLDB_LOGF (log,
300+ " GetThreadLocalData info: link_map=0x%" PRIx64
301+ " , thread info metadata: "
302+ " modid_offset=0x%" PRIx32 " , dtv_offset=0x%" PRIx32
303+ " , tls_offset=0x%" PRIx32 " , dtv_slot_size=%" PRIx32 " \n " ,
304+ link_map, metadata.modid_offset , metadata.dtv_offset ,
305+ metadata.tls_offset , metadata.dtv_slot_size );
306+
307+ // Get the thread pointer.
308+ addr_t tp = thread->GetThreadPointer ();
309+ if (tp == LLDB_INVALID_ADDRESS) {
310+ LLDB_LOGF (log, " GetThreadLocalData error: fail to read thread pointer" );
311+ return LLDB_INVALID_ADDRESS;
312+ }
313+
314+ // Find the module's modid.
315+ int modid_size = 4 ; // FIXME(spucci): This isn't right for big-endian 64-bit
316+ int64_t modid = ReadUnsignedIntWithSizeInBytes (
317+ link_map + metadata.modid_offset , modid_size);
318+ if (modid == -1 ) {
319+ LLDB_LOGF (log, " GetThreadLocalData error: fail to read modid" );
320+ return LLDB_INVALID_ADDRESS;
321+ }
322+
323+ // Lookup the DTV structure for this thread.
324+ addr_t dtv_ptr = tp + metadata.dtv_offset ;
325+ addr_t dtv = ReadPointer (dtv_ptr);
326+ if (dtv == LLDB_INVALID_ADDRESS) {
327+ LLDB_LOGF (log, " GetThreadLocalData error: fail to read dtv" );
328+ return LLDB_INVALID_ADDRESS;
329+ }
330+
331+ // Find the TLS block for this module.
332+ addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
333+ addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset );
334+
335+ LLDB_LOGF (log,
336+ " DynamicLoaderDumpWithModuleList::Performed TLS lookup: "
337+ " module=%s, link_map=0x%" PRIx64 " , tp=0x%" PRIx64
338+ " , modid=%" PRId64 " , tls_block=0x%" PRIx64 " \n " ,
339+ module_sp->GetObjectName ().AsCString (" " ), link_map, tp,
340+ (int64_t )modid, tls_block);
341+
342+ if (tls_block == LLDB_INVALID_ADDRESS) {
343+ LLDB_LOGF (log, " GetThreadLocalData error: fail to read tls_block" );
344+ return LLDB_INVALID_ADDRESS;
345+ } else
346+ return tls_block + tls_file_addr;
347+ }
0 commit comments