|
14 | 14 | #include "lldb/Symbol/ObjectFile.h"
|
15 | 15 | #include "lldb/Symbol/SymbolVendor.h"
|
16 | 16 | #include "lldb/Target/ABI.h"
|
| 17 | +#include "lldb/Target/SectionLoadList.h" |
17 | 18 | #include "lldb/Target/StackFrame.h"
|
18 | 19 | #include "lldb/Target/Target.h"
|
19 | 20 | #include "lldb/Target/Thread.h"
|
@@ -76,13 +77,16 @@ DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
|
76 | 77 | // Constructor
|
77 | 78 | DynamicLoaderMacOS::DynamicLoaderMacOS(Process *process)
|
78 | 79 | : DynamicLoaderDarwin(process), m_image_infos_stop_id(UINT32_MAX),
|
79 |
| - m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(), |
| 80 | + m_break_id(LLDB_INVALID_BREAK_ID), |
| 81 | + m_dyld_handover_break_id(LLDB_INVALID_BREAK_ID), m_mutex(), |
80 | 82 | m_maybe_image_infos_address(LLDB_INVALID_ADDRESS) {}
|
81 | 83 |
|
82 | 84 | // Destructor
|
83 | 85 | DynamicLoaderMacOS::~DynamicLoaderMacOS() {
|
84 | 86 | if (LLDB_BREAK_ID_IS_VALID(m_break_id))
|
85 | 87 | m_process->GetTarget().RemoveBreakpointByID(m_break_id);
|
| 88 | + if (LLDB_BREAK_ID_IS_VALID(m_dyld_handover_break_id)) |
| 89 | + m_process->GetTarget().RemoveBreakpointByID(m_dyld_handover_break_id); |
86 | 90 | }
|
87 | 91 |
|
88 | 92 | bool DynamicLoaderMacOS::ProcessDidExec() {
|
@@ -135,8 +139,11 @@ void DynamicLoaderMacOS::DoClear() {
|
135 | 139 |
|
136 | 140 | if (LLDB_BREAK_ID_IS_VALID(m_break_id))
|
137 | 141 | m_process->GetTarget().RemoveBreakpointByID(m_break_id);
|
| 142 | + if (LLDB_BREAK_ID_IS_VALID(m_dyld_handover_break_id)) |
| 143 | + m_process->GetTarget().RemoveBreakpointByID(m_dyld_handover_break_id); |
138 | 144 |
|
139 | 145 | m_break_id = LLDB_INVALID_BREAK_ID;
|
| 146 | + m_dyld_handover_break_id = LLDB_INVALID_BREAK_ID; |
140 | 147 | }
|
141 | 148 |
|
142 | 149 | // Check if we have found DYLD yet
|
@@ -286,13 +293,50 @@ bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
|
286 | 293 | }
|
287 | 294 | if (dyld_mode == 0) {
|
288 | 295 | // dyld_notify_adding
|
289 |
| - dyld_instance->AddBinaries(image_load_addresses); |
| 296 | + if (process->GetTarget().GetImages().GetSize() == 0) { |
| 297 | + // When all images have been removed, we're doing the |
| 298 | + // dyld handover from a launch-dyld to a shared-cache-dyld, |
| 299 | + // and we've just hit our one-shot address breakpoint in |
| 300 | + // the sc-dyld. Note that the image addresses passed to |
| 301 | + // this function are inferior sizeof(void*) not uint64_t's |
| 302 | + // like our normal notification, so don't even look at |
| 303 | + // image_load_addresses. |
| 304 | + |
| 305 | + dyld_instance->ClearDYLDHandoverBreakpoint(); |
| 306 | + |
| 307 | + dyld_instance->DoInitialImageFetch(); |
| 308 | + dyld_instance->SetNotificationBreakpoint(); |
| 309 | + } else { |
| 310 | + dyld_instance->AddBinaries(image_load_addresses); |
| 311 | + } |
290 | 312 | } else if (dyld_mode == 1) {
|
291 | 313 | // dyld_notify_removing
|
292 | 314 | dyld_instance->UnloadImages(image_load_addresses);
|
293 | 315 | } else if (dyld_mode == 2) {
|
294 | 316 | // dyld_notify_remove_all
|
295 | 317 | dyld_instance->UnloadAllImages();
|
| 318 | + } else if (dyld_mode == 3 && image_infos_count == 1) { |
| 319 | + // dyld_image_dyld_moved |
| 320 | + |
| 321 | + dyld_instance->ClearNotificationBreakpoint(); |
| 322 | + dyld_instance->UnloadAllImages(); |
| 323 | + dyld_instance->ClearDYLDModule(); |
| 324 | + process->GetTarget().GetImages().Clear(); |
| 325 | + process->GetTarget().GetSectionLoadList().Clear(); |
| 326 | + |
| 327 | + addr_t all_image_infos = process->GetImageInfoAddress(); |
| 328 | + int addr_size = |
| 329 | + process->GetTarget().GetArchitecture().GetAddressByteSize(); |
| 330 | + addr_t notification_location = all_image_infos + 4 + // version |
| 331 | + 4 + // infoArrayCount |
| 332 | + addr_size; // infoArray |
| 333 | + Status error; |
| 334 | + addr_t notification_addr = |
| 335 | + process->ReadPointerFromMemory(notification_location, error); |
| 336 | + if (ABISP abi_sp = process->GetABI()) |
| 337 | + notification_addr = abi_sp->FixCodeAddress(notification_addr); |
| 338 | + |
| 339 | + dyld_instance->SetDYLDHandoverBreakpoint(notification_addr); |
296 | 340 | }
|
297 | 341 | }
|
298 | 342 | }
|
@@ -371,6 +415,26 @@ bool DynamicLoaderMacOS::SetNotificationBreakpoint() {
|
371 | 415 | return m_break_id != LLDB_INVALID_BREAK_ID;
|
372 | 416 | }
|
373 | 417 |
|
| 418 | +bool DynamicLoaderMacOS::SetDYLDHandoverBreakpoint( |
| 419 | + addr_t notification_address) { |
| 420 | + if (m_dyld_handover_break_id == LLDB_INVALID_BREAK_ID) { |
| 421 | + BreakpointSP dyld_handover_bp = m_process->GetTarget().CreateBreakpoint( |
| 422 | + notification_address, true, false); |
| 423 | + dyld_handover_bp->SetCallback(DynamicLoaderMacOS::NotifyBreakpointHit, this, |
| 424 | + true); |
| 425 | + dyld_handover_bp->SetOneShot(true); |
| 426 | + m_dyld_handover_break_id = dyld_handover_bp->GetID(); |
| 427 | + return true; |
| 428 | + } |
| 429 | + return false; |
| 430 | +} |
| 431 | + |
| 432 | +void DynamicLoaderMacOS::ClearDYLDHandoverBreakpoint() { |
| 433 | + if (LLDB_BREAK_ID_IS_VALID(m_dyld_handover_break_id)) |
| 434 | + m_process->GetTarget().RemoveBreakpointByID(m_dyld_handover_break_id); |
| 435 | + m_dyld_handover_break_id = LLDB_INVALID_BREAK_ID; |
| 436 | +} |
| 437 | + |
374 | 438 | addr_t
|
375 | 439 | DynamicLoaderMacOS::GetDyldLockVariableAddressFromModule(Module *module) {
|
376 | 440 | SymbolContext sc;
|
|
0 commit comments