LLDB  mainline
DynamicLoaderMacOSXDYLD.h
Go to the documentation of this file.
1 //===-- DynamicLoaderMacOSXDYLD.h -------------------------------*- C++ -*-===//
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 
9 // This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
10 // watchOS / BridgeOS)
11 // platforms earlier than 2016, where lldb would read the "dyld_all_image_infos"
12 // dyld internal structure to understand where things were loaded and the
13 // solib loaded/unloaded notification function we put a breakpoint on gives us
14 // an array of (load address, mod time, file path) tuples.
15 //
16 // As of late 2016, the new DynamicLoaderMacOS plugin should be used, which uses
17 // dyld SPI functions to get the same information without reading internal dyld
18 // data structures.
19 
20 #ifndef liblldb_DynamicLoaderMacOSXDYLD_h_
21 #define liblldb_DynamicLoaderMacOSXDYLD_h_
22 
23 #include <mutex>
24 #include <vector>
25 
26 #include "lldb/Host/SafeMachO.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Utility/FileSpec.h"
31 #include "lldb/Utility/UUID.h"
32 
33 #include "DynamicLoaderDarwin.h"
34 
36 public:
38 
39  ~DynamicLoaderMacOSXDYLD() override;
40 
41  // Static Functions
42  static void Initialize();
43 
44  static void Terminate();
45 
47 
48  static const char *GetPluginDescriptionStatic();
49 
51  CreateInstance(lldb_private::Process *process, bool force);
52 
53  /// Called after attaching a process.
54  ///
55  /// Allow DynamicLoader plug-ins to execute some code after
56  /// attaching to a process.
57  bool ProcessDidExec() override;
58 
60 
62  lldb::addr_t &base_address, lldb_private::UUID &uuid,
63  lldb_private::LazyBool &using_shared_cache,
64  lldb_private::LazyBool &private_shared_cache) override;
65 
66  // PluginInterface protocol
68 
69  uint32_t GetPluginVersion() override;
70 
71 protected:
72  void PutToLog(lldb_private::Log *log) const;
73 
74  void DoInitialImageFetch() override;
75 
76  bool NeedToDoInitialImageFetch() override;
77 
78  bool DidSetNotificationBreakpoint() override;
79 
80  void DoClear() override;
81 
83 
84  static bool
85  NotifyBreakpointHit(void *baton,
87  lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
88 
90 
91  bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header,
92  lldb_private::DataExtractor *load_command_data);
93 
95  ImageInfo &dylib_info,
96  lldb_private::FileSpec *lc_id_dylinker);
97 
100  uint32_t dylib_info_count; // Version >= 1
101  lldb::addr_t dylib_info_addr; // Version >= 1
102  lldb::addr_t notification; // Version >= 1
103  bool processDetachedFromSharedRegion; // Version >= 1
104  bool libSystemInitialized; // Version >= 2
106 
108  : version(0), dylib_info_count(0),
109  dylib_info_addr(LLDB_INVALID_ADDRESS),
110  notification(LLDB_INVALID_ADDRESS),
111  processDetachedFromSharedRegion(false), libSystemInitialized(false),
112  dyldImageLoadAddress(LLDB_INVALID_ADDRESS) {}
113 
114  void Clear() {
115  version = 0;
116  dylib_info_count = 0;
117  dylib_info_addr = LLDB_INVALID_ADDRESS;
118  notification = LLDB_INVALID_ADDRESS;
119  processDetachedFromSharedRegion = false;
120  libSystemInitialized = false;
121  dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
122  }
123 
124  bool IsValid() const { return version >= 1 || version <= 6; }
125  };
126 
128 
129  bool SetNotificationBreakpoint() override;
130 
131  void ClearNotificationBreakpoint() override;
132 
133  // There is a little tricky bit where you might initially attach while dyld is
134  // updating
135  // the all_image_infos, and you can't read the infos, so you have to continue
136  // and pick it
137  // up when you hit the update breakpoint. At that point, you need to run this
138  // initialize
139  // function, but when you do it that way you DON'T need to do the extra work
140  // you would at
141  // the breakpoint.
142  // So this function will only do actual work if the image infos haven't been
143  // read yet.
144  // If it does do any work, then it will return true, and false otherwise.
145  // That way you can
146  // call it in the breakpoint action, and if it returns true you're done.
148 
150 
151  bool AddModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
152  uint32_t image_infos_count);
153 
155  uint32_t image_infos_count);
156 
158  uint32_t infos_count,
159  bool update_executable);
160 
161  bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count,
162  ImageInfo::collection &image_infos);
163 
168  mutable std::recursive_mutex m_mutex;
170 
171 private:
172  DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOSXDYLD);
173 };
174 
175 #endif // liblldb_DynamicLoaderMacOSXDYLD_h_
An data extractor class.
Definition: DataExtractor.h:47
bool RemoveModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr, uint32_t image_infos_count)
void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos, uint32_t infos_count, bool update_executable)
static lldb_private::ConstString GetPluginNameStatic()
bool AddModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr, uint32_t image_infos_count)
DynamicLoaderMacOSXDYLD(lldb_private::Process *process)
A file utility class.
Definition: FileSpec.h:55
bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count, ImageInfo::collection &image_infos)
static bool NotifyBreakpointHit(void *baton, lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
uint32_t ParseLoadCommands(const lldb_private::DataExtractor &data, ImageInfo &dylib_info, lldb_private::FileSpec *lc_id_dylinker)
static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic)
void PutToLog(lldb_private::Log *log) const
bool GetSharedCacheInformation(lldb::addr_t &base_address, lldb_private::UUID &uuid, lldb_private::LazyBool &using_shared_cache, lldb_private::LazyBool &private_shared_cache) override
Get information about the shared cache for a process, if possible.
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
uint64_t user_id_t
Definition: lldb-types.h:84
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
bool ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:64
DYLDAllImageInfos m_dyld_all_image_infos
static const char * GetPluginDescriptionStatic()
uint64_t addr_t
Definition: lldb-types.h:83
A uniqued constant string class.
Definition: ConstString.h:38
bool DidSetNotificationBreakpoint() override
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force)
bool ProcessDidExec() override
Called after attaching a process.
lldb_private::ConstString GetPluginName() override
lldb_private::Status CanLoadImage() override
Ask if it is ok to try and load or unload an shared library (image).
An error handling class.
Definition: Status.h:44
bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header, lldb_private::DataExtractor *load_command_data)