blob: 0f8b1902c8babac386db6c53c1a4d2fa6790b6d0 [file] [log] [blame]
Jason Molenda9ab5dc22016-07-21 08:30:55 +00001//===-- DynamicLoaderMacOS.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Breakpoint/StoppointCallbackContext.h"
11#include "lldb/Core/Debugger.h"
12#include "lldb/Core/Log.h"
13#include "lldb/Core/Module.h"
14#include "lldb/Core/PluginManager.h"
15#include "lldb/Core/Section.h"
16#include "lldb/Core/State.h"
17#include "lldb/Symbol/ClangASTContext.h"
Jason Molenda9ab5dc22016-07-21 08:30:55 +000018#include "lldb/Symbol/ObjectFile.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000019#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda9ab5dc22016-07-21 08:30:55 +000020#include "lldb/Target/ABI.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "lldb/Target/StackFrame.h"
Jason Molenda9ab5dc22016-07-21 08:30:55 +000022#include "lldb/Target/Target.h"
23#include "lldb/Target/Thread.h"
Jason Molenda9ab5dc22016-07-21 08:30:55 +000024
Jason Molenda9ab5dc22016-07-21 08:30:55 +000025#include "DynamicLoaderDarwin.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000026#include "DynamicLoaderMacOS.h"
Jason Molenda9ab5dc22016-07-21 08:30:55 +000027
28using namespace lldb;
29using namespace lldb_private;
30
Jason Molenda9ab5dc22016-07-21 08:30:55 +000031//----------------------------------------------------------------------
32// Create an instance of this class. This function is filled into
33// the plugin info class that gets handed out by the plugin factory and
34// allows the lldb to instantiate an instance of this class.
35//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000036DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
37 bool force) {
38 bool create = force;
39 if (!create) {
40 create = true;
41 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
42 if (exe_module) {
43 ObjectFile *object_file = exe_module->GetObjectFile();
44 if (object_file) {
45 create = (object_file->GetStrata() == ObjectFile::eStrataUser);
46 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +000047 }
48
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 if (create) {
50 const llvm::Triple &triple_ref =
51 process->GetTarget().GetArchitecture().GetTriple();
52 switch (triple_ref.getOS()) {
53 case llvm::Triple::Darwin:
54 case llvm::Triple::MacOSX:
55 case llvm::Triple::IOS:
56 case llvm::Triple::TvOS:
57 case llvm::Triple::WatchOS:
58 create = triple_ref.getVendor() == llvm::Triple::Apple;
59 break;
60 default:
Jason Molenda716814a2016-07-22 22:26:26 +000061 create = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 break;
63 }
Jason Molenda716814a2016-07-22 22:26:26 +000064 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 }
66
67 if (UseDYLDSPI(process) == false) {
68 create = false;
69 }
70
71 if (create)
72 return new DynamicLoaderMacOS(process);
73 return NULL;
Jason Molenda9ab5dc22016-07-21 08:30:55 +000074}
75
76//----------------------------------------------------------------------
77// Constructor
78//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000079DynamicLoaderMacOS::DynamicLoaderMacOS(Process *process)
80 : DynamicLoaderDarwin(process), m_image_infos_stop_id(UINT32_MAX),
81 m_break_id(LLDB_INVALID_BREAK_ID), m_mutex() {}
Jason Molenda9ab5dc22016-07-21 08:30:55 +000082
83//----------------------------------------------------------------------
84// Destructor
85//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000086DynamicLoaderMacOS::~DynamicLoaderMacOS() {
87 if (LLDB_BREAK_ID_IS_VALID(m_break_id))
88 m_process->GetTarget().RemoveBreakpointByID(m_break_id);
Jason Molenda9ab5dc22016-07-21 08:30:55 +000089}
90
Kate Stoneb9c1b512016-09-06 20:57:50 +000091bool DynamicLoaderMacOS::ProcessDidExec() {
92 std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
93 bool did_exec = false;
94 if (m_process) {
95 // If we are stopped after an exec, we will have only one thread...
96 if (m_process->GetThreadList().GetSize() == 1) {
97 // See if we are stopped at '_dyld_start'
98 ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
99 if (thread_sp) {
100 lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
101 if (frame_sp) {
102 const Symbol *symbol =
103 frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
104 if (symbol) {
105 if (symbol->GetName() == ConstString("_dyld_start"))
106 did_exec = true;
107 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000108 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000110 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 if (did_exec) {
114 m_libpthread_module_wp.reset();
115 m_pthread_getspecific_addr.Clear();
116 }
117 return did_exec;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000118}
119
120//----------------------------------------------------------------------
121// Clear out the state of this class.
122//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123void DynamicLoaderMacOS::DoClear() {
124 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000125
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126 if (LLDB_BREAK_ID_IS_VALID(m_break_id))
127 m_process->GetTarget().RemoveBreakpointByID(m_break_id);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 m_break_id = LLDB_INVALID_BREAK_ID;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000130}
131
132//----------------------------------------------------------------------
133// Check if we have found DYLD yet
134//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135bool DynamicLoaderMacOS::DidSetNotificationBreakpoint() {
136 return LLDB_BREAK_ID_IS_VALID(m_break_id);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000137}
138
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139void DynamicLoaderMacOS::ClearNotificationBreakpoint() {
140 if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
141 m_process->GetTarget().RemoveBreakpointByID(m_break_id);
142 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000143}
144
145//----------------------------------------------------------------------
146// Try and figure out where dyld is by first asking the Process
147// if it knows (which currently calls down in the lldb::Process
148// to get the DYLD info (available on SnowLeopard only). If that fails,
149// then check in the default addresses.
150//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151void DynamicLoaderMacOS::DoInitialImageFetch() {
152 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000153
Jason Molenda848c7be2017-01-19 00:20:29 +0000154 // Remove any binaries we pre-loaded in the Target before launching/attaching.
155 // If the same binaries are present in the process, we'll get them from the
156 // shared module cache, we won't need to re-load them from disk.
157 UnloadAllImages();
158
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 StructuredData::ObjectSP all_image_info_json_sp(
160 m_process->GetLoadedDynamicLibrariesInfos());
161 ImageInfo::collection image_infos;
162 if (all_image_info_json_sp.get() &&
163 all_image_info_json_sp->GetAsDictionary() &&
164 all_image_info_json_sp->GetAsDictionary()->HasKey("images") &&
165 all_image_info_json_sp->GetAsDictionary()
166 ->GetValueForKey("images")
167 ->GetAsArray()) {
168 if (JSONImageInformationIntoImageInfo(all_image_info_json_sp,
169 image_infos)) {
170 if (log)
171 log->Printf("Initial module fetch: Adding %" PRId64 " modules.\n",
172 (uint64_t)image_infos.size());
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 UpdateSpecialBinariesFromNewImageInfos(image_infos);
175 AddModulesUsingImageInfos(image_infos);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000176 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177 }
178
179 m_dyld_image_infos_stop_id = m_process->GetStopID();
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000180}
181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182bool DynamicLoaderMacOS::NeedToDoInitialImageFetch() { return true; }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000183
184//----------------------------------------------------------------------
185// Static callback function that gets called when our DYLD notification
186// breakpoint gets hit. We update all of our image infos and then
187// let our super class DynamicLoader class decide if we should stop
188// or not (based on global preference).
189//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
191 StoppointCallbackContext *context,
192 lldb::user_id_t break_id,
193 lldb::user_id_t break_loc_id) {
194 // Let the event know that the images have changed
195 // DYLD passes three arguments to the notification breakpoint.
196 // Arg1: enum dyld_notify_mode mode - 0 = adding, 1 = removing, 2 = remove all
197 // Arg2: unsigned long icount - Number of shared libraries
198 // added/removed
199 // Arg3: uint64_t mach_headers[] - Array of load addresses of binaries
200 // added/removed
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 DynamicLoaderMacOS *dyld_instance = (DynamicLoaderMacOS *)baton;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000203
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 ExecutionContext exe_ctx(context->exe_ctx_ref);
205 Process *process = exe_ctx.GetProcessPtr();
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 // This is a sanity check just in case this dyld_instance is an old dyld
208 // plugin's breakpoint still lying around.
209 if (process != dyld_instance->m_process)
210 return false;
211
212 if (dyld_instance->m_image_infos_stop_id != UINT32_MAX &&
213 process->GetStopID() < dyld_instance->m_image_infos_stop_id) {
214 return false;
215 }
216
217 const lldb::ABISP &abi = process->GetABI();
218 if (abi) {
219 // Build up the value array to store the three arguments given above, then
220 // get the values from the ABI:
221
222 ClangASTContext *clang_ast_context =
223 process->GetTarget().GetScratchClangASTContext();
224 ValueList argument_values;
225
226 Value mode_value; // enum dyld_notify_mode { dyld_notify_adding=0,
227 // dyld_notify_removing=1, dyld_notify_remove_all=2 };
228 Value count_value; // unsigned long count
229 Value headers_value; // uint64_t machHeaders[] (aka void*)
230
231 CompilerType clang_void_ptr_type =
232 clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
233 CompilerType clang_uint32_type =
234 clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
235 lldb::eEncodingUint, 32);
236 CompilerType clang_uint64_type =
237 clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
238 lldb::eEncodingUint, 32);
239
240 mode_value.SetValueType(Value::eValueTypeScalar);
241 mode_value.SetCompilerType(clang_uint32_type);
242
243 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 4) {
244 count_value.SetValueType(Value::eValueTypeScalar);
245 count_value.SetCompilerType(clang_uint32_type);
246 } else {
247 count_value.SetValueType(Value::eValueTypeScalar);
248 count_value.SetCompilerType(clang_uint64_type);
Jason Molenda716814a2016-07-22 22:26:26 +0000249 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000250
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 headers_value.SetValueType(Value::eValueTypeScalar);
252 headers_value.SetCompilerType(clang_void_ptr_type);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 argument_values.PushValue(mode_value);
255 argument_values.PushValue(count_value);
256 argument_values.PushValue(headers_value);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
259 uint32_t dyld_mode =
260 argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
261 if (dyld_mode != static_cast<uint32_t>(-1)) {
262 // Okay the mode was right, now get the number of elements, and the
263 // array of new elements...
264 uint32_t image_infos_count =
265 argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
266 if (image_infos_count != static_cast<uint32_t>(-1)) {
267 addr_t header_array =
268 argument_values.GetValueAtIndex(2)->GetScalar().ULongLong(-1);
269 if (header_array != static_cast<uint64_t>(-1)) {
270 std::vector<addr_t> image_load_addresses;
271 for (uint64_t i = 0; i < image_infos_count; i++) {
272 Error error;
273 addr_t addr = process->ReadUnsignedIntegerFromMemory(
274 header_array + (8 * i), 8, LLDB_INVALID_ADDRESS, error);
275 if (addr != LLDB_INVALID_ADDRESS) {
276 image_load_addresses.push_back(addr);
277 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000278 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 if (dyld_mode == 0) {
280 // dyld_notify_adding
281 dyld_instance->AddBinaries(image_load_addresses);
282 } else if (dyld_mode == 1) {
283 // dyld_notify_removing
284 dyld_instance->UnloadImages(image_load_addresses);
285 } else if (dyld_mode == 2) {
286 // dyld_notify_remove_all
287 dyld_instance->UnloadAllImages();
288 }
289 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000290 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000291 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000292 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 } else {
294 process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
295 "No ABI plugin located for triple %s -- shared libraries will not be "
296 "registered!\n",
297 process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
298 }
299
300 // Return true to stop the target, false to just let the target run
301 return dyld_instance->GetStopWhenImagesChange();
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000302}
303
Kate Stoneb9c1b512016-09-06 20:57:50 +0000304void DynamicLoaderMacOS::AddBinaries(
305 const std::vector<lldb::addr_t> &load_addresses) {
306 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
307 ImageInfo::collection image_infos;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000308
Kate Stoneb9c1b512016-09-06 20:57:50 +0000309 if (log)
310 log->Printf("Adding %" PRId64 " modules.", (uint64_t)load_addresses.size());
311 StructuredData::ObjectSP binaries_info_sp =
312 m_process->GetLoadedDynamicLibrariesInfos(load_addresses);
313 if (binaries_info_sp.get() && binaries_info_sp->GetAsDictionary() &&
314 binaries_info_sp->GetAsDictionary()->HasKey("images") &&
315 binaries_info_sp->GetAsDictionary()
316 ->GetValueForKey("images")
317 ->GetAsArray() &&
318 binaries_info_sp->GetAsDictionary()
319 ->GetValueForKey("images")
320 ->GetAsArray()
321 ->GetSize() == load_addresses.size()) {
322 if (JSONImageInformationIntoImageInfo(binaries_info_sp, image_infos)) {
323 UpdateSpecialBinariesFromNewImageInfos(image_infos);
324 AddModulesUsingImageInfos(image_infos);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000325 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 m_dyld_image_infos_stop_id = m_process->GetStopID();
327 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000328}
329
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000330// Dump the _dyld_all_image_infos members and all current image infos
331// that we have parsed to the file handle provided.
332//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333void DynamicLoaderMacOS::PutToLog(Log *log) const {
334 if (log == NULL)
335 return;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000336}
337
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338bool DynamicLoaderMacOS::SetNotificationBreakpoint() {
339 if (m_break_id == LLDB_INVALID_BREAK_ID) {
340 ConstString g_symbol_name("_dyld_debugger_notification");
341 const Symbol *symbol = nullptr;
342 ModuleSP dyld_sp(GetDYLDModule());
343 if (dyld_sp) {
344 symbol = dyld_sp->FindFirstSymbolWithNameAndType(g_symbol_name,
345 eSymbolTypeCode);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000346 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000347 if (symbol &&
348 (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
349 addr_t symbol_address =
350 symbol->GetAddressRef().GetOpcodeLoadAddress(&m_process->GetTarget());
351 if (symbol_address != LLDB_INVALID_ADDRESS) {
352 bool internal = true;
353 bool hardware = false;
354 Breakpoint *breakpoint =
355 m_process->GetTarget()
356 .CreateBreakpoint(symbol_address, internal, hardware)
357 .get();
358 breakpoint->SetCallback(DynamicLoaderMacOS::NotifyBreakpointHit, this,
359 true);
360 breakpoint->SetBreakpointKind("shared-library-event");
361 m_break_id = breakpoint->GetID();
362 }
363 }
364 }
365 return m_break_id != LLDB_INVALID_BREAK_ID;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000366}
367
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000368addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369DynamicLoaderMacOS::GetDyldLockVariableAddressFromModule(Module *module) {
370 SymbolContext sc;
371 SymbolVendor *sym_vendor = module->GetSymbolVendor();
372 Target &target = m_process->GetTarget();
373 if (sym_vendor) {
374 Symtab *symtab = sym_vendor->GetSymtab();
375 if (symtab) {
376 std::vector<uint32_t> match_indexes;
377 ConstString g_symbol_name("_dyld_global_lock_held");
378 uint32_t num_matches = 0;
379 num_matches =
380 symtab->AppendSymbolIndexesWithName(g_symbol_name, match_indexes);
381 if (num_matches == 1) {
382 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[0]);
383 if (symbol &&
384 (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
385 return symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000386 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000387 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000388 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389 }
390 return LLDB_INVALID_ADDRESS;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000391}
392
393// Look for this symbol:
394//
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395// int __attribute__((visibility("hidden"))) _dyld_global_lock_held =
396// 0;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000397//
398// in libdyld.dylib.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399Error DynamicLoaderMacOS::CanLoadImage() {
400 Error error;
401 addr_t symbol_address = LLDB_INVALID_ADDRESS;
402 Target &target = m_process->GetTarget();
403 const ModuleList &target_modules = target.GetImages();
404 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
405 const size_t num_modules = target_modules.GetSize();
406 ConstString g_libdyld_name("libdyld.dylib");
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 // Find any modules named "libdyld.dylib" and look for the symbol there first
409 for (size_t i = 0; i < num_modules; i++) {
410 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
411 if (module_pointer) {
412 if (module_pointer->GetFileSpec().GetFilename() == g_libdyld_name) {
413 symbol_address = GetDyldLockVariableAddressFromModule(module_pointer);
414 if (symbol_address != LLDB_INVALID_ADDRESS)
415 break;
416 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000417 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000418 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000419
Kate Stoneb9c1b512016-09-06 20:57:50 +0000420 // Search through all modules looking for the symbol in them
421 if (symbol_address == LLDB_INVALID_ADDRESS) {
422 for (size_t i = 0; i < num_modules; i++) {
423 Module *module_pointer =
424 target_modules.GetModulePointerAtIndexUnlocked(i);
425 if (module_pointer) {
426 addr_t symbol_address =
427 GetDyldLockVariableAddressFromModule(module_pointer);
428 if (symbol_address != LLDB_INVALID_ADDRESS)
429 break;
430 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000431 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000433
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 // Default assumption is that it is OK to load images.
435 // Only say that we cannot load images if we find the symbol in libdyld and it
436 // indicates that
437 // we cannot.
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000438
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 if (symbol_address != LLDB_INVALID_ADDRESS) {
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000440 {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 int lock_held =
442 m_process->ReadUnsignedIntegerFromMemory(symbol_address, 4, 0, error);
443 if (lock_held != 0) {
Jason Molenda37397352016-07-22 00:17:55 +0000444 error.SetErrorToGenericError();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445 }
Jason Molenda37397352016-07-22 00:17:55 +0000446 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 } else {
448 // If we were unable to find _dyld_global_lock_held in any modules, or it is
449 // not loaded into
450 // memory yet, we may be at process startup (sitting at _dyld_start) - so we
451 // should not allow
452 // dlopen calls.
453 error.SetErrorToGenericError();
454 }
455 return error;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000456}
457
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458bool DynamicLoaderMacOS::GetSharedCacheInformation(
459 lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
460 LazyBool &private_shared_cache) {
461 base_address = LLDB_INVALID_ADDRESS;
462 uuid.Clear();
463 using_shared_cache = eLazyBoolCalculate;
464 private_shared_cache = eLazyBoolCalculate;
Jason Molenda13becd42016-07-29 00:18:39 +0000465
Kate Stoneb9c1b512016-09-06 20:57:50 +0000466 if (m_process) {
467 StructuredData::ObjectSP info = m_process->GetSharedCacheInfo();
468 StructuredData::Dictionary *info_dict = nullptr;
469 if (info.get() && info->GetAsDictionary()) {
470 info_dict = info->GetAsDictionary();
Jason Molenda13becd42016-07-29 00:18:39 +0000471 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472
473 // {"shared_cache_base_address":140735683125248,"shared_cache_uuid":"DDB8D70C-C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false}
474
475 if (info_dict && info_dict->HasKey("shared_cache_uuid") &&
476 info_dict->HasKey("no_shared_cache") &&
477 info_dict->HasKey("shared_cache_base_address")) {
478 base_address = info_dict->GetValueForKey("shared_cache_base_address")
479 ->GetIntegerValue(LLDB_INVALID_ADDRESS);
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000480 std::string uuid_str =
481 info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482 if (!uuid_str.empty())
483 uuid.SetFromCString(uuid_str.c_str());
484 if (info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue() ==
485 false)
486 using_shared_cache = eLazyBoolYes;
487 else
488 using_shared_cache = eLazyBoolNo;
489 if (info_dict->GetValueForKey("shared_cache_private_cache")
490 ->GetBooleanValue())
491 private_shared_cache = eLazyBoolYes;
492 else
493 private_shared_cache = eLazyBoolNo;
494
495 return true;
496 }
497 }
498 return false;
Jason Molenda13becd42016-07-29 00:18:39 +0000499}
500
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501void DynamicLoaderMacOS::Initialize() {
502 PluginManager::RegisterPlugin(GetPluginNameStatic(),
503 GetPluginDescriptionStatic(), CreateInstance);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000504}
505
Kate Stoneb9c1b512016-09-06 20:57:50 +0000506void DynamicLoaderMacOS::Terminate() {
507 PluginManager::UnregisterPlugin(CreateInstance);
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000508}
509
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510lldb_private::ConstString DynamicLoaderMacOS::GetPluginNameStatic() {
511 static ConstString g_name("macos-dyld");
512 return g_name;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000513}
514
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515const char *DynamicLoaderMacOS::GetPluginDescriptionStatic() {
516 return "Dynamic loader plug-in that watches for shared library loads/unloads "
517 "in MacOSX user processes.";
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000518}
519
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000520//------------------------------------------------------------------
521// PluginInterface protocol
522//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523lldb_private::ConstString DynamicLoaderMacOS::GetPluginName() {
524 return GetPluginNameStatic();
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000525}
526
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527uint32_t DynamicLoaderMacOS::GetPluginVersion() { return 1; }