jasonmolenda created this revision.
jasonmolenda added a reviewer: JDevlieghere.
jasonmolenda added a project: LLDB.
Herald added a project: All.
jasonmolenda requested review of this revision.
Herald added a subscriber: lldb-commits.

In macOS Ventura et al, the dynamic linker, dyld, has moved into the shared 
cache image.  A process starts with our normal on-disk /usr/lib/dyld, and the 
first thing it does is execute into an in-memory-only copy of dyld in the 
shared cache blob.  lldb needs to track this transition as we hand off from one 
dyld to the other, to get notified about newly added binary images in the 
process.

All of the action happens in DynamicLoaderMacOS::NotifyBreakpointHit(), where 
we detect two new cases:  A new `dyld_image_dyld_moved` which is called when 
the launch dyld is about to transition over to the shared cache dyld, and we 
can get the address of the new notification function out of all_image_infos and 
set an address breakpoint and we clear out the list of known binary images.  
And a new mode of `dyld_notify_adding` where we have no binary images 
registered (because it was cleared in the previous step), so we know that this 
is a new shared cache dyld doing its first notification, and treat it 
appropriately, setting our normal by-name notification breakpoint.

rdar://84222158


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D127247

Files:
  lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
  lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
  lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
  lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h

Index: lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
===================================================================
--- lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
+++ lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
@@ -71,6 +71,10 @@
 
   bool DidSetNotificationBreakpoint() override;
 
+  bool SetDYLDHandoverBreakpoint(lldb::addr_t notification_address);
+
+  void ClearDYLDHandoverBreakpoint();
+
   void AddBinaries(const std::vector<lldb::addr_t> &load_addresses);
 
   void DoClear() override;
@@ -94,6 +98,7 @@
   uint32_t m_image_infos_stop_id; // The Stop ID the last time we
                                   // loaded/unloaded images
   lldb::user_id_t m_break_id;
+  lldb::user_id_t m_dyld_handover_break_id;
   mutable std::recursive_mutex m_mutex;
   lldb::addr_t m_maybe_image_infos_address; // If dyld is still maintaining the
                                             // all_image_infos address, store it
Index: lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Target/ABI.h"
+#include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
@@ -76,13 +77,16 @@
 // Constructor
 DynamicLoaderMacOS::DynamicLoaderMacOS(Process *process)
     : DynamicLoaderDarwin(process), m_image_infos_stop_id(UINT32_MAX),
-      m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
+      m_break_id(LLDB_INVALID_BREAK_ID), 
+      m_dyld_handover_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
       m_maybe_image_infos_address(LLDB_INVALID_ADDRESS) {}
 
 // Destructor
 DynamicLoaderMacOS::~DynamicLoaderMacOS() {
   if (LLDB_BREAK_ID_IS_VALID(m_break_id))
     m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+  if (LLDB_BREAK_ID_IS_VALID(m_dyld_handover_break_id))
+    m_process->GetTarget().RemoveBreakpointByID(m_dyld_handover_break_id);
 }
 
 bool DynamicLoaderMacOS::ProcessDidExec() {
@@ -135,8 +139,11 @@
 
   if (LLDB_BREAK_ID_IS_VALID(m_break_id))
     m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+  if (LLDB_BREAK_ID_IS_VALID(m_dyld_handover_break_id))
+    m_process->GetTarget().RemoveBreakpointByID(m_dyld_handover_break_id);
 
   m_break_id = LLDB_INVALID_BREAK_ID;
+  m_dyld_handover_break_id = LLDB_INVALID_BREAK_ID;
 }
 
 // Check if we have found DYLD yet
@@ -286,13 +293,51 @@
             }
             if (dyld_mode == 0) {
               // dyld_notify_adding
-              dyld_instance->AddBinaries(image_load_addresses);
+              if (process->GetTarget().GetImages().GetSize() == 0) {
+                // When all images have been removed, we're doing the
+                // dyld handover from a launch-dyld to a shared-cache-dyld,
+                // and we've just hit our one-shot address breakpoint in
+                // the sc-dyld.  Note that the image addresses passed to
+                // this function are inferior sizeof(void*) not uint64_t's
+                // like our normal notification, so don't even look at
+                // image_load_addresses.
+
+                dyld_instance->ClearDYLDHandoverBreakpoint();
+
+                dyld_instance->DoInitialImageFetch();
+                dyld_instance->SetNotificationBreakpoint();
+              } else {
+                dyld_instance->AddBinaries(image_load_addresses);
+              }
             } else if (dyld_mode == 1) {
               // dyld_notify_removing
               dyld_instance->UnloadImages(image_load_addresses);
             } else if (dyld_mode == 2) {
               // dyld_notify_remove_all
               dyld_instance->UnloadAllImages();
+            } else if (dyld_mode == 3 && image_infos_count == 1) {
+              // dyld_image_dyld_moved
+
+              dyld_instance->ClearNotificationBreakpoint();
+              dyld_instance->UnloadAllImages();
+              dyld_instance->ClearDYLDModule();
+              process->GetTarget().GetImages().Clear();
+              process->GetTarget().GetSectionLoadList().Clear();
+
+              addr_t all_image_infos = process->GetImageInfoAddress();
+              int addr_size =
+                  process->GetTarget().GetArchitecture().GetAddressByteSize();
+              addr_t notification_location = all_image_infos + 
+                                             4 +        // version
+                                             4 +        // infoArrayCount
+                                             addr_size; // infoArray
+              Status error;
+              addr_t notification_addr =
+                  process->ReadPointerFromMemory(notification_location, error);
+              if (ABISP abi_sp = process->GetABI())
+                notification_addr = abi_sp->FixCodeAddress (notification_addr);
+
+              dyld_instance->SetDYLDHandoverBreakpoint(notification_addr);
             }
           }
         }
@@ -371,6 +416,27 @@
   return m_break_id != LLDB_INVALID_BREAK_ID;
 }
 
+bool DynamicLoaderMacOS::SetDYLDHandoverBreakpoint(addr_t notification_address) {
+  if (m_dyld_handover_break_id == LLDB_INVALID_BREAK_ID) {
+    BreakpointSP dyld_handover_bp =
+        m_process->GetTarget().CreateBreakpoint(notification_address, true,
+                                              false);
+    dyld_handover_bp->SetCallback(
+        DynamicLoaderMacOS::NotifyBreakpointHit, this, true);
+    dyld_handover_bp->SetOneShot(true);
+    m_dyld_handover_break_id = dyld_handover_bp->GetID();
+    return true;
+  }
+  return false;
+}
+
+void DynamicLoaderMacOS::ClearDYLDHandoverBreakpoint() {
+  if (LLDB_BREAK_ID_IS_VALID(m_dyld_handover_break_id))
+    m_process->GetTarget().RemoveBreakpointByID(m_dyld_handover_break_id);
+  m_dyld_handover_break_id = LLDB_INVALID_BREAK_ID;
+}
+
+
 addr_t
 DynamicLoaderMacOS::GetDyldLockVariableAddressFromModule(Module *module) {
   SymbolContext sc;
Index: lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
===================================================================
--- lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
+++ lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
@@ -71,6 +71,8 @@
 
   lldb::ModuleSP GetDYLDModule();
 
+  void ClearDYLDModule();
+
   class Segment {
   public:
     Segment() : name() {}
Index: lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -611,6 +611,8 @@
   return dyld_sp;
 }
 
+void DynamicLoaderDarwin::ClearDYLDModule() { m_dyld_module_wp.reset(); }
+
 bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
     ImageInfo::collection &image_infos) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] ... Jason Molenda via Phabricator via lldb-commits

Reply via email to