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 LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H
21#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H
22
23#include <mutex>
24#include <vector>
25
26#include "lldb/Host/SafeMachO.h"
28#include "lldb/Target/Process.h"
31#include "lldb/Utility/UUID.h"
32
33#include "DynamicLoaderDarwin.h"
34
36public:
38
39 ~DynamicLoaderMacOSXDYLD() override;
40
41 // Static Functions
42 static void Initialize();
43
44 static void Terminate();
45
46 static llvm::StringRef GetPluginNameStatic() { return "macosx-dyld"; }
47
48 static llvm::StringRef GetPluginDescriptionStatic();
49
51 CreateInstance(lldb_private::Process *process, bool force);
52
53 static void DebuggerInitialize(lldb_private::Debugger &debugger);
54
55 /// Called after attaching a process.
56 ///
57 /// Allow DynamicLoader plug-ins to execute some code after
58 /// attaching to a process.
59 bool ProcessDidExec() override;
60
62
64 lldb::addr_t &base_address, lldb_private::UUID &uuid,
65 lldb_private::LazyBool &using_shared_cache,
66 lldb_private::LazyBool &private_shared_cache) override;
67
68 // PluginInterface protocol
69 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
70
71 bool IsFullyInitialized() override;
72
73protected:
74 void PutToLog(lldb_private::Log *log) const;
75
76 void DoInitialImageFetch() override;
77
78 bool NeedToDoInitialImageFetch() override;
79
80 bool DidSetNotificationBreakpoint() override;
81
82 void DoClear() override;
83
85
86 static bool
87 NotifyBreakpointHit(void *baton,
89 lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
90
91 uint32_t AddrByteSize();
92
93 bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header,
94 lldb_private::DataExtractor *load_command_data);
95
97 ImageInfo &dylib_info,
98 lldb_private::FileSpec *lc_id_dylinker);
99
101 uint32_t version = 0;
102 uint32_t dylib_info_count = 0; // Version >= 1
105 bool processDetachedFromSharedRegion = false; // Version >= 1
106 bool libSystemInitialized = false; // Version >= 2
108
109 DYLDAllImageInfos() = default;
110
111 void Clear() {
112 version = 0;
117 libSystemInitialized = false;
119 }
120
121 bool IsValid() const { return version >= 1 && version <= 6; }
122 };
123
124 static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
125
126 bool SetNotificationBreakpoint() override;
127
128 void ClearNotificationBreakpoint() override;
129
130 // There is a little tricky bit where you might initially attach while dyld is
131 // updating
132 // the all_image_infos, and you can't read the infos, so you have to continue
133 // and pick it
134 // up when you hit the update breakpoint. At that point, you need to run this
135 // initialize
136 // function, but when you do it that way you DON'T need to do the extra work
137 // you would at
138 // the breakpoint.
139 // So this function will only do actual work if the image infos haven't been
140 // read yet.
141 // If it does do any work, then it will return true, and false otherwise.
142 // That way you can
143 // call it in the breakpoint action, and if it returns true you're done.
145
147
149 uint32_t image_infos_count);
150
152 uint32_t image_infos_count);
153
154 void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
155 uint32_t infos_count,
156 bool update_executable);
157
158 bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count,
159 ImageInfo::collection &image_infos);
160
165 mutable std::recursive_mutex m_mutex;
167
168private:
172};
173
174#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H
bool ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
void PutToLog(lldb_private::Log *log) const
bool RemoveModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr, uint32_t image_infos_count)
static void DebuggerInitialize(lldb_private::Debugger &debugger)
static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force)
void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos, uint32_t infos_count, bool update_executable)
static llvm::StringRef GetPluginNameStatic()
static llvm::StringRef GetPluginDescriptionStatic()
static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic)
llvm::StringRef GetPluginName() override
bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count, ImageInfo::collection &image_infos)
bool DidSetNotificationBreakpoint() override
uint32_t ParseLoadCommands(const lldb_private::DataExtractor &data, ImageInfo &dylib_info, lldb_private::FileSpec *lc_id_dylinker)
lldb_private::Status CanLoadImage() override
Ask if it is ok to try and load or unload an shared library (image).
DynamicLoaderMacOSXDYLD(const DynamicLoaderMacOSXDYLD &)=delete
bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header, lldb_private::DataExtractor *load_command_data)
bool ProcessDidExec() override
Called after attaching a process.
bool IsFullyInitialized() override
Return whether the dynamic loader is fully initialized and it's safe to call its APIs.
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.
bool AddModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr, uint32_t image_infos_count)
static bool NotifyBreakpointHit(void *baton, lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
DYLDAllImageInfos m_dyld_all_image_infos
const DynamicLoaderMacOSXDYLD & operator=(const DynamicLoaderMacOSXDYLD &)=delete
An data extractor class.
Definition: DataExtractor.h:48
A class to manage flag bits.
Definition: Debugger.h:80
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:54
A file utility class.
Definition: FileSpec.h:56
A plug-in interface definition class for debugging a process.
Definition: Process.h:343
An error handling class.
Definition: Status.h:118
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
ByteOrder
Byte ordering definitions.
uint64_t user_id_t
Definition: lldb-types.h:82
uint64_t addr_t
Definition: lldb-types.h:80