LLDB mainline
DynamicLoaderDarwin.cpp
Go to the documentation of this file.
1//===-- DynamicLoaderDarwin.cpp -------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
12#include "lldb/Core/Debugger.h"
13#include "lldb/Core/Module.h"
16#include "lldb/Core/Section.h"
19#include "lldb/Host/HostInfo.h"
22#include "lldb/Target/ABI.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Target/Thread.h"
34#include "lldb/Utility/Log.h"
35#include "lldb/Utility/State.h"
36#include "llvm/Support/ThreadPool.h"
37
40
41//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
42#ifdef ENABLE_DEBUG_PRINTF
43#include <cstdio>
44#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
45#else
46#define DEBUG_PRINTF(fmt, ...)
47#endif
48
49#include <memory>
50
51using namespace lldb;
52using namespace lldb_private;
53
54// Constructor
59
60// Destructor
62
63/// Called after attaching a process.
64///
65/// Allow DynamicLoader plug-ins to execute some code after
66/// attaching to a process.
72
73/// Called after attaching a process.
74///
75/// Allow DynamicLoader plug-ins to execute some code after
76/// attaching to a process.
82
83// Clear out the state of this class.
84void DynamicLoaderDarwin::Clear(bool clear_process) {
85 std::lock_guard<std::recursive_mutex> guard(m_mutex);
86 if (clear_process)
87 m_process = nullptr;
88 m_dyld_image_infos.clear();
90 m_dyld.Clear(false);
91}
92
94 const ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
95 if (did_create_ptr)
96 *did_create_ptr = false;
97
98 Target &target = m_process->GetTarget();
99 const ModuleList &target_images = target.GetImages();
100 ModuleSpec module_spec(image_info.file_spec);
101 module_spec.GetUUID() = image_info.uuid;
102
103 // macCatalyst support: Request matching os/environment.
104 {
105 auto &target_triple = target.GetArchitecture().GetTriple();
106 if (target_triple.getOS() == llvm::Triple::IOS &&
107 target_triple.getEnvironment() == llvm::Triple::MacABI) {
108 // Request the macCatalyst variant of frameworks that have both
109 // a PLATFORM_MACOS and a PLATFORM_MACCATALYST load command.
110 module_spec.GetArchitecture() = ArchSpec(target_triple);
111 }
112 }
113
114 ModuleSP module_sp(target_images.FindFirstModule(module_spec));
115
116 if (module_sp && !module_spec.GetUUID().IsValid() &&
117 !module_sp->GetUUID().IsValid()) {
118 // No UUID, we must rely upon the cached module modification time and the
119 // modification time of the file on disk
120 if (module_sp->GetModificationTime() !=
121 FileSystem::Instance().GetModificationTime(module_sp->GetFileSpec()))
122 module_sp.reset();
123 }
124
125 if (module_sp || !can_create)
126 return module_sp;
127
128 // See if we have this binary in the Target or the global Module
129 // cache already.
130 module_sp = target.GetOrCreateModule(module_spec, /*notify=*/false);
131
132 if (!module_sp &&
133 HostInfo::GetArchitecture().IsCompatibleMatch(target.GetArchitecture())) {
134
135 SharedCacheImageInfo image_info;
136
137 // If we have a shared cache filepath and UUID, ask HostInfo
138 // if it can provide the SourceCacheImageInfo for the binary
139 // out of that shared cache. Search by the Module's UUID if
140 // available, else the filepath.
141 addr_t sc_base_addr;
142 UUID sc_uuid;
143 LazyBool using_sc;
144 LazyBool private_sc;
145 FileSpec sc_path;
146 std::optional<uint64_t> size;
149 if (GetSharedCacheInformation(sc_base_addr, sc_uuid, using_sc, private_sc,
150 sc_path, size) &&
151 sc_uuid) {
152 if (module_spec.GetUUID())
153 image_info = HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(),
154 sc_uuid, sc_mode);
155
156 else {
157 std::string filepath = module_spec.GetFileSpec().GetPath();
158 image_info =
159 HostInfo::GetSharedCacheImageInfo(filepath, sc_uuid, sc_mode);
160 }
161 } else {
162 // Fall back to looking lldb's own shared cache by filename
163 std::string filepath = module_spec.GetFileSpec().GetPath();
164 image_info = HostInfo::GetSharedCacheImageInfo(filepath, sc_mode);
165 }
166
167 // If we found it and it has the correct UUID, let's proceed with
168 // creating a module from the memory contents.
169 if (image_info.GetUUID() &&
170 (!module_spec.GetUUID() ||
171 module_spec.GetUUID() == image_info.GetUUID())) {
172 ModuleSpec shared_cache_spec(module_spec.GetFileSpec(),
173 image_info.GetUUID(),
174 image_info.GetExtractor());
175 module_sp =
176 target.GetOrCreateModule(shared_cache_spec, false /* notify */);
177 }
178 }
179 // We'll call Target::ModulesDidLoad after all the modules have been
180 // added to the target, don't let it be called for every one.
181 if (!module_sp || module_sp->GetObjectFile() == nullptr) {
182 llvm::Expected<ModuleSP> module_sp_or_err = m_process->ReadModuleFromMemory(
183 image_info.file_spec, image_info.address,
184 image_info.mh_and_load_cmd_size);
185 if (auto err = module_sp_or_err.takeError()) {
187 "Failed to load module from memory: {0}");
188 return {};
189 }
190 module_sp = *module_sp_or_err;
191 }
192
193 if (did_create_ptr)
194 *did_create_ptr = (bool)module_sp;
195
196 return module_sp;
197}
198
200 const std::vector<lldb::addr_t> &solib_addresses) {
201 std::lock_guard<std::recursive_mutex> guard(m_mutex);
202 if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
203 return;
204
206 Target &target = m_process->GetTarget();
207 LLDB_LOGF(log, "Removing %" PRId64 " modules.",
208 (uint64_t)solib_addresses.size());
209
210 ModuleList unloaded_module_list;
211
212 for (addr_t solib_addr : solib_addresses) {
213 Address header;
214 if (header.SetLoadAddress(solib_addr, &target)) {
215 if (header.GetOffset() == 0) {
216 ModuleSP module_to_remove(header.GetModule());
217 if (module_to_remove.get()) {
218 LLDB_LOGF(log, "Removing module at address 0x%" PRIx64, solib_addr);
219 // remove the sections from the Target
220 UnloadSections(module_to_remove);
221 // add this to the list of modules to remove
222 unloaded_module_list.AppendIfNeeded(module_to_remove);
223 // remove the entry from the m_dyld_image_infos
224 ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
225 for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
226 if (solib_addr == (*pos).address) {
227 m_dyld_image_infos.erase(pos);
228 break;
229 }
230 }
231 }
232 }
233 }
234 }
235
236 if (unloaded_module_list.GetSize() > 0) {
237 if (log) {
238 log->PutCString("Unloaded:");
239 unloaded_module_list.LogUUIDAndPaths(
240 log, "DynamicLoaderDarwin::UnloadModules");
241 }
242 m_process->GetTarget().GetImages().Remove(unloaded_module_list);
244 }
245}
246
249 ModuleList unloaded_modules_list;
250
251 Target &target = m_process->GetTarget();
252 const ModuleList &target_modules = target.GetImages();
253 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
254
255 ModuleSP dyld_sp(GetDYLDModule());
256 for (ModuleSP module_sp : target_modules.Modules()) {
257 // Don't remove dyld - else we'll lose our breakpoint notifying us about
258 // libraries being re-loaded...
259 if (module_sp && module_sp != dyld_sp) {
260 UnloadSections(module_sp);
261 unloaded_modules_list.Append(module_sp);
262 }
263 }
264
265 if (unloaded_modules_list.GetSize() != 0) {
266 if (log) {
267 log->PutCString("Unloaded:");
268 unloaded_modules_list.LogUUIDAndPaths(
269 log, "DynamicLoaderDarwin::UnloadAllImages");
270 }
271 target.GetImages().Remove(unloaded_modules_list);
272 m_dyld_image_infos.clear();
274 }
275}
276
277// Update the load addresses for all segments in MODULE using the updated INFO
278// that is passed in.
280 ImageInfo &info) {
281 bool changed = false;
283 if (module) {
284 ObjectFile *image_object_file = module->GetObjectFile();
285 if (image_object_file) {
286 SectionList *section_list = image_object_file->GetSectionList();
287 if (section_list) {
288 std::vector<uint32_t> inaccessible_segment_indexes;
289 // We now know the slide amount, so go through all sections and update
290 // the load addresses with the correct values.
291 const size_t num_segments = info.segments.size();
292 for (size_t i = 0; i < num_segments; ++i) {
293 // Only load a segment if it has protections. Things like __PAGEZERO
294 // don't have any protections, and they shouldn't be slid
295 SectionSP section_sp(
296 section_list->FindSectionByName(info.segments[i].name));
297
298 if (info.segments[i].maxprot == 0) {
299 inaccessible_segment_indexes.push_back(i);
300 } else {
301 const addr_t new_section_load_addr =
302 info.segments[i].vmaddr + info.slide;
303 static ConstString g_section_name_LINKEDIT("__LINKEDIT");
304
305 if (section_sp) {
306 // __LINKEDIT sections from files in the shared cache can overlap
307 // so check to see what the segment name is and pass "false" so
308 // we don't warn of overlapping "Section" objects, and "true" for
309 // all other sections.
310 const bool warn_multiple =
311 section_sp->GetName() != g_section_name_LINKEDIT;
312
313 // If a segment was eliminated for the in-memory image,
314 // don't map it into lldb's target section load list.
315 if (info.segments[i].vmsize == 0) {
316 LLDB_LOG(log, "{0}: Omitting zero-size segment {1}",
317 info.file_spec.GetFilename(), info.segments[i].name);
318 continue;
319 }
320
321 if (info.segments[i].vmsize != section_sp->GetByteSize())
322 LLDB_LOG(log,
323 "{0}: In-memory segment size for {1} is {2:x}"
324 " but file segment size is {3:x}",
325 info.file_spec.GetFilename(), info.segments[i].name,
326 info.segments[i].vmsize, section_sp->GetByteSize());
327
328 changed = m_process->GetTarget().SetSectionLoadAddress(
329 section_sp, new_section_load_addr, warn_multiple);
330 }
331 }
332 }
333
334 // If the loaded the file (it changed) and we have segments that are
335 // not readable or writeable, add them to the invalid memory region
336 // cache for the process. This will typically only be the __PAGEZERO
337 // segment in the main executable. We might be able to apply this more
338 // generally to more sections that have no protections in the future,
339 // but for now we are going to just do __PAGEZERO.
340 if (changed && !inaccessible_segment_indexes.empty()) {
341 for (uint32_t i = 0; i < inaccessible_segment_indexes.size(); ++i) {
342 const uint32_t seg_idx = inaccessible_segment_indexes[i];
343 SectionSP section_sp(
344 section_list->FindSectionByName(info.segments[seg_idx].name));
345
346 if (section_sp) {
347 static ConstString g_pagezero_section_name("__PAGEZERO");
348 if (g_pagezero_section_name == section_sp->GetName()) {
349 // __PAGEZERO never slides...
350 const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
351 const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
352 Process::LoadRange pagezero_range(vmaddr, vmsize);
353 m_process->AddInvalidMemoryRegion(pagezero_range);
354 }
355 }
356 }
357 }
358 }
359 }
360 }
361 // We might have an in memory image that was loaded as soon as it was created
362 if (info.load_stop_id == m_process->GetStopID())
363 changed = true;
364 else if (changed) {
365 // Update the stop ID when this library was updated
366 info.load_stop_id = m_process->GetStopID();
367 }
368 return changed;
369}
370
371// Unload the segments in MODULE using the INFO that is passed in.
373 ImageInfo &info) {
374 bool changed = false;
375 if (module) {
376 ObjectFile *image_object_file = module->GetObjectFile();
377 if (image_object_file) {
378 SectionList *section_list = image_object_file->GetSectionList();
379 if (section_list) {
380 const size_t num_segments = info.segments.size();
381 for (size_t i = 0; i < num_segments; ++i) {
382 SectionSP section_sp(
383 section_list->FindSectionByName(info.segments[i].name));
384 if (section_sp) {
385 const addr_t old_section_load_addr =
386 info.segments[i].vmaddr + info.slide;
387 if (m_process->GetTarget().SetSectionUnloaded(
388 section_sp, old_section_load_addr))
389 changed = true;
390 } else {
391 Debugger::ReportWarning(llvm::formatv(
392 "unable to find and unload segment named "
393 "'{0}' in '{1}' in macosx dynamic loader plug-in",
394 info.segments[i].name[0] ? info.segments[i].name : "<invalid>",
395 image_object_file->GetFileSpec().GetPath()));
396 }
397 }
398 }
399 }
400 }
401 return changed;
402}
403
404// Given a JSON dictionary (from debugserver, most likely) of binary images
405// loaded in the inferior process, add the images to the ImageInfo collection.
406
408 StructuredData::ObjectSP image_details,
409 ImageInfo::collection &image_infos) {
410 StructuredData::ObjectSP images_sp =
411 image_details->GetAsDictionary()->GetValueForKey("images");
412 if (images_sp.get() == nullptr)
413 return false;
414
415 image_infos.resize(images_sp->GetAsArray()->GetSize());
416
417 for (size_t i = 0; i < image_infos.size(); i++) {
418 StructuredData::ObjectSP image_sp =
419 images_sp->GetAsArray()->GetItemAtIndex(i);
420 if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
421 return false;
422 StructuredData::Dictionary *image = image_sp->GetAsDictionary();
423 // clang-format off
424 if (!image->HasKey("load_address") ||
425 !image->HasKey("pathname") ||
426 !image->HasKey("mach_header") ||
427 image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr ||
428 !image->HasKey("segments") ||
429 image->GetValueForKey("segments")->GetAsArray() == nullptr ||
430 !image->HasKey("uuid")) {
431 return false;
432 }
433 // clang-format on
434 image_infos[i].address =
435 image->GetValueForKey("load_address")->GetUnsignedIntegerValue();
436 image_infos[i].file_spec.SetFile(
437 image->GetValueForKey("pathname")->GetAsString()->GetValue(),
438 FileSpec::Style::native);
439
441 image->GetValueForKey("mach_header")->GetAsDictionary();
442 image_infos[i].header.magic =
443 mh->GetValueForKey("magic")->GetUnsignedIntegerValue();
444 image_infos[i].header.cputype =
445 mh->GetValueForKey("cputype")->GetUnsignedIntegerValue();
446 image_infos[i].header.cpusubtype =
447 mh->GetValueForKey("cpusubtype")->GetUnsignedIntegerValue();
448 image_infos[i].header.filetype =
449 mh->GetValueForKey("filetype")->GetUnsignedIntegerValue();
450 if (mh->HasKey("sizeof_mh_and_loadcmds"))
451 image_infos[i].mh_and_load_cmd_size =
452 mh->GetValueForKey("sizeof_mh_and_loadcmds")
453 ->GetUnsignedIntegerValue();
454
455 if (image->HasKey("min_version_os_name")) {
456 std::string os_name =
457 std::string(image->GetValueForKey("min_version_os_name")
458 ->GetAsString()
459 ->GetValue());
460 if (os_name == "macosx")
461 image_infos[i].os_type = llvm::Triple::MacOSX;
462 else if (os_name == "ios" || os_name == "iphoneos")
463 image_infos[i].os_type = llvm::Triple::IOS;
464 else if (os_name == "tvos")
465 image_infos[i].os_type = llvm::Triple::TvOS;
466 else if (os_name == "watchos")
467 image_infos[i].os_type = llvm::Triple::WatchOS;
468 else if (os_name == "bridgeos")
469 image_infos[i].os_type = llvm::Triple::BridgeOS;
470 else if (os_name == "driverkit")
471 image_infos[i].os_type = llvm::Triple::DriverKit;
472 else if (os_name == "xros")
473 image_infos[i].os_type = llvm::Triple::XROS;
474 else if (os_name == "maccatalyst") {
475 image_infos[i].os_type = llvm::Triple::IOS;
476 image_infos[i].os_env = llvm::Triple::MacABI;
477 } else if (os_name == "iossimulator") {
478 image_infos[i].os_type = llvm::Triple::IOS;
479 image_infos[i].os_env = llvm::Triple::Simulator;
480 } else if (os_name == "tvossimulator") {
481 image_infos[i].os_type = llvm::Triple::TvOS;
482 image_infos[i].os_env = llvm::Triple::Simulator;
483 } else if (os_name == "watchossimulator") {
484 image_infos[i].os_type = llvm::Triple::WatchOS;
485 image_infos[i].os_env = llvm::Triple::Simulator;
486 } else if (os_name == "xrsimulator") {
487 image_infos[i].os_type = llvm::Triple::XROS;
488 image_infos[i].os_env = llvm::Triple::Simulator;
489 }
490 }
491 if (image->HasKey("min_version_os_sdk")) {
492 image_infos[i].min_version_os_sdk =
493 std::string(image->GetValueForKey("min_version_os_sdk")
494 ->GetAsString()
495 ->GetValue());
496 }
497
498 // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
499 // currently send them in the reply.
500
501 if (mh->HasKey("flags"))
502 image_infos[i].header.flags =
503 mh->GetValueForKey("flags")->GetUnsignedIntegerValue();
504 else
505 image_infos[i].header.flags = 0;
506
507 if (mh->HasKey("ncmds"))
508 image_infos[i].header.ncmds =
509 mh->GetValueForKey("ncmds")->GetUnsignedIntegerValue();
510 else
511 image_infos[i].header.ncmds = 0;
512
513 if (mh->HasKey("sizeofcmds"))
514 image_infos[i].header.sizeofcmds =
515 mh->GetValueForKey("sizeofcmds")->GetUnsignedIntegerValue();
516 else
517 image_infos[i].header.sizeofcmds = 0;
518
519 StructuredData::Array *segments =
520 image->GetValueForKey("segments")->GetAsArray();
521 uint32_t segcount = segments->GetSize();
522 for (size_t j = 0; j < segcount; j++) {
525 segments->GetItemAtIndex(j)->GetAsDictionary();
526 llvm::StringRef seg_name =
527 seg->GetValueForKey("name")->GetAsString()->GetValue();
528 strncpy(segment.name, seg_name.data(),
529 std::min(seg_name.size(), size_t(16)));
530 segment.name[16] = '\0';
531 segment.vmaddr = seg->GetValueForKey("vmaddr")->GetUnsignedIntegerValue();
532 segment.vmsize = seg->GetValueForKey("vmsize")->GetUnsignedIntegerValue();
533 segment.fileoff =
534 seg->GetValueForKey("fileoff")->GetUnsignedIntegerValue();
535 segment.filesize =
536 seg->GetValueForKey("filesize")->GetUnsignedIntegerValue();
537 segment.maxprot =
538 seg->GetValueForKey("maxprot")->GetUnsignedIntegerValue();
539
540 // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
541 // currently send them in the reply.
542
543 if (seg->HasKey("initprot"))
544 segment.initprot =
545 seg->GetValueForKey("initprot")->GetUnsignedIntegerValue();
546 else
547 segment.initprot = 0;
548
549 if (seg->HasKey("flags"))
550 segment.flags = seg->GetValueForKey("flags")->GetUnsignedIntegerValue();
551 else
552 segment.flags = 0;
553
554 if (seg->HasKey("nsects"))
555 segment.nsects =
556 seg->GetValueForKey("nsects")->GetUnsignedIntegerValue();
557 else
558 segment.nsects = 0;
559
560 image_infos[i].segments.push_back(segment);
561 }
562
563 image_infos[i].uuid.SetFromStringRef(
564 image->GetValueForKey("uuid")->GetAsString()->GetValue());
565
566 // All sections listed in the dyld image info structure will all either be
567 // fixed up already, or they will all be off by a single slide amount that
568 // is determined by finding the first segment that is at file offset zero
569 // which also has bytes (a file size that is greater than zero) in the
570 // object file.
571
572 // Determine the slide amount (if any)
573 const size_t num_sections = image_infos[i].segments.size();
574 for (size_t k = 0; k < num_sections; ++k) {
575 // Iterate through the object file sections to find the first section
576 // that starts of file offset zero and that has bytes in the file...
577 if ((image_infos[i].segments[k].fileoff == 0 &&
578 image_infos[i].segments[k].filesize > 0) ||
579 (llvm::StringRef(image_infos[i].segments[k].name) == "__TEXT")) {
580 image_infos[i].slide =
581 image_infos[i].address - image_infos[i].segments[k].vmaddr;
582 // We have found the slide amount, so we can exit this for loop.
583 break;
584 }
585 }
586 }
587
588 return true;
589}
590
592 std::vector<std::pair<ImageInfo, ModuleSP>> &images) {
593 uint32_t exe_idx = UINT32_MAX;
594 uint32_t dyld_idx = UINT32_MAX;
595 Target &target = m_process->GetTarget();
597 ConstString g_dyld_sim_filename("dyld_sim");
598
599 ArchSpec target_arch = target.GetArchitecture();
600 const size_t images_size = images.size();
601 for (size_t i = 0; i < images_size; i++) {
602 const auto &image_info = images[i].first;
603 if (image_info.header.filetype == llvm::MachO::MH_DYLINKER) {
604 // In a "simulator" process we will have two dyld modules --
605 // a "dyld" that we want to keep track of, and a "dyld_sim" which
606 // we don't need to keep track of here. dyld_sim will have a non-macosx
607 // OS.
608 if (target_arch.GetTriple().getEnvironment() == llvm::Triple::Simulator &&
609 image_info.os_type != llvm::Triple::OSType::MacOSX) {
610 continue;
611 }
612
613 dyld_idx = i;
614 }
615 if (image_info.header.filetype == llvm::MachO::MH_EXECUTE) {
616 exe_idx = i;
617 }
618 }
619
620 // Set the target executable if we haven't found one so far.
621 if (exe_idx != UINT32_MAX && !target.GetExecutableModule()) {
622 ModuleSP exe_module_sp = images[exe_idx].second;
623 if (exe_module_sp) {
624 LLDB_LOGF(log, "Found executable module: %s",
625 exe_module_sp->GetFileSpec().GetPath().c_str());
626 target.GetImages().AppendIfNeeded(exe_module_sp);
627 UpdateImageLoadAddress(exe_module_sp.get(), images[exe_idx].first);
628 if (exe_module_sp.get() != target.GetExecutableModulePointer())
629 target.RebuildModuleListWithExecutable(exe_module_sp,
631
632 // Update the target executable's arch if necessary.
633 auto exe_triple = exe_module_sp->GetArchitecture().GetTriple();
634 if (target_arch.GetTriple().isArm64e() &&
635 exe_triple.getArch() == llvm::Triple::aarch64 &&
636 !exe_triple.isArm64e()) {
637 // On arm64e-capable Apple platforms, the system libraries are
638 // always arm64e, but applications often are arm64. When a
639 // target is created from a file, LLDB recognizes it as an
640 // arm64 target, but debugserver will still (technically
641 // correct) report the process as being arm64e. For
642 // consistency, set the target to arm64 here, so attaching to
643 // a live process behaves the same as creating a process from
644 // file.
645 auto triple = target_arch.GetTriple();
646 triple.setArchName(exe_triple.getArchName());
647 target_arch.SetTriple(triple);
648 target.SetArchitecture(target_arch, /*set_platform=*/false,
649 /*merge=*/false);
650 }
651 }
652 }
653
654 if (dyld_idx != UINT32_MAX) {
655 ModuleSP dyld_sp = images[dyld_idx].second;
656 if (dyld_sp.get()) {
657 LLDB_LOGF(log, "Found dyld module: %s",
658 dyld_sp->GetFileSpec().GetPath().c_str());
659 target.GetImages().AppendIfNeeded(dyld_sp);
660 UpdateImageLoadAddress(dyld_sp.get(), images[dyld_idx].first);
661 SetDYLDModule(dyld_sp);
662 }
663 }
664}
665
667 ImageInfo &image_info) {
668 if (image_info.header.filetype == llvm::MachO::MH_DYLINKER) {
669 const bool can_create = true;
670 ModuleSP dyld_sp =
671 FindTargetModuleForImageInfo(image_info, can_create, nullptr);
672 if (dyld_sp.get()) {
673 Target &target = m_process->GetTarget();
674 target.GetImages().AppendIfNeeded(dyld_sp);
675 UpdateImageLoadAddress(dyld_sp.get(), image_info);
676 SetDYLDModule(dyld_sp);
677 return true;
678 }
679 }
680 return false;
681}
682
683std::optional<lldb_private::Address> DynamicLoaderDarwin::GetStartAddress() {
685
686 auto log_err = [log](llvm::StringLiteral err_msg) -> std::nullopt_t {
687 LLDB_LOG_VERBOSE(log, "{}", err_msg);
688 return std::nullopt;
689 };
690
691 ModuleSP dyld_sp = GetDYLDModule();
692 if (!dyld_sp)
693 return log_err("Couldn't retrieve DYLD module. Cannot get `start` symbol.");
694
695 const Symbol *symbol =
696 dyld_sp->FindFirstSymbolWithNameAndType(ConstString("_dyld_start"));
697 if (!symbol)
698 return log_err("Cannot find `start` symbol in DYLD module.");
699
700 return symbol->GetAddress();
701}
702
704 m_dyld_module_wp = dyld_module_sp;
705}
706
708 ModuleSP dyld_sp(m_dyld_module_wp.lock());
709 return dyld_sp;
710}
711
713
714std::vector<std::pair<DynamicLoaderDarwin::ImageInfo, ModuleSP>>
716 const ImageInfo::collection &image_infos) {
717 const auto size = image_infos.size();
718 std::vector<std::pair<DynamicLoaderDarwin::ImageInfo, ModuleSP>> images(size);
719 auto LoadImage = [&](size_t i, ImageInfo::collection::const_iterator it) {
720 const auto &image_info = *it;
721 images[i] = std::make_pair(
722 image_info, FindTargetModuleForImageInfo(image_info, true, nullptr));
723 };
724 auto it = image_infos.begin();
725 bool is_parallel_load = m_process->GetTarget().GetParallelModuleLoad();
726 if (is_parallel_load) {
727 llvm::ThreadPoolTaskGroup taskGroup(Debugger::GetThreadPool());
728 for (size_t i = 0; i < size; ++i, ++it) {
729 taskGroup.async(LoadImage, i, it);
730 }
731 taskGroup.wait();
732 } else {
733 for (size_t i = 0; i < size; ++i, ++it) {
734 LoadImage(i, it);
735 }
736 }
737 return images;
738}
739
741 ImageInfo::collection &image_infos) {
742 std::lock_guard<std::recursive_mutex> guard(m_mutex);
743 auto images = PreloadModulesFromImageInfos(image_infos);
744 return AddModulesUsingPreloadedModules(images);
745}
746
748 std::vector<std::pair<ImageInfo, ModuleSP>> &images) {
749 std::lock_guard<std::recursive_mutex> guard(m_mutex);
750 // Now add these images to the main list.
751 ModuleList loaded_module_list;
753 Target &target = m_process->GetTarget();
754 ModuleList &target_images = target.GetImages();
755
756 for (uint32_t idx = 0; idx < images.size(); ++idx) {
757 auto &image_info = images[idx].first;
758 const auto &image_module_sp = images[idx].second;
759 if (log) {
760 LLDB_LOGF(log, "Adding new image at address=0x%16.16" PRIx64 ".",
761 image_info.address);
762 image_info.PutToLog(log);
763 }
764 m_dyld_image_infos.push_back(image_info);
765
766 if (image_module_sp) {
767 ObjectFile *objfile = image_module_sp->GetObjectFile();
768 if (objfile) {
769 SectionList *sections = objfile->GetSectionList();
770 if (sections) {
771 llvm::StringRef commpage_sect_name("__commpage");
772 Section *commpage_section =
773 sections->FindSectionByName(commpage_sect_name).get();
774 if (commpage_section) {
775 ModuleSpec module_spec(objfile->GetFileSpec(),
776 image_info.GetArchitecture());
777 module_spec.GetObjectName() = ConstString(commpage_sect_name);
778 ModuleSP commpage_image_module_sp(
779 target_images.FindFirstModule(module_spec));
780 if (!commpage_image_module_sp) {
781 module_spec.SetObjectOffset(objfile->GetFileOffset() +
782 commpage_section->GetFileOffset());
783 module_spec.SetObjectSize(objfile->GetByteSize());
784 commpage_image_module_sp = target.GetOrCreateModule(module_spec,
785 true /* notify */);
786 if (!commpage_image_module_sp ||
787 commpage_image_module_sp->GetObjectFile() == nullptr) {
788 llvm::Expected<ModuleSP> module_sp_or_err =
789 m_process->ReadModuleFromMemory(image_info.file_spec,
790 image_info.address);
791 if (auto err = module_sp_or_err.takeError()) {
792 LLDB_LOG_ERROR(log, std::move(err),
793 "Failed to read module from memory: {0}");
794 } else {
795 // Always load a memory image right away in the target in case
796 // we end up trying to read the symbol table from memory...
797 // The __LINKEDIT will need to be mapped so we can figure out
798 // where the symbol table bits are...
799 commpage_image_module_sp = *module_sp_or_err;
800 bool changed = false;
801 UpdateImageLoadAddress(commpage_image_module_sp.get(),
802 image_info);
803 target.GetImages().Append(commpage_image_module_sp);
804 if (changed) {
805 image_info.load_stop_id = m_process->GetStopID();
806 loaded_module_list.AppendIfNeeded(commpage_image_module_sp);
807 }
808 }
809 }
810 }
811 }
812 }
813 }
814
815 // UpdateImageLoadAddress will return true if any segments change load
816 // address. We need to check this so we don't mention that all loaded
817 // shared libraries are newly loaded each time we hit out dyld breakpoint
818 // since dyld will list all shared libraries each time.
819 if (UpdateImageLoadAddress(image_module_sp.get(), image_info)) {
820 target_images.AppendIfNeeded(image_module_sp);
821 loaded_module_list.AppendIfNeeded(image_module_sp);
822 }
823
824 // To support macCatalyst and legacy iOS simulator,
825 // update the module's platform with the DYLD info.
826 ArchSpec dyld_spec = image_info.GetArchitecture();
827 auto &dyld_triple = dyld_spec.GetTriple();
828 if ((dyld_triple.getEnvironment() == llvm::Triple::MacABI &&
829 dyld_triple.getOS() == llvm::Triple::IOS) ||
830 (dyld_triple.getEnvironment() == llvm::Triple::Simulator &&
831 (dyld_triple.getOS() == llvm::Triple::IOS ||
832 dyld_triple.getOS() == llvm::Triple::TvOS ||
833 dyld_triple.getOS() == llvm::Triple::WatchOS ||
834 dyld_triple.getOS() == llvm::Triple::XROS)))
835 image_module_sp->MergeArchitecture(dyld_spec);
836 }
837 }
838
839 if (loaded_module_list.GetSize() > 0) {
840 if (log)
841 loaded_module_list.LogUUIDAndPaths(log,
842 "DynamicLoaderDarwin::ModulesDidLoad");
843 m_process->GetTarget().ModulesDidLoad(loaded_module_list);
844 }
845 return true;
846}
847
848// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
849// functions written in hand-written assembly, and also have hand-written
850// unwind information in the eh_frame section. Normally we prefer analyzing
851// the assembly instructions of a currently executing frame to unwind from that
852// frame -- but on hand-written functions this profiling can fail. We should
853// use the eh_frame instructions for these functions all the time.
854//
855// As an aside, it would be better if the eh_frame entries had a flag (or were
856// extensible so they could have an Apple-specific flag) which indicates that
857// the instructions are asynchronous -- accurate at every instruction, instead
858// of our normal default assumption that they are not.
859
861 ModuleSP module_sp;
862 if (sym_ctx.symbol) {
863 module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
864 }
865 if (module_sp.get() == nullptr && sym_ctx.function)
866 module_sp = sym_ctx.function->GetAddress().GetModule();
867 if (module_sp.get() == nullptr)
868 return false;
869
871 return objc_runtime != nullptr &&
872 objc_runtime->IsModuleObjCLibrary(module_sp);
873}
874
875// Dump a Segment to the file handle provided.
877 lldb::addr_t slide) const {
878 if (slide == 0)
879 LLDB_LOGF(log, "\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")", name,
880 vmaddr + slide, vmaddr + slide + vmsize);
881 else
882 LLDB_LOGF(log,
883 "\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
884 ") slide = 0x%" PRIx64,
885 name, vmaddr + slide, vmaddr + slide + vmsize, slide);
886}
887
889 // Update the module's platform with the DYLD info.
891 header.cpusubtype);
892 if (os_env == llvm::Triple::MacABI && os_type == llvm::Triple::IOS) {
893 llvm::Triple triple(llvm::Twine(arch_spec.GetArchitectureName()) +
894 "-apple-ios" + min_version_os_sdk + "-macabi");
895 ArchSpec maccatalyst_spec(triple);
896 if (arch_spec.IsCompatibleMatch(maccatalyst_spec))
897 arch_spec.MergeFrom(maccatalyst_spec);
898 }
899 if (os_env == llvm::Triple::Simulator &&
900 (os_type == llvm::Triple::IOS || os_type == llvm::Triple::TvOS ||
901 os_type == llvm::Triple::WatchOS || os_type == llvm::Triple::XROS)) {
902 llvm::Triple triple(llvm::Twine(arch_spec.GetArchitectureName()) +
903 "-apple-" + llvm::Triple::getOSTypeName(os_type) +
904 min_version_os_sdk + "-simulator");
905 ArchSpec sim_spec(triple);
906 if (arch_spec.IsCompatibleMatch(sim_spec))
907 arch_spec.MergeFrom(sim_spec);
908 }
909 return arch_spec;
910}
911
912// Dump an image info structure to the file handle provided.
914 if (!log)
915 return;
917 LLDB_LOG(log, "uuid={} path='{}' (UNLOADED)", uuid.GetAsString(),
918 file_spec.GetPath());
919 } else {
920 LLDB_LOG(log, "address={0:x+16} uuid={1} path='{2}'", address,
921 uuid.GetAsString(), file_spec.GetPath());
922 for (uint32_t i = 0; i < segments.size(); ++i)
923 segments[i].PutToLog(log, slide);
924 }
925}
926
928 DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__,
929 StateAsCString(m_process->GetState()));
930 Clear(true);
931 m_process = process;
932}
933
934// Member function that gets called when the process state changes.
936 StateType state) {
937 DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__,
938 StateAsCString(state));
939 switch (state) {
940 case eStateConnected:
941 case eStateAttaching:
942 case eStateLaunching:
943 case eStateInvalid:
944 case eStateUnloaded:
945 case eStateExited:
946 case eStateDetached:
947 Clear(false);
948 break;
949
950 case eStateStopped:
951 // Keep trying find dyld and set our notification breakpoint each time we
952 // stop until we succeed
953 if (!DidSetNotificationBreakpoint() && m_process->IsAlive()) {
956
958 }
959 break;
960
961 case eStateRunning:
962 case eStateStepping:
963 case eStateCrashed:
964 case eStateSuspended:
965 break;
966 }
967}
968
971 bool stop_others) {
972 ThreadPlanSP thread_plan_sp;
973 StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
974 const SymbolContext &current_context =
975 current_frame->GetSymbolContext(eSymbolContextSymbol);
976 const Symbol *current_symbol = current_context.symbol;
977 Log *log = GetLog(LLDBLog::Step);
978 TargetSP target_sp(thread.CalculateTarget());
979
980 if (current_symbol != nullptr) {
981 std::vector<Address> addresses;
982
983 ConstString current_name =
984 current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
985 llvm::StringRef target_symbol_name = current_name;
986 static const llvm::StringRef g_lazy_stub_name = "$lazyLoadStub";
987 // If this is a "lazy library" stub, we don't have a guarantee that the
988 // target library is loaded at the point where we hit the stub. So we
989 // have to use a symbol name breakpoint rather than an address one.
990 if (current_name && target_symbol_name.consume_back(g_lazy_stub_name)) {
991 auto bkpt_sp = target_sp->CreateBreakpoint(
992 nullptr, nullptr, target_symbol_name.str().c_str(),
993 eFunctionNameTypeFull, eLanguageTypeUnknown, /*offset=*/0,
994 /*is_insn_count=*/false,
995 /*skip_prologue=*/eLazyBoolNo, /*internal=*/true,
996 /* hardware=*/false);
997 return std::make_shared<ThreadPlanRunToBreakpoint>(thread, bkpt_sp,
998 stop_others);
999 }
1000
1001 if (current_symbol->IsTrampoline()) {
1002 if (current_name) {
1003 const ModuleList &images = target_sp->GetImages();
1004
1005 SymbolContextList code_symbols;
1006 images.FindSymbolsWithNameAndType(current_name, eSymbolTypeCode,
1007 code_symbols);
1008 for (const SymbolContext &context : code_symbols) {
1009 Address addr = context.GetFunctionOrSymbolAddress();
1010 addresses.push_back(addr);
1011 if (log) {
1012 addr_t load_addr = addr.GetLoadAddress(target_sp.get());
1013
1014 LLDB_LOGF(log, "Found a trampoline target symbol at 0x%" PRIx64 ".",
1015 load_addr);
1016 }
1017 }
1018 SymbolContextList reexported_symbols;
1020 reexported_symbols);
1021 for (const SymbolContext &context : reexported_symbols) {
1022 if (context.symbol) {
1023 const Symbol *actual_symbol =
1024 context.symbol->ResolveReExportedSymbol(*target_sp.get());
1025 if (actual_symbol) {
1026 const Address actual_symbol_addr = actual_symbol->GetAddress();
1027 if (actual_symbol_addr.IsValid()) {
1028 addresses.push_back(actual_symbol_addr);
1029 if (log) {
1030 lldb::addr_t load_addr =
1031 actual_symbol_addr.GetLoadAddress(target_sp.get());
1032 LLDB_LOGF(log,
1033 "Found a re-exported symbol: %s at 0x%" PRIx64 ".",
1034 actual_symbol->GetName().GetCString(), load_addr);
1035 }
1036 }
1037 }
1038 }
1039 }
1040
1041 SymbolContextList indirect_symbols;
1043 indirect_symbols);
1044
1045 for (const SymbolContext &context : indirect_symbols) {
1046 Address addr = context.GetFunctionOrSymbolAddress();
1047 addresses.push_back(addr);
1048 if (log) {
1049 addr_t load_addr = addr.GetLoadAddress(target_sp.get());
1050
1051 LLDB_LOGF(log, "Found an indirect target symbol at 0x%" PRIx64 ".",
1052 load_addr);
1053 }
1054 }
1055 }
1056 } else if (current_symbol->GetType() == eSymbolTypeReExported) {
1057 // I am not sure we could ever end up stopped AT a re-exported symbol.
1058 // But just in case:
1059
1060 const Symbol *actual_symbol =
1061 current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
1062 if (actual_symbol) {
1063 Address target_addr(actual_symbol->GetAddress());
1064 if (target_addr.IsValid()) {
1065 LLDB_LOGF(
1066 log,
1067 "Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64
1068 ".",
1069 current_symbol->GetName().GetCString(),
1070 actual_symbol->GetName().GetCString(),
1071 target_addr.GetLoadAddress(target_sp.get()));
1072 addresses.push_back(
1073 Address(target_addr.GetLoadAddress(target_sp.get())));
1074 }
1075 }
1076 }
1077
1078 if (addresses.size() > 0) {
1079 // First check whether any of the addresses point to Indirect symbols,
1080 // and if they do, resolve them:
1081 std::vector<lldb::addr_t> load_addrs;
1082 for (Address address : addresses) {
1083 const Symbol *symbol = address.CalculateSymbolContextSymbol();
1084 if (symbol && symbol->IsIndirect()) {
1085 Status error;
1086 Address symbol_address = symbol->GetAddress();
1087 addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(
1088 &symbol_address, error);
1089 if (error.Success()) {
1090 load_addrs.push_back(resolved_addr);
1091 LLDB_LOGF(log,
1092 "ResolveIndirectFunction found resolved target for "
1093 "%s at 0x%" PRIx64 ".",
1094 symbol->GetName().GetCString(), resolved_addr);
1095 }
1096 } else {
1097 load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
1098 }
1099 }
1100 thread_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
1101 thread, load_addrs, stop_others);
1102 }
1103 // One more case we have to consider is "branch islands". These are regular
1104 // TEXT symbols but their names end in .island plus maybe a .digit suffix.
1105 // They are to allow arm64 code to branch further than the size of the
1106 // address slot allows. We just need to single-instruction step in that
1107 // case.
1108 static const char *g_branch_island_pattern = "\\.island\\.?[0-9]*$";
1109 static RegularExpression g_branch_island_regex(g_branch_island_pattern);
1110
1111 bool is_branch_island = g_branch_island_regex.Execute(current_name);
1112 if (!thread_plan_sp && is_branch_island) {
1113 thread_plan_sp = std::make_shared<ThreadPlanStepInstruction>(
1114 thread,
1115 /* step_over= */ false, /* stop_others */ false, eVoteNoOpinion,
1117 LLDB_LOG(log, "Stepping one instruction over branch island: '{0}'.",
1118 current_name);
1119 }
1120 } else {
1121 LLDB_LOGF(log, "Could not find symbol for step through.");
1122 }
1123
1124 return thread_plan_sp;
1125}
1126
1128 const lldb_private::Symbol *original_symbol,
1130 lldb_private::SymbolContextList &equivalent_symbols) {
1131 ConstString trampoline_name =
1132 original_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1133 if (!trampoline_name)
1134 return;
1135
1136 static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
1137 std::string equivalent_regex_buf("^");
1138 equivalent_regex_buf.append(trampoline_name.GetCString());
1139 equivalent_regex_buf.append(resolver_name_regex);
1140
1141 RegularExpression equivalent_name_regex(equivalent_regex_buf);
1142 images.FindSymbolsMatchingRegExAndType(equivalent_name_regex, eSymbolTypeCode,
1143 equivalent_symbols);
1144}
1145
1147 ModuleSP module_sp = m_libpthread_module_wp.lock();
1148 if (!module_sp) {
1149 SymbolContextList sc_list;
1150 ModuleSpec module_spec;
1151 module_spec.GetFileSpec().SetFilename("libsystem_pthread.dylib");
1152 ModuleList module_list;
1153 m_process->GetTarget().GetImages().FindModules(module_spec, module_list);
1154 if (!module_list.IsEmpty()) {
1155 if (module_list.GetSize() == 1) {
1156 module_sp = module_list.GetModuleAtIndex(0);
1157 if (module_sp)
1158 m_libpthread_module_wp = module_sp;
1159 }
1160 }
1161 }
1162 return module_sp;
1163}
1164
1166 if (!m_pthread_getspecific_addr.IsValid()) {
1167 ModuleSP module_sp = GetPThreadLibraryModule();
1168 if (module_sp) {
1170 module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"),
1171 eSymbolTypeCode, sc_list);
1172 SymbolContext sc;
1173 if (sc_list.GetContextAtIndex(0, sc)) {
1174 if (sc.symbol)
1176 }
1177 }
1178 }
1180}
1181
1184 const lldb::ThreadSP thread_sp,
1185 lldb::addr_t tls_file_addr) {
1186 if (!thread_sp || !module_sp)
1187 return LLDB_INVALID_ADDRESS;
1188
1189 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1190
1191 lldb_private::Address tls_addr;
1192 if (!module_sp->ResolveFileAddress(tls_file_addr, tls_addr))
1193 return LLDB_INVALID_ADDRESS;
1194
1195 Target &target = m_process->GetTarget();
1196 TypeSystemClangSP scratch_ts_sp =
1198 if (!scratch_ts_sp)
1199 return LLDB_INVALID_ADDRESS;
1200
1201 CompilerType clang_void_ptr_type =
1202 scratch_ts_sp->GetBasicType(eBasicTypeVoid).GetPointerType();
1203
1204 auto evaluate_tls_address = [this, &thread_sp, &clang_void_ptr_type](
1205 Address func_ptr,
1206 llvm::ArrayRef<addr_t> args) -> addr_t {
1208
1209 lldb::ThreadPlanSP thread_plan_sp(new ThreadPlanCallFunction(
1210 *thread_sp, func_ptr, clang_void_ptr_type, args, options));
1211
1212 DiagnosticManager execution_errors;
1213 ExecutionContext exe_ctx(thread_sp);
1214 lldb::ExpressionResults results = m_process->RunThreadPlan(
1215 exe_ctx, thread_plan_sp, options, execution_errors);
1216
1217 if (results == lldb::eExpressionCompleted) {
1218 if (lldb::ValueObjectSP result_valobj_sp =
1219 thread_plan_sp->GetReturnValueObject()) {
1220 return result_valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
1221 }
1222 }
1223 return LLDB_INVALID_ADDRESS;
1224 };
1225
1226 // On modern apple platforms, there is a small data structure that looks
1227 // approximately like this:
1228 // struct TLS_Thunk {
1229 // void *(*get_addr)(struct TLS_Thunk *);
1230 // size_t key;
1231 // size_t offset;
1232 // }
1233 //
1234 // The strategy is to take get_addr and call it with the address of the
1235 // containing TLS_Thunk structure.
1236 //
1237 // On older apple platforms, the key is treated as a pthread_key_t and passed
1238 // to pthread_getspecific. The pointer returned from that call is added to
1239 // offset to get the relevant data block.
1240
1241 const uint32_t addr_size = m_process->GetAddressByteSize();
1242 uint8_t buf[sizeof(addr_t) * 3];
1243 Status error;
1244 const size_t tls_data_size = addr_size * 3;
1245 const size_t bytes_read = target.ReadMemory(
1246 tls_addr, buf, tls_data_size, error, /*force_live_memory = */ true);
1247 if (bytes_read != tls_data_size || error.Fail())
1248 return LLDB_INVALID_ADDRESS;
1249
1250 DataExtractor data(buf, sizeof(buf), m_process->GetByteOrder(), addr_size);
1251 lldb::offset_t offset = 0;
1252 const addr_t tls_thunk = data.GetAddress(&offset);
1253 const addr_t key = data.GetAddress(&offset);
1254 const addr_t tls_offset = data.GetAddress(&offset);
1255
1256 if (tls_thunk != 0) {
1257 const addr_t fixed_tls_thunk = m_process->FixCodeAddress(tls_thunk);
1258 Address thunk_load_addr;
1259 if (target.ResolveLoadAddress(fixed_tls_thunk, thunk_load_addr)) {
1260 const addr_t tls_load_addr = tls_addr.GetLoadAddress(&target);
1261 const addr_t tls_data = evaluate_tls_address(
1262 thunk_load_addr, llvm::ArrayRef<addr_t>(tls_load_addr));
1263 if (tls_data != LLDB_INVALID_ADDRESS)
1264 return tls_data;
1265 }
1266 }
1267
1268 if (key != 0) {
1269 // First check to see if we have already figured out the location of
1270 // TLS data for the pthread_key on a specific thread yet. If we have we
1271 // can re-use it since its location will not change unless the process
1272 // execs.
1273 const lldb::tid_t tid = thread_sp->GetID();
1274 auto tid_pos = m_tid_to_tls_map.find(tid);
1275 if (tid_pos != m_tid_to_tls_map.end()) {
1276 auto tls_pos = tid_pos->second.find(key);
1277 if (tls_pos != tid_pos->second.end()) {
1278 return tls_pos->second + tls_offset;
1279 }
1280 }
1281 Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
1282 if (pthread_getspecific_addr.IsValid()) {
1283 const addr_t tls_data = evaluate_tls_address(pthread_getspecific_addr,
1284 llvm::ArrayRef<addr_t>(key));
1285 if (tls_data != LLDB_INVALID_ADDRESS)
1286 return tls_data + tls_offset;
1287 }
1288 }
1289 return LLDB_INVALID_ADDRESS;
1290}
1291
1294 bool use_new_spi_interface = true;
1295
1296 llvm::VersionTuple version = process->GetHostOSVersion();
1297 if (!version.empty()) {
1298 using namespace llvm;
1299 const Triple::OSType os_type =
1300 process->GetTarget().GetArchitecture().GetTriple().getOS();
1301
1302 auto OlderThan = [os_type, version](llvm::Triple::OSType o,
1303 llvm::VersionTuple v) -> bool {
1304 return os_type == o && version < v;
1305 };
1306
1307 if (OlderThan(Triple::MacOSX, VersionTuple(10, 12)))
1308 use_new_spi_interface = false;
1309
1310 if (OlderThan(Triple::IOS, VersionTuple(10)))
1311 use_new_spi_interface = false;
1312
1313 if (OlderThan(Triple::TvOS, VersionTuple(10)))
1314 use_new_spi_interface = false;
1315
1316 if (OlderThan(Triple::WatchOS, VersionTuple(3)))
1317 use_new_spi_interface = false;
1318
1319 // llvm::Triple::BridgeOS and llvm::Triple::XROS always use the new
1320 // libdyld SPI interface.
1321 } else {
1322 // We could not get an OS version string, we are likely not
1323 // connected to debugserver and the packets to call the libdyld SPI
1324 // will not exist.
1325 use_new_spi_interface = false;
1326 }
1327
1328 // Corefiles cannot use the libdyld SPI to get the inferior's
1329 // binaries, we must find it through metadata or a scan
1330 // of the corefile memory.
1331 if (!process->IsLiveDebugSession())
1332 use_new_spi_interface = false;
1333
1334 if (log) {
1335 if (use_new_spi_interface)
1336 LLDB_LOGF(
1337 log, "DynamicLoaderDarwin::UseDYLDSPI: Use new DynamicLoader plugin");
1338 else
1339 LLDB_LOGF(
1340 log, "DynamicLoaderDarwin::UseDYLDSPI: Use old DynamicLoader plugin");
1341 }
1342 return use_new_spi_interface;
1343}
static llvm::raw_ostream & error(Stream &strm)
#define DEBUG_PRINTF(fmt,...)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
#define LLDB_LOG_VERBOSE(log,...)
Definition Log.h:382
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:303
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition Address.cpp:1029
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:275
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition Address.h:329
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:545
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition ArchSpec.cpp:949
void MergeFrom(const ArchSpec &other)
Merges fields from another ArchSpec into this ArchSpec.
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
Definition ArchSpec.h:597
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition ArchSpec.cpp:742
Generic representation of a type in a programming language.
A uniqued constant string class.
Definition ConstString.h:40
const char * GetCString() const
Get the string value as a C string.
An data extractor class.
uint64_t GetAddress(lldb::offset_t *offset_ptr) const
Extract an address from *offset_ptr.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
static llvm::ThreadPoolInterface & GetThreadPool()
Shared thread pool. Use only with ThreadPoolTaskGroup.
void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const
lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override
Retrieves the per-module TLS block for a given thread.
bool UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info)
bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override
Ask if the eh_frame information for the given SymbolContext should be relied on even when it's the fi...
virtual bool NeedToDoInitialImageFetch()=0
virtual void DoInitialImageFetch()=0
DynamicLoaderDarwin(lldb_private::Process *process)
void PrivateProcessStateChanged(lldb_private::Process *process, lldb::StateType state)
void DidLaunch() override
Called after attaching a process.
lldb::ModuleSP FindTargetModuleForImageInfo(const ImageInfo &image_info, bool can_create, bool *did_create_ptr)
virtual bool SetNotificationBreakpoint()=0
bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos)
void FindEquivalentSymbols(const lldb_private::Symbol *original_symbol, lldb_private::ModuleList &module_list, lldb_private::SymbolContextList &equivalent_symbols) override
Some dynamic loaders provide features where there are a group of symbols "equivalent to" a given symb...
void DidAttach() override
Called after attaching a process.
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, bool stop_others) override
Provides a plan to step through the dynamic loader trampoline for the current state of thread.
std::vector< std::pair< ImageInfo, lldb::ModuleSP > > PreloadModulesFromImageInfos(const ImageInfo::collection &image_infos)
bool JSONImageInformationIntoImageInfo(lldb_private::StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos)
bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info)
std::optional< lldb_private::Address > GetStartAddress() override
Return the start address in the dynamic loader module.
void UpdateSpecialBinariesFromPreloadedModules(std::vector< std::pair< ImageInfo, lldb::ModuleSP > > &images)
void PrivateInitialize(lldb_private::Process *process)
lldb_private::Address GetPthreadSetSpecificAddress()
bool AddModulesUsingPreloadedModules(std::vector< std::pair< ImageInfo, lldb::ModuleSP > > &images)
void SetDYLDModule(lldb::ModuleSP &dyld_module_sp)
static bool UseDYLDSPI(lldb_private::Process *process)
lldb_private::Address m_pthread_getspecific_addr
bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info)
void UnloadImages(const std::vector< lldb::addr_t > &solib_addresses)
virtual bool DidSetNotificationBreakpoint()=0
Process * m_process
The process that this dynamic loader plug-in is tracking.
DynamicLoader(Process *process)
Construct with a process.
virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache, LazyBool &private_shared_cache, lldb_private::FileSpec &shared_cache_path, std::optional< uint64_t > &size)
Get information about the shared cache for a process, if possible.
virtual void UnloadSections(const lldb::ModuleSP module)
Removes the loaded sections from the target in module.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition FileSpec.h:56
void SetFilename(llvm::StringRef filename)
Filename string set accessor.
Definition FileSpec.cpp:363
llvm::StringRef GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:248
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
static FileSystem & Instance()
const Address & GetAddress() const
Return the address of the function (its entry point).
Definition Function.h:439
void PutCString(const char *cstr)
Definition Log.cpp:162
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition Mangled.cpp:369
lldb::SymbolSharedCacheUse GetSharedCacheBinaryLoading() const
A collection class for Module objects.
Definition ModuleList.h:125
std::recursive_mutex & GetMutex() const
Definition ModuleList.h:252
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Finds the first module whose file specification matches module_spec.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
static ModuleListProperties & GetGlobalModuleListProperties()
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
void FindSymbolsMatchingRegExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
ModuleIterable Modules() const
Definition ModuleList.h:571
size_t GetSize() const
Gets the size of the module list.
void LogUUIDAndPaths(Log *log, const char *prefix_cstr)
void SetObjectSize(uint64_t object_size)
Definition ModuleSpec.h:119
ConstString & GetObjectName()
Definition ModuleSpec.h:107
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
void SetObjectOffset(uint64_t object_offset)
Definition ModuleSpec.h:113
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:91
virtual bool IsModuleObjCLibrary(const lldb::ModuleSP &module_sp)=0
static ObjCLanguageRuntime * Get(Process &process)
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
virtual lldb::addr_t GetFileOffset() const
Returns the offset into a file at which this object resides.
Definition ObjectFile.h:271
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:280
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
virtual lldb::addr_t GetByteSize() const
Definition ObjectFile.h:273
A plug-in interface definition class for debugging a process.
Definition Process.h:368
Range< lldb::addr_t, lldb::addr_t > LoadRange
Definition Process.h:401
virtual llvm::VersionTuple GetHostOSVersion()
Sometimes the connection to a process can detect the host OS version that the process is running on.
Definition Process.h:1257
virtual bool IsLiveDebugSession() const
Check if a process is a live debug session, or a corefile/post-mortem.
Definition Process.h:1558
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1267
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
static lldb::TypeSystemClangSP GetForTarget(Target &target, std::optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
lldb::SectionSP FindSectionByName(llvm::StringRef section_name) const
Definition Section.cpp:562
lldb::offset_t GetFileOffset() const
Definition Section.h:180
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
An error handling class.
Definition Status.h:118
ObjectSP GetItemAtIndex(size_t idx) const
ObjectSP GetValueForKey(llvm::StringRef key) const
bool HasKey(llvm::StringRef key) const
std::shared_ptr< Object > ObjectSP
Defines a list of symbol context objects.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Symbol * symbol
The Symbol for a given query.
bool IsIndirect() const
Definition Symbol.cpp:249
Mangled & GetMangled()
Definition Symbol.h:162
bool IsTrampoline() const
Definition Symbol.cpp:247
Address & GetAddressRef()
Definition Symbol.h:78
ConstString GetName() const
Definition Symbol.cpp:612
lldb::SymbolType GetType() const
Definition Symbol.h:197
Address GetAddress() const
Definition Symbol.h:98
Symbol * ResolveReExportedSymbol(Target &target, const lldb::ModuleSP &containing_module_sp=lldb::ModuleSP()) const
Find the symbol this re-exported symbol resolves to.
Definition Symbol.cpp:533
Symbol * CalculateSymbolContextSymbol() override
Definition Symbol.cpp:452
Module * GetExecutableModulePointer()
Definition Target.cpp:1650
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition Target.cpp:2470
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
Definition Target.cpp:3505
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition Target.cpp:1807
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition Target.cpp:1630
virtual size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, Status &error, bool force_live_memory=false, lldb::addr_t *load_addr_ptr=nullptr, bool *did_read_live_memory=nullptr)
Definition Target.cpp:2112
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1273
const ArchSpec & GetArchitecture() const
Definition Target.h:1315
void RebuildModuleListWithExecutable(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Clear the module list and rebuild it around a new main executable.
Definition Target.cpp:1673
Represents UUID's of various sizes.
Definition UUID.h:27
bool IsValid() const
Definition UUID.h:69
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
uint64_t offset_t
Definition lldb-types.h:86
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateLaunching
Process is in the process of launching.
@ eStateAttaching
Process is currently trying to attach.
@ eStateExited
Process has exited and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
@ eLanguageTypeUnknown
Unknown or invalid language value.
ExpressionResults
The results of expression evaluation.
@ eExpressionCompleted
@ eSymbolTypeReExported
@ eSymbolTypeResolver
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
uint64_t tid_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Module > ModuleSP
lldb_private::UUID uuid
UUID for this dylib if it has one, else all zeros.
lldb::addr_t address
Address of mach header for this dylib.
std::string min_version_os_sdk
LC_VERSION_MIN_... SDK.
lldb::addr_t slide
The amount to slide all segments by if there is a global slide.
llvm::MachO::mach_header header
The mach header for this image.
llvm::Triple::OSType os_type
LC_VERSION_MIN_... load command os type.
std::vector< Segment > segments
All segment vmaddr and vmsize pairs for this executable (from memory of inferior).
lldb_private::FileSpec file_spec
Resolved path for this dylib.
uint32_t mh_and_load_cmd_size
When we need to read a binary's mach header and load commands out of memory, this specifies how much ...
llvm::Triple::EnvironmentType os_env
LC_VERSION_MIN_... load command os environment.
uint32_t load_stop_id
The process stop ID that the sections for this image were loaded.
void PutToLog(lldb_private::Log *log) const
lldb::DataExtractorSP GetExtractor()
size_t vmsize
std::string name
uint64_t vmaddr