Bug Summary

File:tools/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
Warning:line 1153, column 54
Potential buffer overflow. Replace with 'sizeof(developer_dir_path) - strlen(developer_dir_path) - 1' or use a safer 'strlcat' API

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1//===-- PlatformDarwin.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 "PlatformDarwin.h"
11
12// C Includes
13#include <string.h>
14
15// C++ Includes
16#include <algorithm>
17#include <mutex>
18
19// Other libraries and framework includes
20#include "clang/Basic/VersionTuple.h"
21// Project includes
22#include "lldb/Breakpoint/BreakpointLocation.h"
23#include "lldb/Breakpoint/BreakpointSite.h"
24#include "lldb/Core/Debugger.h"
25#include "lldb/Core/Module.h"
26#include "lldb/Core/ModuleSpec.h"
27#include "lldb/Host/Host.h"
28#include "lldb/Host/HostInfo.h"
29#include "lldb/Host/Symbols.h"
30#include "lldb/Host/XML.h"
31#include "lldb/Interpreter/CommandInterpreter.h"
32#include "lldb/Symbol/ObjectFile.h"
33#include "lldb/Symbol/SymbolFile.h"
34#include "lldb/Symbol/SymbolVendor.h"
35#include "lldb/Target/Platform.h"
36#include "lldb/Target/Process.h"
37#include "lldb/Target/Target.h"
38#include "lldb/Utility/DataBufferLLVM.h"
39#include "lldb/Utility/Log.h"
40#include "lldb/Utility/Status.h"
41#include "lldb/Utility/Timer.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/Support/FileSystem.h"
44#include "llvm/Support/Threading.h"
45
46#if defined(__APPLE__)
47#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH
48#endif
49
50using namespace lldb;
51using namespace lldb_private;
52
53//------------------------------------------------------------------
54/// Default Constructor
55//------------------------------------------------------------------
56PlatformDarwin::PlatformDarwin(bool is_host)
57 : PlatformPOSIX(is_host), // This is the local host platform
58 m_developer_directory() {}
59
60//------------------------------------------------------------------
61/// Destructor.
62///
63/// The destructor is virtual since this class is designed to be
64/// inherited from by the plug-in instance.
65//------------------------------------------------------------------
66PlatformDarwin::~PlatformDarwin() {}
67
68FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
69 Target *target, Module &module, Stream *feedback_stream) {
70 FileSpecList file_list;
71 if (target &&
72 target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython) {
73 // NB some extensions might be meaningful and should not be stripped -
74 // "this.binary.file"
75 // should not lose ".file" but GetFileNameStrippingExtension() will do
76 // precisely that.
77 // Ideally, we should have a per-platform list of extensions (".exe",
78 // ".app", ".dSYM", ".framework")
79 // which should be stripped while leaving "this.binary.file" as-is.
80 ScriptInterpreter *script_interpreter =
81 target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
82
83 FileSpec module_spec = module.GetFileSpec();
84
85 if (module_spec) {
86 SymbolVendor *symbols = module.GetSymbolVendor();
87 if (symbols) {
88 SymbolFile *symfile = symbols->GetSymbolFile();
89 if (symfile) {
90 ObjectFile *objfile = symfile->GetObjectFile();
91 if (objfile) {
92 FileSpec symfile_spec(objfile->GetFileSpec());
93 if (symfile_spec && symfile_spec.Exists()) {
94 while (module_spec.GetFilename()) {
95 std::string module_basename(
96 module_spec.GetFilename().GetCString());
97 std::string original_module_basename(module_basename);
98
99 bool was_keyword = false;
100
101 // FIXME: for Python, we cannot allow certain characters in
102 // module
103 // filenames we import. Theoretically, different scripting
104 // languages may
105 // have different sets of forbidden tokens in filenames, and
106 // that should
107 // be dealt with by each ScriptInterpreter. For now, we just
108 // replace dots
109 // with underscores, but if we ever support anything other than
110 // Python
111 // we will need to rework this
112 std::replace(module_basename.begin(), module_basename.end(),
113 '.', '_');
114 std::replace(module_basename.begin(), module_basename.end(),
115 ' ', '_');
116 std::replace(module_basename.begin(), module_basename.end(),
117 '-', '_');
118 if (script_interpreter &&
119 script_interpreter->IsReservedWord(
120 module_basename.c_str())) {
121 module_basename.insert(module_basename.begin(), '_');
122 was_keyword = true;
123 }
124
125 StreamString path_string;
126 StreamString original_path_string;
127 // for OSX we are going to be in
128 // .dSYM/Contents/Resources/DWARF/<basename>
129 // let us go to .dSYM/Contents/Resources/Python/<basename>.py
130 // and see if the file exists
131 path_string.Printf("%s/../Python/%s.py",
132 symfile_spec.GetDirectory().GetCString(),
133 module_basename.c_str());
134 original_path_string.Printf(
135 "%s/../Python/%s.py",
136 symfile_spec.GetDirectory().GetCString(),
137 original_module_basename.c_str());
138 FileSpec script_fspec(path_string.GetString(), true);
139 FileSpec orig_script_fspec(original_path_string.GetString(),
140 true);
141
142 // if we did some replacements of reserved characters, and a
143 // file with the untampered name
144 // exists, then warn the user that the file as-is shall not be
145 // loaded
146 if (feedback_stream) {
147 if (module_basename != original_module_basename &&
148 orig_script_fspec.Exists()) {
149 const char *reason_for_complaint =
150 was_keyword ? "conflicts with a keyword"
151 : "contains reserved characters";
152 if (script_fspec.Exists())
153 feedback_stream->Printf(
154 "warning: the symbol file '%s' contains a debug "
155 "script. However, its name"
156 " '%s' %s and as such cannot be loaded. LLDB will"
157 " load '%s' instead. Consider removing the file with "
158 "the malformed name to"
159 " eliminate this warning.\n",
160 symfile_spec.GetPath().c_str(),
161 original_path_string.GetData(), reason_for_complaint,
162 path_string.GetData());
163 else
164 feedback_stream->Printf(
165 "warning: the symbol file '%s' contains a debug "
166 "script. However, its name"
167 " %s and as such cannot be loaded. If you intend"
168 " to have this script loaded, please rename '%s' to "
169 "'%s' and retry.\n",
170 symfile_spec.GetPath().c_str(), reason_for_complaint,
171 original_path_string.GetData(),
172 path_string.GetData());
173 }
174 }
175
176 if (script_fspec.Exists()) {
177 file_list.Append(script_fspec);
178 break;
179 }
180
181 // If we didn't find the python file, then keep
182 // stripping the extensions and try again
183 ConstString filename_no_extension(
184 module_spec.GetFileNameStrippingExtension());
185 if (module_spec.GetFilename() == filename_no_extension)
186 break;
187
188 module_spec.GetFilename() = filename_no_extension;
189 }
190 }
191 }
192 }
193 }
194 }
195 }
196 return file_list;
197}
198
199Status PlatformDarwin::ResolveSymbolFile(Target &target,
200 const ModuleSpec &sym_spec,
201 FileSpec &sym_file) {
202 Status error;
203 sym_file = sym_spec.GetSymbolFileSpec();
204
205 llvm::sys::fs::file_status st;
206 if (status(sym_file.GetPath(), st, false)) {
207 error.SetErrorString("Could not stat file!");
208 return error;
209 }
210
211 if (exists(st)) {
212 if (is_directory(st)) {
213 sym_file = Symbols::FindSymbolFileInBundle(
214 sym_file, sym_spec.GetUUIDPtr(), sym_spec.GetArchitecturePtr());
215 }
216 } else {
217 if (sym_spec.GetUUID().IsValid()) {
218 }
219 }
220 return error;
221}
222
223static lldb_private::Status
224MakeCacheFolderForFile(const FileSpec &module_cache_spec) {
225 FileSpec module_cache_folder =
226 module_cache_spec.CopyByRemovingLastPathComponent();
227 return llvm::sys::fs::create_directory(module_cache_folder.GetPath());
228}
229
230static lldb_private::Status
231BringInRemoteFile(Platform *platform,
232 const lldb_private::ModuleSpec &module_spec,
233 const FileSpec &module_cache_spec) {
234 MakeCacheFolderForFile(module_cache_spec);
235 Status err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
236 return err;
237}
238
239lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
240 const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
241 const lldb_private::FileSpecList *module_search_paths_ptr,
242 lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
243
244 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM(1u << 25)));
245 if (log)
246 log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol "
247 "path %s/%s",
248 (IsHost() ? "host" : "remote"),
249 module_spec.GetFileSpec().GetDirectory().AsCString(),
250 module_spec.GetFileSpec().GetFilename().AsCString(),
251 module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
252 module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
253 module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
254 module_spec.GetSymbolFileSpec().GetFilename().AsCString());
255
256 Status err;
257
258 err = ModuleList::GetSharedModule(module_spec, module_sp,
259 module_search_paths_ptr, old_module_sp_ptr,
260 did_create_ptr);
261 if (module_sp)
262 return err;
263
264 if (!IsHost()) {
265 std::string cache_path(GetLocalCacheDirectory());
266 // Only search for a locally cached file if we have a valid cache path
267 if (!cache_path.empty()) {
268 std::string module_path(module_spec.GetFileSpec().GetPath());
269 cache_path.append(module_path);
270 FileSpec module_cache_spec(cache_path, false);
271
272 // if rsync is supported, always bring in the file - rsync will be very
273 // efficient
274 // when files are the same on the local and remote end of the connection
275 if (this->GetSupportsRSync()) {
276 err = BringInRemoteFile(this, module_spec, module_cache_spec);
277 if (err.Fail())
278 return err;
279 if (module_cache_spec.Exists()) {
280 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM(1u << 25)));
281 if (log)
282 log->Printf("[%s] module %s/%s was rsynced and is now there",
283 (IsHost() ? "host" : "remote"),
284 module_spec.GetFileSpec().GetDirectory().AsCString(),
285 module_spec.GetFileSpec().GetFilename().AsCString());
286 ModuleSpec local_spec(module_cache_spec,
287 module_spec.GetArchitecture());
288 module_sp.reset(new Module(local_spec));
289 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
290 return Status();
291 }
292 }
293
294 // try to find the module in the cache
295 if (module_cache_spec.Exists()) {
296 // get the local and remote MD5 and compare
297 if (m_remote_platform_sp) {
298 // when going over the *slow* GDB remote transfer mechanism we first
299 // check the hashes of the files - and only do the actual transfer if
300 // they differ
301 uint64_t high_local, high_remote, low_local, low_remote;
302 auto MD5 = llvm::sys::fs::md5_contents(module_cache_spec.GetPath());
303 if (!MD5)
304 return Status(MD5.getError());
305 std::tie(high_local, low_local) = MD5->words();
306
307 m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(),
308 low_remote, high_remote);
309 if (low_local != low_remote || high_local != high_remote) {
310 // bring in the remote file
311 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM(1u << 25)));
312 if (log)
313 log->Printf(
314 "[%s] module %s/%s needs to be replaced from remote copy",
315 (IsHost() ? "host" : "remote"),
316 module_spec.GetFileSpec().GetDirectory().AsCString(),
317 module_spec.GetFileSpec().GetFilename().AsCString());
318 Status err =
319 BringInRemoteFile(this, module_spec, module_cache_spec);
320 if (err.Fail())
321 return err;
322 }
323 }
324
325 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
326 module_sp.reset(new Module(local_spec));
327 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
328 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM(1u << 25)));
329 if (log)
330 log->Printf("[%s] module %s/%s was found in the cache",
331 (IsHost() ? "host" : "remote"),
332 module_spec.GetFileSpec().GetDirectory().AsCString(),
333 module_spec.GetFileSpec().GetFilename().AsCString());
334 return Status();
335 }
336
337 // bring in the remote module file
338 if (log)
339 log->Printf("[%s] module %s/%s needs to come in remotely",
340 (IsHost() ? "host" : "remote"),
341 module_spec.GetFileSpec().GetDirectory().AsCString(),
342 module_spec.GetFileSpec().GetFilename().AsCString());
343 Status err = BringInRemoteFile(this, module_spec, module_cache_spec);
344 if (err.Fail())
345 return err;
346 if (module_cache_spec.Exists()) {
347 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM(1u << 25)));
348 if (log)
349 log->Printf("[%s] module %s/%s is now cached and fine",
350 (IsHost() ? "host" : "remote"),
351 module_spec.GetFileSpec().GetDirectory().AsCString(),
352 module_spec.GetFileSpec().GetFilename().AsCString());
353 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
354 module_sp.reset(new Module(local_spec));
355 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
356 return Status();
357 } else
358 return Status("unable to obtain valid module file");
359 } else
360 return Status("no cache path");
361 } else
362 return Status("unable to resolve module");
363}
364
365Status PlatformDarwin::GetSharedModule(
366 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
367 const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
368 bool *did_create_ptr) {
369 Status error;
370 module_sp.reset();
371
372 if (IsRemote()) {
373 // If we have a remote platform always, let it try and locate
374 // the shared module first.
375 if (m_remote_platform_sp) {
376 error = m_remote_platform_sp->GetSharedModule(
377 module_spec, process, module_sp, module_search_paths_ptr,
378 old_module_sp_ptr, did_create_ptr);
379 }
380 }
381
382 if (!module_sp) {
383 // Fall back to the local platform and find the file locally
384 error = Platform::GetSharedModule(module_spec, process, module_sp,
385 module_search_paths_ptr,
386 old_module_sp_ptr, did_create_ptr);
387
388 const FileSpec &platform_file = module_spec.GetFileSpec();
389 if (!module_sp && module_search_paths_ptr && platform_file) {
390 // We can try to pull off part of the file path up to the bundle
391 // directory level and try any module search paths...
392 FileSpec bundle_directory;
393 if (Host::GetBundleDirectory(platform_file, bundle_directory)) {
394 if (platform_file == bundle_directory) {
395 ModuleSpec new_module_spec(module_spec);
396 new_module_spec.GetFileSpec() = bundle_directory;
397 if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) {
398 Status new_error(Platform::GetSharedModule(
399 new_module_spec, process, module_sp, NULL__null, old_module_sp_ptr,
400 did_create_ptr));
401
402 if (module_sp)
403 return new_error;
404 }
405 } else {
406 char platform_path[PATH_MAX4096];
407 char bundle_dir[PATH_MAX4096];
408 platform_file.GetPath(platform_path, sizeof(platform_path));
409 const size_t bundle_directory_len =
410 bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir));
411 char new_path[PATH_MAX4096];
412 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
413 for (size_t i = 0; i < num_module_search_paths; ++i) {
414 const size_t search_path_len =
415 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(
416 new_path, sizeof(new_path));
417 if (search_path_len < sizeof(new_path)) {
418 snprintf(new_path + search_path_len,
419 sizeof(new_path) - search_path_len, "/%s",
420 platform_path + bundle_directory_len);
421 FileSpec new_file_spec(new_path, false);
422 if (new_file_spec.Exists()) {
423 ModuleSpec new_module_spec(module_spec);
424 new_module_spec.GetFileSpec() = new_file_spec;
425 Status new_error(Platform::GetSharedModule(
426 new_module_spec, process, module_sp, NULL__null,
427 old_module_sp_ptr, did_create_ptr));
428
429 if (module_sp) {
430 module_sp->SetPlatformFileSpec(new_file_spec);
431 return new_error;
432 }
433 }
434 }
435 }
436 }
437 }
438 }
439 }
440 if (module_sp)
441 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
442 return error;
443}
444
445size_t
446PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,
447 BreakpointSite *bp_site) {
448 const uint8_t *trap_opcode = nullptr;
449 uint32_t trap_opcode_size = 0;
450 bool bp_is_thumb = false;
451
452 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
453 switch (machine) {
454 case llvm::Triple::aarch64: {
455 // TODO: fix this with actual darwin breakpoint opcode for arm64.
456 // right now debugging uses the Z packets with GDB remote so this
457 // is not needed, but the size needs to be correct...
458 static const uint8_t g_arm64_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
459 trap_opcode = g_arm64_breakpoint_opcode;
460 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
461 } break;
462
463 case llvm::Triple::thumb:
464 bp_is_thumb = true;
465 LLVM_FALLTHROUGH[[clang::fallthrough]];
466 case llvm::Triple::arm: {
467 static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
468 static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE};
469
470 // Auto detect arm/thumb if it wasn't explicitly specified
471 if (!bp_is_thumb) {
472 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
473 if (bp_loc_sp)
474 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
475 eAddressClassCodeAlternateISA;
476 }
477 if (bp_is_thumb) {
478 trap_opcode = g_thumb_breakpooint_opcode;
479 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
480 break;
481 }
482 trap_opcode = g_arm_breakpoint_opcode;
483 trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
484 } break;
485
486 case llvm::Triple::ppc:
487 case llvm::Triple::ppc64: {
488 static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
489 trap_opcode = g_ppc_breakpoint_opcode;
490 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
491 } break;
492
493 default:
494 return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
495 }
496
497 if (trap_opcode && trap_opcode_size) {
498 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
499 return trap_opcode_size;
500 }
501 return 0;
502}
503
504bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches(
505 lldb_private::Target &target, const lldb::ModuleSP &module_sp) {
506 if (!module_sp)
507 return false;
508
509 ObjectFile *obj_file = module_sp->GetObjectFile();
510 if (!obj_file)
511 return false;
512
513 ObjectFile::Type obj_type = obj_file->GetType();
514 if (obj_type == ObjectFile::eTypeDynamicLinker)
515 return true;
516 else
517 return false;
518}
519
520bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx,
521 ArchSpec &arch) {
522 ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
523 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) {
524 switch (idx) {
525 case 0:
526 arch = host_arch;
527 return true;
528
529 case 1:
530 arch.SetTriple("x86_64-apple-macosx");
531 return true;
532
533 case 2:
534 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
535 return true;
536
537 default:
538 return false;
539 }
540 } else {
541 if (idx == 0) {
542 arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
543 return arch.IsValid();
544 } else if (idx == 1) {
545 ArchSpec platform_arch(
546 HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
547 ArchSpec platform_arch64(
548 HostInfo::GetArchitecture(HostInfo::eArchKind64));
549 if (platform_arch.IsExactMatch(platform_arch64)) {
550 // This macosx platform supports both 32 and 64 bit. Since we already
551 // returned the 64 bit arch for idx == 0, return the 32 bit arch
552 // for idx == 1
553 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
554 return arch.IsValid();
555 }
556 }
557 }
558 return false;
559}
560
561// The architecture selection rules for arm processors
562// These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run
563// fine on an armv7f processor.
564
565bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx,
566 ArchSpec &arch) {
567 ArchSpec system_arch(GetSystemArchitecture());
568
569// When lldb is running on a watch or tv, set the arch OS name appropriately.
570#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
571#define OSNAME"ios" "tvos"
572#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
573#define OSNAME"ios" "watchos"
574#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
575#define OSNAME"ios" "bridgeos"
576#else
577#define OSNAME"ios" "ios"
578#endif
579
580 const ArchSpec::Core system_core = system_arch.GetCore();
581 switch (system_core) {
582 default:
583 switch (idx) {
584 case 0:
585 arch.SetTriple("arm64-apple-" OSNAME"ios");
586 return true;
587 case 1:
588 arch.SetTriple("armv7-apple-" OSNAME"ios");
589 return true;
590 case 2:
591 arch.SetTriple("armv7f-apple-" OSNAME"ios");
592 return true;
593 case 3:
594 arch.SetTriple("armv7k-apple-" OSNAME"ios");
595 return true;
596 case 4:
597 arch.SetTriple("armv7s-apple-" OSNAME"ios");
598 return true;
599 case 5:
600 arch.SetTriple("armv7m-apple-" OSNAME"ios");
601 return true;
602 case 6:
603 arch.SetTriple("armv7em-apple-" OSNAME"ios");
604 return true;
605 case 7:
606 arch.SetTriple("armv6m-apple-" OSNAME"ios");
607 return true;
608 case 8:
609 arch.SetTriple("armv6-apple-" OSNAME"ios");
610 return true;
611 case 9:
612 arch.SetTriple("armv5-apple-" OSNAME"ios");
613 return true;
614 case 10:
615 arch.SetTriple("armv4-apple-" OSNAME"ios");
616 return true;
617 case 11:
618 arch.SetTriple("arm-apple-" OSNAME"ios");
619 return true;
620 case 12:
621 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
622 return true;
623 case 13:
624 arch.SetTriple("thumbv7f-apple-" OSNAME"ios");
625 return true;
626 case 14:
627 arch.SetTriple("thumbv7k-apple-" OSNAME"ios");
628 return true;
629 case 15:
630 arch.SetTriple("thumbv7s-apple-" OSNAME"ios");
631 return true;
632 case 16:
633 arch.SetTriple("thumbv7m-apple-" OSNAME"ios");
634 return true;
635 case 17:
636 arch.SetTriple("thumbv7em-apple-" OSNAME"ios");
637 return true;
638 case 18:
639 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
640 return true;
641 case 19:
642 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
643 return true;
644 case 20:
645 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
646 return true;
647 case 21:
648 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
649 return true;
650 case 22:
651 arch.SetTriple("thumb-apple-" OSNAME"ios");
652 return true;
653 default:
654 break;
655 }
656 break;
657
658 case ArchSpec::eCore_arm_arm64:
659 switch (idx) {
660 case 0:
661 arch.SetTriple("arm64-apple-" OSNAME"ios");
662 return true;
663 case 1:
664 arch.SetTriple("armv7s-apple-" OSNAME"ios");
665 return true;
666 case 2:
667 arch.SetTriple("armv7f-apple-" OSNAME"ios");
668 return true;
669 case 3:
670 arch.SetTriple("armv7m-apple-" OSNAME"ios");
671 return true;
672 case 4:
673 arch.SetTriple("armv7em-apple-" OSNAME"ios");
674 return true;
675 case 5:
676 arch.SetTriple("armv7-apple-" OSNAME"ios");
677 return true;
678 case 6:
679 arch.SetTriple("armv6m-apple-" OSNAME"ios");
680 return true;
681 case 7:
682 arch.SetTriple("armv6-apple-" OSNAME"ios");
683 return true;
684 case 8:
685 arch.SetTriple("armv5-apple-" OSNAME"ios");
686 return true;
687 case 9:
688 arch.SetTriple("armv4-apple-" OSNAME"ios");
689 return true;
690 case 10:
691 arch.SetTriple("arm-apple-" OSNAME"ios");
692 return true;
693 case 11:
694 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
695 return true;
696 case 12:
697 arch.SetTriple("thumbv7f-apple-" OSNAME"ios");
698 return true;
699 case 13:
700 arch.SetTriple("thumbv7k-apple-" OSNAME"ios");
701 return true;
702 case 14:
703 arch.SetTriple("thumbv7s-apple-" OSNAME"ios");
704 return true;
705 case 15:
706 arch.SetTriple("thumbv7m-apple-" OSNAME"ios");
707 return true;
708 case 16:
709 arch.SetTriple("thumbv7em-apple-" OSNAME"ios");
710 return true;
711 case 17:
712 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
713 return true;
714 case 18:
715 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
716 return true;
717 case 19:
718 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
719 return true;
720 case 20:
721 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
722 return true;
723 case 21:
724 arch.SetTriple("thumb-apple-" OSNAME"ios");
725 return true;
726 default:
727 break;
728 }
729 break;
730
731 case ArchSpec::eCore_arm_armv7f:
732 switch (idx) {
733 case 0:
734 arch.SetTriple("armv7f-apple-" OSNAME"ios");
735 return true;
736 case 1:
737 arch.SetTriple("armv7-apple-" OSNAME"ios");
738 return true;
739 case 2:
740 arch.SetTriple("armv6m-apple-" OSNAME"ios");
741 return true;
742 case 3:
743 arch.SetTriple("armv6-apple-" OSNAME"ios");
744 return true;
745 case 4:
746 arch.SetTriple("armv5-apple-" OSNAME"ios");
747 return true;
748 case 5:
749 arch.SetTriple("armv4-apple-" OSNAME"ios");
750 return true;
751 case 6:
752 arch.SetTriple("arm-apple-" OSNAME"ios");
753 return true;
754 case 7:
755 arch.SetTriple("thumbv7f-apple-" OSNAME"ios");
756 return true;
757 case 8:
758 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
759 return true;
760 case 9:
761 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
762 return true;
763 case 10:
764 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
765 return true;
766 case 11:
767 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
768 return true;
769 case 12:
770 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
771 return true;
772 case 13:
773 arch.SetTriple("thumb-apple-" OSNAME"ios");
774 return true;
775 default:
776 break;
777 }
778 break;
779
780 case ArchSpec::eCore_arm_armv7k:
781 switch (idx) {
782 case 0:
783 arch.SetTriple("armv7k-apple-" OSNAME"ios");
784 return true;
785 case 1:
786 arch.SetTriple("armv7-apple-" OSNAME"ios");
787 return true;
788 case 2:
789 arch.SetTriple("armv6m-apple-" OSNAME"ios");
790 return true;
791 case 3:
792 arch.SetTriple("armv6-apple-" OSNAME"ios");
793 return true;
794 case 4:
795 arch.SetTriple("armv5-apple-" OSNAME"ios");
796 return true;
797 case 5:
798 arch.SetTriple("armv4-apple-" OSNAME"ios");
799 return true;
800 case 6:
801 arch.SetTriple("arm-apple-" OSNAME"ios");
802 return true;
803 case 7:
804 arch.SetTriple("thumbv7k-apple-" OSNAME"ios");
805 return true;
806 case 8:
807 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
808 return true;
809 case 9:
810 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
811 return true;
812 case 10:
813 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
814 return true;
815 case 11:
816 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
817 return true;
818 case 12:
819 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
820 return true;
821 case 13:
822 arch.SetTriple("thumb-apple-" OSNAME"ios");
823 return true;
824 default:
825 break;
826 }
827 break;
828
829 case ArchSpec::eCore_arm_armv7s:
830 switch (idx) {
831 case 0:
832 arch.SetTriple("armv7s-apple-" OSNAME"ios");
833 return true;
834 case 1:
835 arch.SetTriple("armv7-apple-" OSNAME"ios");
836 return true;
837 case 2:
838 arch.SetTriple("armv6m-apple-" OSNAME"ios");
839 return true;
840 case 3:
841 arch.SetTriple("armv6-apple-" OSNAME"ios");
842 return true;
843 case 4:
844 arch.SetTriple("armv5-apple-" OSNAME"ios");
845 return true;
846 case 5:
847 arch.SetTriple("armv4-apple-" OSNAME"ios");
848 return true;
849 case 6:
850 arch.SetTriple("arm-apple-" OSNAME"ios");
851 return true;
852 case 7:
853 arch.SetTriple("thumbv7s-apple-" OSNAME"ios");
854 return true;
855 case 8:
856 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
857 return true;
858 case 9:
859 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
860 return true;
861 case 10:
862 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
863 return true;
864 case 11:
865 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
866 return true;
867 case 12:
868 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
869 return true;
870 case 13:
871 arch.SetTriple("thumb-apple-" OSNAME"ios");
872 return true;
873 default:
874 break;
875 }
876 break;
877
878 case ArchSpec::eCore_arm_armv7m:
879 switch (idx) {
880 case 0:
881 arch.SetTriple("armv7m-apple-" OSNAME"ios");
882 return true;
883 case 1:
884 arch.SetTriple("armv7-apple-" OSNAME"ios");
885 return true;
886 case 2:
887 arch.SetTriple("armv6m-apple-" OSNAME"ios");
888 return true;
889 case 3:
890 arch.SetTriple("armv6-apple-" OSNAME"ios");
891 return true;
892 case 4:
893 arch.SetTriple("armv5-apple-" OSNAME"ios");
894 return true;
895 case 5:
896 arch.SetTriple("armv4-apple-" OSNAME"ios");
897 return true;
898 case 6:
899 arch.SetTriple("arm-apple-" OSNAME"ios");
900 return true;
901 case 7:
902 arch.SetTriple("thumbv7m-apple-" OSNAME"ios");
903 return true;
904 case 8:
905 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
906 return true;
907 case 9:
908 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
909 return true;
910 case 10:
911 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
912 return true;
913 case 11:
914 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
915 return true;
916 case 12:
917 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
918 return true;
919 case 13:
920 arch.SetTriple("thumb-apple-" OSNAME"ios");
921 return true;
922 default:
923 break;
924 }
925 break;
926
927 case ArchSpec::eCore_arm_armv7em:
928 switch (idx) {
929 case 0:
930 arch.SetTriple("armv7em-apple-" OSNAME"ios");
931 return true;
932 case 1:
933 arch.SetTriple("armv7-apple-" OSNAME"ios");
934 return true;
935 case 2:
936 arch.SetTriple("armv6m-apple-" OSNAME"ios");
937 return true;
938 case 3:
939 arch.SetTriple("armv6-apple-" OSNAME"ios");
940 return true;
941 case 4:
942 arch.SetTriple("armv5-apple-" OSNAME"ios");
943 return true;
944 case 5:
945 arch.SetTriple("armv4-apple-" OSNAME"ios");
946 return true;
947 case 6:
948 arch.SetTriple("arm-apple-" OSNAME"ios");
949 return true;
950 case 7:
951 arch.SetTriple("thumbv7em-apple-" OSNAME"ios");
952 return true;
953 case 8:
954 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
955 return true;
956 case 9:
957 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
958 return true;
959 case 10:
960 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
961 return true;
962 case 11:
963 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
964 return true;
965 case 12:
966 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
967 return true;
968 case 13:
969 arch.SetTriple("thumb-apple-" OSNAME"ios");
970 return true;
971 default:
972 break;
973 }
974 break;
975
976 case ArchSpec::eCore_arm_armv7:
977 switch (idx) {
978 case 0:
979 arch.SetTriple("armv7-apple-" OSNAME"ios");
980 return true;
981 case 1:
982 arch.SetTriple("armv6m-apple-" OSNAME"ios");
983 return true;
984 case 2:
985 arch.SetTriple("armv6-apple-" OSNAME"ios");
986 return true;
987 case 3:
988 arch.SetTriple("armv5-apple-" OSNAME"ios");
989 return true;
990 case 4:
991 arch.SetTriple("armv4-apple-" OSNAME"ios");
992 return true;
993 case 5:
994 arch.SetTriple("arm-apple-" OSNAME"ios");
995 return true;
996 case 6:
997 arch.SetTriple("thumbv7-apple-" OSNAME"ios");
998 return true;
999 case 7:
1000 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
1001 return true;
1002 case 8:
1003 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
1004 return true;
1005 case 9:
1006 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
1007 return true;
1008 case 10:
1009 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
1010 return true;
1011 case 11:
1012 arch.SetTriple("thumb-apple-" OSNAME"ios");
1013 return true;
1014 default:
1015 break;
1016 }
1017 break;
1018
1019 case ArchSpec::eCore_arm_armv6m:
1020 switch (idx) {
1021 case 0:
1022 arch.SetTriple("armv6m-apple-" OSNAME"ios");
1023 return true;
1024 case 1:
1025 arch.SetTriple("armv6-apple-" OSNAME"ios");
1026 return true;
1027 case 2:
1028 arch.SetTriple("armv5-apple-" OSNAME"ios");
1029 return true;
1030 case 3:
1031 arch.SetTriple("armv4-apple-" OSNAME"ios");
1032 return true;
1033 case 4:
1034 arch.SetTriple("arm-apple-" OSNAME"ios");
1035 return true;
1036 case 5:
1037 arch.SetTriple("thumbv6m-apple-" OSNAME"ios");
1038 return true;
1039 case 6:
1040 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
1041 return true;
1042 case 7:
1043 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
1044 return true;
1045 case 8:
1046 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
1047 return true;
1048 case 9:
1049 arch.SetTriple("thumb-apple-" OSNAME"ios");
1050 return true;
1051 default:
1052 break;
1053 }
1054 break;
1055
1056 case ArchSpec::eCore_arm_armv6:
1057 switch (idx) {
1058 case 0:
1059 arch.SetTriple("armv6-apple-" OSNAME"ios");
1060 return true;
1061 case 1:
1062 arch.SetTriple("armv5-apple-" OSNAME"ios");
1063 return true;
1064 case 2:
1065 arch.SetTriple("armv4-apple-" OSNAME"ios");
1066 return true;
1067 case 3:
1068 arch.SetTriple("arm-apple-" OSNAME"ios");
1069 return true;
1070 case 4:
1071 arch.SetTriple("thumbv6-apple-" OSNAME"ios");
1072 return true;
1073 case 5:
1074 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
1075 return true;
1076 case 6:
1077 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
1078 return true;
1079 case 7:
1080 arch.SetTriple("thumb-apple-" OSNAME"ios");
1081 return true;
1082 default:
1083 break;
1084 }
1085 break;
1086
1087 case ArchSpec::eCore_arm_armv5:
1088 switch (idx) {
1089 case 0:
1090 arch.SetTriple("armv5-apple-" OSNAME"ios");
1091 return true;
1092 case 1:
1093 arch.SetTriple("armv4-apple-" OSNAME"ios");
1094 return true;
1095 case 2:
1096 arch.SetTriple("arm-apple-" OSNAME"ios");
1097 return true;
1098 case 3:
1099 arch.SetTriple("thumbv5-apple-" OSNAME"ios");
1100 return true;
1101 case 4:
1102 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
1103 return true;
1104 case 5:
1105 arch.SetTriple("thumb-apple-" OSNAME"ios");
1106 return true;
1107 default:
1108 break;
1109 }
1110 break;
1111
1112 case ArchSpec::eCore_arm_armv4:
1113 switch (idx) {
1114 case 0:
1115 arch.SetTriple("armv4-apple-" OSNAME"ios");
1116 return true;
1117 case 1:
1118 arch.SetTriple("arm-apple-" OSNAME"ios");
1119 return true;
1120 case 2:
1121 arch.SetTriple("thumbv4t-apple-" OSNAME"ios");
1122 return true;
1123 case 3:
1124 arch.SetTriple("thumb-apple-" OSNAME"ios");
1125 return true;
1126 default:
1127 break;
1128 }
1129 break;
1130 }
1131 arch.Clear();
1132 return false;
1133}
1134
1135// Return a directory path like /Applications/Xcode.app/Contents/Developer
1136const char *PlatformDarwin::GetDeveloperDirectory() {
1137 std::lock_guard<std::mutex> guard(m_mutex);
1138 if (m_developer_directory.empty()) {
1139 bool developer_dir_path_valid = false;
1140 char developer_dir_path[PATH_MAX4096];
1141 FileSpec temp_file_spec;
1142
1143 // Get the lldb framework's file path, and if it exists, truncate some
1144 // components to only the developer directory path.
1145 if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec)) {
1146 if (temp_file_spec.GetPath(developer_dir_path,
1147 sizeof(developer_dir_path))) {
1148 // e.g. /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework
1149 char *shared_frameworks =
1150 strstr(developer_dir_path, "/SharedFrameworks/LLDB.framework");
1151 if (shared_frameworks) {
1152 shared_frameworks[0] = '\0'; // truncate developer_dir_path at this point
1153 strncat (developer_dir_path, "/Developer", sizeof (developer_dir_path) - 1); // add /Developer on
Potential buffer overflow. Replace with 'sizeof(developer_dir_path) - strlen(developer_dir_path) - 1' or use a safer 'strlcat' API
1154 developer_dir_path_valid = true;
1155 } else {
1156 // e.g. /Applications/Xcode.app/Contents/Developer/Toolchains/iOS11.2.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework
1157 char *developer_toolchains =
1158 strstr(developer_dir_path, "/Contents/Developer/Toolchains/");
1159 if (developer_toolchains) {
1160 developer_toolchains += sizeof ("/Contents/Developer") - 1;
1161 developer_toolchains[0] = '\0'; // truncate developer_dir_path at this point
1162 developer_dir_path_valid = true;
1163 }
1164 }
1165 }
1166 }
1167
1168 if (!developer_dir_path_valid) {
1169 std::string xcode_dir_path;
1170 const char *xcode_select_prefix_dir = getenv("XCODE_SELECT_PREFIX_DIR");
1171 if (xcode_select_prefix_dir)
1172 xcode_dir_path.append(xcode_select_prefix_dir);
1173 xcode_dir_path.append("/usr/share/xcode-select/xcode_dir_path");
1174 temp_file_spec.SetFile(xcode_dir_path, false);
1175 auto dir_buffer =
1176 DataBufferLLVM::CreateFromPath(temp_file_spec.GetPath());
1177 if (dir_buffer && dir_buffer->GetByteSize() > 0) {
1178 llvm::StringRef path_ref(dir_buffer->GetChars());
1179 // Trim tailing newlines and make sure there is enough room for a null
1180 // terminator.
1181 path_ref =
1182 path_ref.rtrim("\r\n").take_front(sizeof(developer_dir_path) - 1);
1183 ::memcpy(developer_dir_path, path_ref.data(), path_ref.size());
1184 developer_dir_path[path_ref.size()] = '\0';
1185 developer_dir_path_valid = true;
1186 }
1187 }
1188
1189 if (!developer_dir_path_valid) {
1190 FileSpec xcode_select_cmd("/usr/bin/xcode-select", false);
1191 if (xcode_select_cmd.Exists()) {
1192 int exit_status = -1;
1193 int signo = -1;
1194 std::string command_output;
1195 Status error =
1196 Host::RunShellCommand("/usr/bin/xcode-select --print-path",
1197 NULL__null, // current working directory
1198 &exit_status, &signo, &command_output,
1199 2, // short timeout
1200 false); // don't run in a shell
1201 if (error.Success() && exit_status == 0 && !command_output.empty()) {
1202 const char *cmd_output_ptr = command_output.c_str();
1203 developer_dir_path[sizeof(developer_dir_path) - 1] = '\0';
1204 size_t i;
1205 for (i = 0; i < sizeof(developer_dir_path) - 1; i++) {
1206 if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' ||
1207 cmd_output_ptr[i] == '\0')
1208 break;
1209 developer_dir_path[i] = cmd_output_ptr[i];
1210 }
1211 developer_dir_path[i] = '\0';
1212
1213 FileSpec devel_dir(developer_dir_path, false);
1214 if (llvm::sys::fs::is_directory(devel_dir.GetPath())) {
1215 developer_dir_path_valid = true;
1216 }
1217 }
1218 }
1219 }
1220
1221 if (developer_dir_path_valid) {
1222 temp_file_spec.SetFile(developer_dir_path, false);
1223 if (temp_file_spec.Exists()) {
1224 m_developer_directory.assign(developer_dir_path);
1225 return m_developer_directory.c_str();
1226 }
1227 }
1228 // Assign a single NULL character so we know we tried to find the device
1229 // support directory and we don't keep trying to find it over and over.
1230 m_developer_directory.assign(1, '\0');
1231 }
1232
1233 // We should have put a single NULL character into m_developer_directory
1234 // or it should have a valid path if the code gets here
1235 assert(m_developer_directory.empty() == false)(static_cast <bool> (m_developer_directory.empty() == false
) ? void (0) : __assert_fail ("m_developer_directory.empty() == false"
, "/build/llvm-toolchain-snapshot-6.0~svn321639/tools/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp"
, 1235, __extension__ __PRETTY_FUNCTION__))
;
1236 if (m_developer_directory[0])
1237 return m_developer_directory.c_str();
1238 return NULL__null;
1239}
1240
1241BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) {
1242 BreakpointSP bp_sp;
1243 static const char *g_bp_names[] = {
1244 "start_wqthread", "_pthread_wqthread", "_pthread_start",
1245 };
1246
1247 static const char *g_bp_modules[] = {"libsystem_c.dylib",
1248 "libSystem.B.dylib"};
1249
1250 FileSpecList bp_modules;
1251 for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++) {
1252 const char *bp_module = g_bp_modules[i];
1253 bp_modules.Append(FileSpec(bp_module, false));
1254 }
1255
1256 bool internal = true;
1257 bool hardware = false;
1258 LazyBool skip_prologue = eLazyBoolNo;
1259 bp_sp = target.CreateBreakpoint(&bp_modules, NULL__null, g_bp_names,
1260 llvm::array_lengthof(g_bp_names),
1261 eFunctionNameTypeFull, eLanguageTypeUnknown,
1262 0, skip_prologue, internal, hardware);
1263 bp_sp->SetBreakpointKind("thread-creation");
1264
1265 return bp_sp;
1266}
1267
1268int32_t
1269PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
1270 const FileSpec &shell = launch_info.GetShell();
1271 if (!shell)
1272 return 1;
1273
1274 std::string shell_string = shell.GetPath();
1275 const char *shell_name = strrchr(shell_string.c_str(), '/');
1276 if (shell_name == NULL__null)
1277 shell_name = shell_string.c_str();
1278 else
1279 shell_name++;
1280
1281 if (strcmp(shell_name, "sh") == 0) {
1282 // /bin/sh re-exec's itself as /bin/bash requiring another resume.
1283 // But it only does this if the COMMAND_MODE environment variable
1284 // is set to "legacy".
1285 const char **envp =
1286 launch_info.GetEnvironmentEntries().GetConstArgumentVector();
1287 if (envp != NULL__null) {
1288 for (int i = 0; envp[i] != NULL__null; i++) {
1289 if (strcmp(envp[i], "COMMAND_MODE=legacy") == 0)
1290 return 2;
1291 }
1292 }
1293 return 1;
1294 } else if (strcmp(shell_name, "csh") == 0 ||
1295 strcmp(shell_name, "tcsh") == 0 ||
1296 strcmp(shell_name, "zsh") == 0) {
1297 // csh and tcsh always seem to re-exec themselves.
1298 return 2;
1299 } else
1300 return 1;
1301}
1302
1303void PlatformDarwin::CalculateTrapHandlerSymbolNames() {
1304 m_trap_handlers.push_back(ConstString("_sigtramp"));
1305}
1306
1307static const char *const sdk_strings[] = {
1308 "MacOSX", "iPhoneSimulator", "iPhoneOS",
1309};
1310
1311static FileSpec CheckPathForXcode(const FileSpec &fspec) {
1312 if (fspec.Exists()) {
1313 const char substr[] = ".app/Contents/";
1314
1315 std::string path_to_shlib = fspec.GetPath();
1316 size_t pos = path_to_shlib.rfind(substr);
1317 if (pos != std::string::npos) {
1318 path_to_shlib.erase(pos + strlen(substr));
1319 FileSpec ret(path_to_shlib, false);
1320
1321 FileSpec xcode_binary_path = ret;
1322 xcode_binary_path.AppendPathComponent("MacOS");
1323 xcode_binary_path.AppendPathComponent("Xcode");
1324
1325 if (xcode_binary_path.Exists()) {
1326 return ret;
1327 }
1328 }
1329 }
1330 return FileSpec();
1331}
1332
1333static FileSpec GetXcodeContentsPath() {
1334 static FileSpec g_xcode_filespec;
1335 static llvm::once_flag g_once_flag;
1336 llvm::call_once(g_once_flag, []() {
1337
1338 FileSpec fspec;
1339
1340 // First get the program file spec. If lldb.so or LLDB.framework is running
1341 // in a program and that program is Xcode, the path returned with be the
1342 // path
1343 // to Xcode.app/Contents/MacOS/Xcode, so this will be the correct Xcode to
1344 // use.
1345 fspec = HostInfo::GetProgramFileSpec();
1346
1347 if (fspec) {
1348 // Ignore the current binary if it is python.
1349 std::string basename_lower = fspec.GetFilename().GetCString();
1350 std::transform(basename_lower.begin(), basename_lower.end(),
1351 basename_lower.begin(), tolower);
1352 if (basename_lower != "python") {
1353 g_xcode_filespec = CheckPathForXcode(fspec);
1354 }
1355 }
1356
1357 // Next check DEVELOPER_DIR environment variable
1358 if (!g_xcode_filespec) {
1359 const char *developer_dir_env_var = getenv("DEVELOPER_DIR");
1360 if (developer_dir_env_var && developer_dir_env_var[0]) {
1361 g_xcode_filespec =
1362 CheckPathForXcode(FileSpec(developer_dir_env_var, true));
1363 }
1364
1365 // Fall back to using "xcrun" to find the selected Xcode
1366 if (!g_xcode_filespec) {
1367 int status = 0;
1368 int signo = 0;
1369 std::string output;
1370 const char *command = "/usr/bin/xcode-select -p";
1371 lldb_private::Status error = Host::RunShellCommand(
1372 command, // shell command to run
1373 NULL__null, // current working directory
1374 &status, // Put the exit status of the process in here
1375 &signo, // Put the signal that caused the process to exit in here
1376 &output, // Get the output from the command and place it in this
1377 // string
1378 3); // Timeout in seconds to wait for shell program to finish
1379 if (status == 0 && !output.empty()) {
1380 size_t first_non_newline = output.find_last_not_of("\r\n");
1381 if (first_non_newline != std::string::npos) {
1382 output.erase(first_non_newline + 1);
1383 }
1384 output.append("/..");
1385
1386 g_xcode_filespec = CheckPathForXcode(FileSpec(output, false));
1387 }
1388 }
1389 }
1390 });
1391
1392 return g_xcode_filespec;
1393}
1394
1395bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type, uint32_t major,
1396 uint32_t minor, uint32_t micro) {
1397 switch (sdk_type) {
1398 case SDKType::MacOSX:
1399 if (major > 10 || (major == 10 && minor >= 10))
1400 return true;
1401 break;
1402 case SDKType::iPhoneOS:
1403 case SDKType::iPhoneSimulator:
1404 if (major >= 8)
1405 return true;
1406 break;
1407 }
1408
1409 return false;
1410}
1411
1412bool PlatformDarwin::SDKSupportsModules(SDKType desired_type,
1413 const FileSpec &sdk_path) {
1414 ConstString last_path_component = sdk_path.GetLastPathComponent();
1415
1416 if (last_path_component) {
1417 const llvm::StringRef sdk_name = last_path_component.GetStringRef();
1418
1419 llvm::StringRef version_part;
1420
1421 if (sdk_name.startswith(sdk_strings[(int)desired_type])) {
1422 version_part =
1423 sdk_name.drop_front(strlen(sdk_strings[(int)desired_type]));
1424 } else {
1425 return false;
1426 }
1427
1428 const size_t major_dot_offset = version_part.find('.');
1429 if (major_dot_offset == llvm::StringRef::npos)
1430 return false;
1431
1432 const llvm::StringRef major_version =
1433 version_part.slice(0, major_dot_offset);
1434 const llvm::StringRef minor_part =
1435 version_part.drop_front(major_dot_offset + 1);
1436
1437 const size_t minor_dot_offset = minor_part.find('.');
1438 if (minor_dot_offset == llvm::StringRef::npos)
1439 return false;
1440
1441 const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset);
1442
1443 unsigned int major = 0;
1444 unsigned int minor = 0;
1445 unsigned int micro = 0;
1446
1447 if (major_version.getAsInteger(10, major))
1448 return false;
1449
1450 if (minor_version.getAsInteger(10, minor))
1451 return false;
1452
1453 return SDKSupportsModules(desired_type, major, minor, micro);
1454 }
1455
1456 return false;
1457}
1458
1459FileSpec::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator(
1460 void *baton, llvm::sys::fs::file_type file_type, const FileSpec &spec) {
1461 SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);
1462
1463 if (SDKSupportsModules(enumerator_info->sdk_type, spec)) {
1464 enumerator_info->found_path = spec;
1465 return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
1466 }
1467
1468 return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
1469}
1470
1471FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type,
1472 const FileSpec &sdks_spec) {
1473 // Look inside Xcode for the required installed iOS SDK version
1474
1475 if (!llvm::sys::fs::is_directory(sdks_spec.GetPath())) {
1476 return FileSpec();
1477 }
1478
1479 const bool find_directories = true;
1480 const bool find_files = false;
1481 const bool find_other = true; // include symlinks
1482
1483 SDKEnumeratorInfo enumerator_info;
1484
1485 enumerator_info.sdk_type = sdk_type;
1486
1487 FileSpec::EnumerateDirectory(sdks_spec.GetPath(), find_directories,
1488 find_files, find_other, DirectoryEnumerator,
1489 &enumerator_info);
1490
1491 if (llvm::sys::fs::is_directory(enumerator_info.found_path.GetPath()))
1492 return enumerator_info.found_path;
1493 else
1494 return FileSpec();
1495}
1496
1497FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
1498 switch (sdk_type) {
1499 case SDKType::MacOSX:
1500 case SDKType::iPhoneSimulator:
1501 case SDKType::iPhoneOS:
1502 break;
1503 }
1504
1505 FileSpec sdks_spec = GetXcodeContentsPath();
1506 sdks_spec.AppendPathComponent("Developer");
1507 sdks_spec.AppendPathComponent("Platforms");
1508
1509 switch (sdk_type) {
1510 case SDKType::MacOSX:
1511 sdks_spec.AppendPathComponent("MacOSX.platform");
1512 break;
1513 case SDKType::iPhoneSimulator:
1514 sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
1515 break;
1516 case SDKType::iPhoneOS:
1517 sdks_spec.AppendPathComponent("iPhoneOS.platform");
1518 break;
1519 }
1520
1521 sdks_spec.AppendPathComponent("Developer");
1522 sdks_spec.AppendPathComponent("SDKs");
1523
1524 if (sdk_type == SDKType::MacOSX) {
1525 uint32_t major = 0;
1526 uint32_t minor = 0;
1527 uint32_t micro = 0;
1528
1529 if (HostInfo::GetOSVersion(major, minor, micro)) {
1530 if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro)) {
1531 // We slightly prefer the exact SDK for this machine. See if it is
1532 // there.
1533
1534 FileSpec native_sdk_spec = sdks_spec;
1535 StreamString native_sdk_name;
1536 native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor);
1537 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
1538
1539 if (native_sdk_spec.Exists()) {
1540 return native_sdk_spec;
1541 }
1542 }
1543 }
1544 }
1545
1546 return FindSDKInXcodeForModules(sdk_type, sdks_spec);
1547}
1548
1549std::tuple<uint32_t, uint32_t, uint32_t, llvm::StringRef>
1550PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
1551 uint32_t major, minor, update;
1552 llvm::StringRef build;
1553 llvm::StringRef version_str;
1554 llvm::StringRef build_str;
1555 std::tie(version_str, build_str) = dir.split(' ');
1556 if (Args::StringToVersion(version_str, major, minor, update) ||
1557 build_str.empty()) {
1558 if (build_str.consume_front("(")) {
1559 size_t pos = build_str.find(')');
1560 build = build_str.slice(0, pos);
1561 }
1562 }
1563
1564 return std::make_tuple(major, minor, update, build);
1565}
1566
1567void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
1568 Target *target, std::vector<std::string> &options, SDKType sdk_type) {
1569 const std::vector<std::string> apple_arguments = {
1570 "-x", "objective-c++", "-fobjc-arc",
1571 "-fblocks", "-D_ISO646_H", "-D__ISO646_H"};
1572
1573 options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
1574
1575 StreamString minimum_version_option;
1576 uint32_t versions[3] = {0, 0, 0};
1577 bool use_current_os_version = false;
1578 switch (sdk_type) {
1579 case SDKType::iPhoneOS:
1580#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
1581 use_current_os_version = true;
1582#else
1583 use_current_os_version = false;
1584#endif
1585 break;
1586
1587 case SDKType::iPhoneSimulator:
1588 use_current_os_version = false;
1589 break;
1590
1591 case SDKType::MacOSX:
1592#if defined(__i386__) || defined(__x86_64__1)
1593 use_current_os_version = true;
1594#else
1595 use_current_os_version = false;
1596#endif
1597 break;
1598 }
1599
1600 bool versions_valid = false;
1601 if (use_current_os_version)
1602 versions_valid = GetOSVersion(versions[0], versions[1], versions[2]);
1603 else if (target) {
1604 // Our OS doesn't match our executable so we need to get the min OS version
1605 // from the object file
1606 ModuleSP exe_module_sp = target->GetExecutableModule();
1607 if (exe_module_sp) {
1608 ObjectFile *object_file = exe_module_sp->GetObjectFile();
1609 if (object_file)
1610 versions_valid = object_file->GetMinimumOSVersion(versions, 3) > 0;
1611 }
1612 }
1613 // Only add the version-min options if we got a version from somewhere
1614 if (versions_valid && versions[0] != UINT32_MAX(4294967295U)) {
1615 // Make any invalid versions be zero if needed
1616 if (versions[1] == UINT32_MAX(4294967295U))
1617 versions[1] = 0;
1618 if (versions[2] == UINT32_MAX(4294967295U))
1619 versions[2] = 0;
1620
1621 switch (sdk_type) {
1622 case SDKType::iPhoneOS:
1623 minimum_version_option.PutCString("-mios-version-min=");
1624 minimum_version_option.PutCString(
1625 clang::VersionTuple(versions[0], versions[1], versions[2])
1626 .getAsString());
1627 break;
1628 case SDKType::iPhoneSimulator:
1629 minimum_version_option.PutCString("-mios-simulator-version-min=");
1630 minimum_version_option.PutCString(
1631 clang::VersionTuple(versions[0], versions[1], versions[2])
1632 .getAsString());
1633 break;
1634 case SDKType::MacOSX:
1635 minimum_version_option.PutCString("-mmacosx-version-min=");
1636 minimum_version_option.PutCString(
1637 clang::VersionTuple(versions[0], versions[1], versions[2])
1638 .getAsString());
1639 }
1640 options.push_back(minimum_version_option.GetString());
1641 }
1642
1643 FileSpec sysroot_spec;
1644 // Scope for mutex locker below
1645 {
1646 std::lock_guard<std::mutex> guard(m_mutex);
1647 sysroot_spec = GetSDKDirectoryForModules(sdk_type);
1648 }
1649
1650 if (llvm::sys::fs::is_directory(sysroot_spec.GetPath())) {
1651 options.push_back("-isysroot");
1652 options.push_back(sysroot_spec.GetPath());
1653 }
1654}
1655
1656ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) {
1657 if (basename.IsEmpty())
1658 return basename;
1659
1660 StreamString stream;
1661 stream.Printf("lib%s.dylib", basename.GetCString());
1662 return ConstString(stream.GetString());
1663}
1664
1665bool PlatformDarwin::GetOSVersion(uint32_t &major, uint32_t &minor,
1666 uint32_t &update, Process *process) {
1667 if (process && strstr(GetPluginName().GetCString(), "-simulator")) {
1668 lldb_private::ProcessInstanceInfo proc_info;
1669 if (Host::GetProcessInfo(process->GetID(), proc_info)) {
1670 Args &env = proc_info.GetEnvironmentEntries();
1671 const size_t n = env.GetArgumentCount();
1672 const llvm::StringRef k_runtime_version("SIMULATOR_RUNTIME_VERSION=");
1673 const llvm::StringRef k_dyld_root_path("DYLD_ROOT_PATH=");
1674 std::string dyld_root_path;
1675
1676 for (size_t i = 0; i < n; ++i) {
1677 const char *env_cstr = env.GetArgumentAtIndex(i);
1678 if (env_cstr) {
1679 llvm::StringRef env_str(env_cstr);
1680 if (env_str.consume_front(k_runtime_version)) {
1681 if (Args::StringToVersion(env_str, major, minor, update))
1682 return true;
1683 } else if (env_str.consume_front(k_dyld_root_path)) {
1684 dyld_root_path = env_str;
1685 }
1686 }
1687 }
1688
1689 if (!dyld_root_path.empty()) {
1690 dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
1691 ApplePropertyList system_version_plist(dyld_root_path.c_str());
1692 std::string product_version;
1693 if (system_version_plist.GetValueAsString("ProductVersion",
1694 product_version)) {
1695 return Args::StringToVersion(product_version, major, minor, update);
1696 }
1697 }
1698 }
1699 // For simulator platforms, do NOT call back through
1700 // Platform::GetOSVersion()
1701 // as it might call Process::GetHostOSVersion() which we don't want as it
1702 // will be
1703 // incorrect
1704 return false;
1705 }
1706
1707 return Platform::GetOSVersion(major, minor, update, process);
1708}
1709
1710lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
1711 // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled
1712 // in with
1713 // any executable directories that should be searched.
1714 static std::vector<FileSpec> g_executable_dirs;
1715
1716 // Find the global list of directories that we will search for
1717 // executables once so we don't keep doing the work over and over.
1718 static llvm::once_flag g_once_flag;
1719 llvm::call_once(g_once_flag, []() {
1720
1721 // When locating executables, trust the DEVELOPER_DIR first if it is set
1722 FileSpec xcode_contents_dir = GetXcodeContentsPath();
1723 if (xcode_contents_dir) {
1724 FileSpec xcode_lldb_resources = xcode_contents_dir;
1725 xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
1726 xcode_lldb_resources.AppendPathComponent("LLDB.framework");
1727 xcode_lldb_resources.AppendPathComponent("Resources");
1728 if (xcode_lldb_resources.Exists()) {
1729 FileSpec dir;
1730 dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
1731 g_executable_dirs.push_back(dir);
1732 }
1733 }
1734 });
1735
1736 // Now search the global list of executable directories for the executable we
1737 // are looking for
1738 for (const auto &executable_dir : g_executable_dirs) {
1739 FileSpec executable_file;
1740 executable_file.GetDirectory() = executable_dir.GetDirectory();
1741 executable_file.GetFilename().SetCString(basename);
1742 if (executable_file.Exists())
1743 return executable_file;
1744 }
1745
1746 return FileSpec();
1747}
1748
1749lldb_private::Status
1750PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) {
1751 // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr
1752 // if the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't
1753 // require any specific value; rather, it just needs to exist).
1754 // We will set it here as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag
1755 // is not set. Xcode makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
1756 // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
1757 // specifically want it unset.
1758 const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
1759 auto &env_vars = launch_info.GetEnvironmentEntries();
1760 if (!env_vars.ContainsEnvironmentVariable(llvm::StringRef(disable_env_var))) {
1761 // We want to make sure that OS_ACTIVITY_DT_MODE is set so that
1762 // we get os_log and NSLog messages mirrored to the target process
1763 // stderr.
1764 if (!env_vars.ContainsEnvironmentVariable(
1765 llvm::StringRef("OS_ACTIVITY_DT_MODE")))
1766 env_vars.AppendArgument(llvm::StringRef("OS_ACTIVITY_DT_MODE=enable"));
1767 }
1768
1769 // Let our parent class do the real launching.
1770 return PlatformPOSIX::LaunchProcess(launch_info);
1771}
1772
1773lldb_private::Status
1774PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec, Process *process,
1775 ModuleSP &module_sp,
1776 const FileSpecList *module_search_paths_ptr,
1777 ModuleSP *old_module_sp_ptr, bool *did_create_ptr)
1778{
1779 const FileSpec &platform_file = module_spec.GetFileSpec();
1780 // See if the file is present in any of the module_search_paths_ptr directories.
1781 if (!module_sp && module_search_paths_ptr && platform_file) {
1782 // create a vector of all the file / directory names in platform_file
1783 // e.g. this might be
1784 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
1785 //
1786 // We'll need to look in the module_search_paths_ptr directories for
1787 // both "UIFoundation" and "UIFoundation.framework" -- most likely the
1788 // latter will be the one we find there.
1789
1790 FileSpec platform_pull_apart(platform_file);
1791 std::vector<std::string> path_parts;
1792 ConstString unix_root_dir("/");
1793 while (true) {
1794 ConstString part = platform_pull_apart.GetLastPathComponent();
1795 platform_pull_apart.RemoveLastPathComponent();
1796 if (part.IsEmpty() || part == unix_root_dir)
1797 break;
1798 path_parts.push_back(part.AsCString());
1799 }
1800 const size_t path_parts_size = path_parts.size();
1801
1802 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
1803 for (size_t i = 0; i < num_module_search_paths; ++i) {
1804 Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST(1u << 14));
1805 if (log_verbose)
1806 log_verbose->Printf ("PlatformRemoteDarwinDevice::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
1807 // Create a new FileSpec with this module_search_paths_ptr
1808 // plus just the filename ("UIFoundation"), then the parent
1809 // dir plus filename ("UIFoundation.framework/UIFoundation")
1810 // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
1811
1812 for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
1813 FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
1814
1815 // Add the components backwards. For
1816 // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
1817 // path_parts is
1818 // [0] UIFoundation
1819 // [1] UIFoundation.framework
1820 // [2] PrivateFrameworks
1821 //
1822 // and if 'j' is 2, we want to append path_parts[1] and then
1823 // path_parts[0], aka
1824 // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
1825 // path.
1826
1827 for (int k = j; k >= 0; --k) {
1828 path_to_try.AppendPathComponent(path_parts[k]);
1829 }
1830
1831 if (path_to_try.Exists()) {
1832 ModuleSpec new_module_spec(module_spec);
1833 new_module_spec.GetFileSpec() = path_to_try;
1834 Status new_error(Platform::GetSharedModule(
1835 new_module_spec, process, module_sp, NULL__null, old_module_sp_ptr,
1836 did_create_ptr));
1837
1838 if (module_sp) {
1839 module_sp->SetPlatformFileSpec(path_to_try);
1840 return new_error;
1841 }
1842 }
1843 }
1844 }
1845 }
1846 return Status();
1847}