Coverage Report

Created: 2022-01-15 10:30

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- PlatformDarwin.cpp ------------------------------------------------===//
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
#include "PlatformDarwin.h"
10
11
#include <cstring>
12
13
#include <algorithm>
14
#include <memory>
15
#include <mutex>
16
17
#include "lldb/Breakpoint/BreakpointLocation.h"
18
#include "lldb/Breakpoint/BreakpointSite.h"
19
#include "lldb/Core/Debugger.h"
20
#include "lldb/Core/Module.h"
21
#include "lldb/Core/ModuleSpec.h"
22
#include "lldb/Core/Section.h"
23
#include "lldb/Host/Host.h"
24
#include "lldb/Host/HostInfo.h"
25
#include "lldb/Host/XML.h"
26
#include "lldb/Interpreter/CommandInterpreter.h"
27
#include "lldb/Symbol/LocateSymbolFile.h"
28
#include "lldb/Symbol/ObjectFile.h"
29
#include "lldb/Symbol/SymbolFile.h"
30
#include "lldb/Symbol/SymbolVendor.h"
31
#include "lldb/Target/Platform.h"
32
#include "lldb/Target/Process.h"
33
#include "lldb/Target/Target.h"
34
#include "lldb/Utility/Log.h"
35
#include "lldb/Utility/ProcessInfo.h"
36
#include "lldb/Utility/Status.h"
37
#include "lldb/Utility/Timer.h"
38
#include "llvm/ADT/STLExtras.h"
39
#include "llvm/Support/FileSystem.h"
40
#include "llvm/Support/Threading.h"
41
#include "llvm/Support/VersionTuple.h"
42
43
#if defined(__APPLE__)
44
#include <TargetConditionals.h>
45
#endif
46
47
using namespace lldb;
48
using namespace lldb_private;
49
50
/// Default Constructor
51
3.47k
PlatformDarwin::PlatformDarwin(bool is_host) : PlatformPOSIX(is_host) {}
52
53
/// Destructor.
54
///
55
/// The destructor is virtual since this class is designed to be
56
/// inherited from by the plug-in instance.
57
3.14k
PlatformDarwin::~PlatformDarwin() = default;
58
59
lldb_private::Status
60
PlatformDarwin::PutFile(const lldb_private::FileSpec &source,
61
                        const lldb_private::FileSpec &destination, uint32_t uid,
62
1
                        uint32_t gid) {
63
  // Unconditionally unlink the destination. If it is an executable,
64
  // simply opening it and truncating its contents would invalidate
65
  // its cached code signature.
66
1
  Unlink(destination);
67
1
  return PlatformPOSIX::PutFile(source, destination, uid, gid);
68
1
}
69
70
FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
71
278k
    Target *target, Module &module, Stream *feedback_stream) {
72
278k
  FileSpecList file_list;
73
278k
  if (target &&
74
278k
      
target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython278k
) {
75
    // NB some extensions might be meaningful and should not be stripped -
76
    // "this.binary.file"
77
    // should not lose ".file" but GetFileNameStrippingExtension() will do
78
    // precisely that. Ideally, we should have a per-platform list of
79
    // extensions (".exe", ".app", ".dSYM", ".framework") which should be
80
    // stripped while leaving "this.binary.file" as-is.
81
82
278k
    FileSpec module_spec = module.GetFileSpec();
83
84
278k
    if (module_spec) {
85
278k
      if (SymbolFile *symfile = module.GetSymbolFile()) {
86
276k
        ObjectFile *objfile = symfile->GetObjectFile();
87
276k
        if (
objfile276k
) {
88
276k
          FileSpec symfile_spec(objfile->GetFileSpec());
89
276k
          if (symfile_spec &&
90
276k
              strcasestr(symfile_spec.GetPath().c_str(),
91
270k
                         ".dSYM/Contents/Resources/DWARF") != nullptr &&
92
276k
              
FileSystem::Instance().Exists(symfile_spec)2.57k
) {
93
5.01k
            while (module_spec.GetFilename()) {
94
5.01k
              std::string module_basename(
95
5.01k
                  module_spec.GetFilename().GetCString());
96
5.01k
              std::string original_module_basename(module_basename);
97
98
5.01k
              bool was_keyword = false;
99
100
              // FIXME: for Python, we cannot allow certain characters in
101
              // module
102
              // filenames we import. Theoretically, different scripting
103
              // languages may have different sets of forbidden tokens in
104
              // filenames, and that should be dealt with by each
105
              // ScriptInterpreter. For now, we just replace dots with
106
              // underscores, but if we ever support anything other than
107
              // Python we will need to rework this
108
5.01k
              std::replace(module_basename.begin(), module_basename.end(), '.',
109
5.01k
                           '_');
110
5.01k
              std::replace(module_basename.begin(), module_basename.end(), ' ',
111
5.01k
                           '_');
112
5.01k
              std::replace(module_basename.begin(), module_basename.end(), '-',
113
5.01k
                           '_');
114
5.01k
              ScriptInterpreter *script_interpreter =
115
5.01k
                  target->GetDebugger().GetScriptInterpreter();
116
5.01k
              if (script_interpreter &&
117
5.01k
                  script_interpreter->IsReservedWord(module_basename.c_str())) {
118
2
                module_basename.insert(module_basename.begin(), '_');
119
2
                was_keyword = true;
120
2
              }
121
122
5.01k
              StreamString path_string;
123
5.01k
              StreamString original_path_string;
124
              // for OSX we are going to be in
125
              // .dSYM/Contents/Resources/DWARF/<basename> let us go to
126
              // .dSYM/Contents/Resources/Python/<basename>.py and see if the
127
              // file exists
128
5.01k
              path_string.Printf("%s/../Python/%s.py",
129
5.01k
                                 symfile_spec.GetDirectory().GetCString(),
130
5.01k
                                 module_basename.c_str());
131
5.01k
              original_path_string.Printf(
132
5.01k
                  "%s/../Python/%s.py",
133
5.01k
                  symfile_spec.GetDirectory().GetCString(),
134
5.01k
                  original_module_basename.c_str());
135
5.01k
              FileSpec script_fspec(path_string.GetString());
136
5.01k
              FileSystem::Instance().Resolve(script_fspec);
137
5.01k
              FileSpec orig_script_fspec(original_path_string.GetString());
138
5.01k
              FileSystem::Instance().Resolve(orig_script_fspec);
139
140
              // if we did some replacements of reserved characters, and a
141
              // file with the untampered name exists, then warn the user
142
              // that the file as-is shall not be loaded
143
5.01k
              if (feedback_stream) {
144
5.01k
                if (module_basename != original_module_basename &&
145
5.01k
                    
FileSystem::Instance().Exists(orig_script_fspec)2.47k
) {
146
0
                  const char *reason_for_complaint =
147
0
                      was_keyword ? "conflicts with a keyword"
148
0
                                  : "contains reserved characters";
149
0
                  if (FileSystem::Instance().Exists(script_fspec))
150
0
                    feedback_stream->Printf(
151
0
                        "warning: the symbol file '%s' contains a debug "
152
0
                        "script. However, its name"
153
0
                        " '%s' %s and as such cannot be loaded. LLDB will"
154
0
                        " load '%s' instead. Consider removing the file with "
155
0
                        "the malformed name to"
156
0
                        " eliminate this warning.\n",
157
0
                        symfile_spec.GetPath().c_str(),
158
0
                        original_path_string.GetData(), reason_for_complaint,
159
0
                        path_string.GetData());
160
0
                  else
161
0
                    feedback_stream->Printf(
162
0
                        "warning: the symbol file '%s' contains a debug "
163
0
                        "script. However, its name"
164
0
                        " %s and as such cannot be loaded. If you intend"
165
0
                        " to have this script loaded, please rename '%s' to "
166
0
                        "'%s' and retry.\n",
167
0
                        symfile_spec.GetPath().c_str(), reason_for_complaint,
168
0
                        original_path_string.GetData(), path_string.GetData());
169
0
                }
170
5.01k
              }
171
172
5.01k
              if (FileSystem::Instance().Exists(script_fspec)) {
173
2
                file_list.Append(script_fspec);
174
2
                break;
175
2
              }
176
177
              // If we didn't find the python file, then keep stripping the
178
              // extensions and try again
179
5.01k
              ConstString filename_no_extension(
180
5.01k
                  module_spec.GetFileNameStrippingExtension());
181
5.01k
              if (module_spec.GetFilename() == filename_no_extension)
182
2.57k
                break;
183
184
2.44k
              module_spec.GetFilename() = filename_no_extension;
185
2.44k
            }
186
2.57k
          }
187
276k
        }
188
276k
      }
189
278k
    }
190
278k
  }
191
278k
  return file_list;
192
278k
}
193
194
Status PlatformDarwin::ResolveSymbolFile(Target &target,
195
                                         const ModuleSpec &sym_spec,
196
15
                                         FileSpec &sym_file) {
197
15
  sym_file = sym_spec.GetSymbolFileSpec();
198
15
  if (FileSystem::Instance().IsDirectory(sym_file)) {
199
4
    sym_file = Symbols::FindSymbolFileInBundle(sym_file, sym_spec.GetUUIDPtr(),
200
4
                                               sym_spec.GetArchitecturePtr());
201
4
  }
202
15
  return {};
203
15
}
204
205
static lldb_private::Status
206
0
MakeCacheFolderForFile(const FileSpec &module_cache_spec) {
207
0
  FileSpec module_cache_folder =
208
0
      module_cache_spec.CopyByRemovingLastPathComponent();
209
0
  return llvm::sys::fs::create_directory(module_cache_folder.GetPath());
210
0
}
211
212
static lldb_private::Status
213
BringInRemoteFile(Platform *platform,
214
                  const lldb_private::ModuleSpec &module_spec,
215
0
                  const FileSpec &module_cache_spec) {
216
0
  MakeCacheFolderForFile(module_cache_spec);
217
0
  Status err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
218
0
  return err;
219
0
}
220
221
lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
222
    const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
223
    const lldb_private::FileSpecList *module_search_paths_ptr,
224
136k
    llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
225
226
136k
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
227
136k
  LLDB_LOGF(log,
228
136k
            "[%s] Trying to find module %s/%s - platform path %s/%s symbol "
229
136k
            "path %s/%s",
230
136k
            (IsHost() ? "host" : "remote"),
231
136k
            module_spec.GetFileSpec().GetDirectory().AsCString(),
232
136k
            module_spec.GetFileSpec().GetFilename().AsCString(),
233
136k
            module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
234
136k
            module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
235
136k
            module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
236
136k
            module_spec.GetSymbolFileSpec().GetFilename().AsCString());
237
238
136k
  Status err;
239
240
136k
  if (CheckLocalSharedCache()) {
241
    // When debugging on the host, we are most likely using the same shared
242
    // cache as our inferior. The dylibs from the shared cache might not
243
    // exist on the filesystem, so let's use the images in our own memory
244
    // to create the modules.
245
246
    // Check if the requested image is in our shared cache.
247
136k
    SharedCacheImageInfo image_info =
248
136k
        HostInfo::GetSharedCacheImageInfo(module_spec.GetFileSpec().GetPath());
249
250
    // If we found it and it has the correct UUID, let's proceed with
251
    // creating a module from the memory contents.
252
136k
    if (image_info.uuid &&
253
136k
        
(133k
!module_spec.GetUUID()133k
||
module_spec.GetUUID() == image_info.uuid0
)) {
254
133k
      ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid,
255
133k
                                   image_info.data_sp);
256
133k
      err = ModuleList::GetSharedModule(shared_cache_spec, module_sp,
257
133k
                                        module_search_paths_ptr, old_modules,
258
133k
                                        did_create_ptr);
259
133k
      if (module_sp)
260
133k
        return err;
261
133k
    }
262
136k
  }
263
264
3.23k
  err = ModuleList::GetSharedModule(module_spec, module_sp,
265
3.23k
                                    module_search_paths_ptr, old_modules,
266
3.23k
                                    did_create_ptr);
267
3.23k
  if (module_sp)
268
3.01k
    return err;
269
270
225
  if (!IsHost()) {
271
4
    std::string cache_path(GetLocalCacheDirectory());
272
    // Only search for a locally cached file if we have a valid cache path
273
4
    if (!cache_path.empty()) {
274
0
      std::string module_path(module_spec.GetFileSpec().GetPath());
275
0
      cache_path.append(module_path);
276
0
      FileSpec module_cache_spec(cache_path);
277
278
      // if rsync is supported, always bring in the file - rsync will be very
279
      // efficient when files are the same on the local and remote end of the
280
      // connection
281
0
      if (this->GetSupportsRSync()) {
282
0
        err = BringInRemoteFile(this, module_spec, module_cache_spec);
283
0
        if (err.Fail())
284
0
          return err;
285
0
        if (FileSystem::Instance().Exists(module_cache_spec)) {
286
0
          Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
287
0
          LLDB_LOGF(log, "[%s] module %s/%s was rsynced and is now there",
288
0
                    (IsHost() ? "host" : "remote"),
289
0
                    module_spec.GetFileSpec().GetDirectory().AsCString(),
290
0
                    module_spec.GetFileSpec().GetFilename().AsCString());
291
0
          ModuleSpec local_spec(module_cache_spec,
292
0
                                module_spec.GetArchitecture());
293
0
          module_sp = std::make_shared<Module>(local_spec);
294
0
          module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
295
0
          return Status();
296
0
        }
297
0
      }
298
299
      // try to find the module in the cache
300
0
      if (FileSystem::Instance().Exists(module_cache_spec)) {
301
        // get the local and remote MD5 and compare
302
0
        if (m_remote_platform_sp) {
303
          // when going over the *slow* GDB remote transfer mechanism we first
304
          // check the hashes of the files - and only do the actual transfer if
305
          // they differ
306
0
          uint64_t high_local, high_remote, low_local, low_remote;
307
0
          auto MD5 = llvm::sys::fs::md5_contents(module_cache_spec.GetPath());
308
0
          if (!MD5)
309
0
            return Status(MD5.getError());
310
0
          std::tie(high_local, low_local) = MD5->words();
311
312
0
          m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(),
313
0
                                             low_remote, high_remote);
314
0
          if (low_local != low_remote || high_local != high_remote) {
315
            // bring in the remote file
316
0
            Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
317
0
            LLDB_LOGF(log,
318
0
                      "[%s] module %s/%s needs to be replaced from remote copy",
319
0
                      (IsHost() ? "host" : "remote"),
320
0
                      module_spec.GetFileSpec().GetDirectory().AsCString(),
321
0
                      module_spec.GetFileSpec().GetFilename().AsCString());
322
0
            Status err =
323
0
                BringInRemoteFile(this, module_spec, module_cache_spec);
324
0
            if (err.Fail())
325
0
              return err;
326
0
          }
327
0
        }
328
329
0
        ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
330
0
        module_sp = std::make_shared<Module>(local_spec);
331
0
        module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
332
0
        Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
333
0
        LLDB_LOGF(log, "[%s] module %s/%s was found in the cache",
334
0
                  (IsHost() ? "host" : "remote"),
335
0
                  module_spec.GetFileSpec().GetDirectory().AsCString(),
336
0
                  module_spec.GetFileSpec().GetFilename().AsCString());
337
0
        return Status();
338
0
      }
339
340
      // bring in the remote module file
341
0
      LLDB_LOGF(log, "[%s] module %s/%s needs to come in remotely",
342
0
                (IsHost() ? "host" : "remote"),
343
0
                module_spec.GetFileSpec().GetDirectory().AsCString(),
344
0
                module_spec.GetFileSpec().GetFilename().AsCString());
345
0
      Status err = BringInRemoteFile(this, module_spec, module_cache_spec);
346
0
      if (err.Fail())
347
0
        return err;
348
0
      if (FileSystem::Instance().Exists(module_cache_spec)) {
349
0
        Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
350
0
        LLDB_LOGF(log, "[%s] module %s/%s is now cached and fine",
351
0
                  (IsHost() ? "host" : "remote"),
352
0
                  module_spec.GetFileSpec().GetDirectory().AsCString(),
353
0
                  module_spec.GetFileSpec().GetFilename().AsCString());
354
0
        ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
355
0
        module_sp = std::make_shared<Module>(local_spec);
356
0
        module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
357
0
        return Status();
358
0
      } else
359
0
        return Status("unable to obtain valid module file");
360
0
    } else
361
4
      return Status("no cache path");
362
4
  } else
363
221
    return Status("unable to resolve module");
364
225
}
365
366
Status PlatformDarwin::GetSharedModule(
367
    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
368
    const FileSpecList *module_search_paths_ptr,
369
0
    llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
370
0
  Status error;
371
0
  module_sp.reset();
372
373
0
  if (IsRemote()) {
374
    // If we have a remote platform always, let it try and locate the shared
375
    // module first.
376
0
    if (m_remote_platform_sp) {
377
0
      error = m_remote_platform_sp->GetSharedModule(
378
0
          module_spec, process, module_sp, module_search_paths_ptr, old_modules,
379
0
          did_create_ptr);
380
0
    }
381
0
  }
382
383
0
  if (!module_sp) {
384
    // Fall back to the local platform and find the file locally
385
0
    error = Platform::GetSharedModule(module_spec, process, module_sp,
386
0
                                      module_search_paths_ptr, old_modules,
387
0
                                      did_create_ptr);
388
389
0
    const FileSpec &platform_file = module_spec.GetFileSpec();
390
0
    if (!module_sp && module_search_paths_ptr && platform_file) {
391
      // We can try to pull off part of the file path up to the bundle
392
      // directory level and try any module search paths...
393
0
      FileSpec bundle_directory;
394
0
      if (Host::GetBundleDirectory(platform_file, bundle_directory)) {
395
0
        if (platform_file == bundle_directory) {
396
0
          ModuleSpec new_module_spec(module_spec);
397
0
          new_module_spec.GetFileSpec() = bundle_directory;
398
0
          if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) {
399
0
            Status new_error(Platform::GetSharedModule(
400
0
                new_module_spec, process, module_sp, nullptr, old_modules,
401
0
                did_create_ptr));
402
403
0
            if (module_sp)
404
0
              return new_error;
405
0
          }
406
0
        } else {
407
0
          char platform_path[PATH_MAX];
408
0
          char bundle_dir[PATH_MAX];
409
0
          platform_file.GetPath(platform_path, sizeof(platform_path));
410
0
          const size_t bundle_directory_len =
411
0
              bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir));
412
0
          char new_path[PATH_MAX];
413
0
          size_t num_module_search_paths = module_search_paths_ptr->GetSize();
414
0
          for (size_t i = 0; i < num_module_search_paths; ++i) {
415
0
            const size_t search_path_len =
416
0
                module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(
417
0
                    new_path, sizeof(new_path));
418
0
            if (search_path_len < sizeof(new_path)) {
419
0
              snprintf(new_path + search_path_len,
420
0
                       sizeof(new_path) - search_path_len, "/%s",
421
0
                       platform_path + bundle_directory_len);
422
0
              FileSpec new_file_spec(new_path);
423
0
              if (FileSystem::Instance().Exists(new_file_spec)) {
424
0
                ModuleSpec new_module_spec(module_spec);
425
0
                new_module_spec.GetFileSpec() = new_file_spec;
426
0
                Status new_error(Platform::GetSharedModule(
427
0
                    new_module_spec, process, module_sp, nullptr, old_modules,
428
0
                    did_create_ptr));
429
430
0
                if (module_sp) {
431
0
                  module_sp->SetPlatformFileSpec(new_file_spec);
432
0
                  return new_error;
433
0
                }
434
0
              }
435
0
            }
436
0
          }
437
0
        }
438
0
      }
439
0
    }
440
0
  }
441
0
  if (module_sp)
442
0
    module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
443
0
  return error;
444
0
}
445
446
size_t
447
PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,
448
67.4k
                                                BreakpointSite *bp_site) {
449
67.4k
  const uint8_t *trap_opcode = nullptr;
450
67.4k
  uint32_t trap_opcode_size = 0;
451
67.4k
  bool bp_is_thumb = false;
452
453
67.4k
  llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
454
67.4k
  switch (machine) {
455
0
  case llvm::Triple::aarch64_32:
456
0
  case llvm::Triple::aarch64: {
457
    // 'brk #0' or 0xd4200000 in BE byte order
458
0
    static const uint8_t g_arm64_breakpoint_opcode[] = {0x00, 0x00, 0x20, 0xD4};
459
0
    trap_opcode = g_arm64_breakpoint_opcode;
460
0
    trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
461
0
  } break;
462
463
0
  case llvm::Triple::thumb:
464
0
    bp_is_thumb = true;
465
0
    LLVM_FALLTHROUGH;
466
0
  case llvm::Triple::arm: {
467
0
    static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
468
0
    static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE};
469
470
    // Auto detect arm/thumb if it wasn't explicitly specified
471
0
    if (!bp_is_thumb) {
472
0
      lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
473
0
      if (bp_loc_sp)
474
0
        bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
475
0
                      AddressClass::eCodeAlternateISA;
476
0
    }
477
0
    if (bp_is_thumb) {
478
0
      trap_opcode = g_thumb_breakpooint_opcode;
479
0
      trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
480
0
      break;
481
0
    }
482
0
    trap_opcode = g_arm_breakpoint_opcode;
483
0
    trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
484
0
  } break;
485
486
0
  case llvm::Triple::ppc:
487
0
  case llvm::Triple::ppc64: {
488
0
    static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
489
0
    trap_opcode = g_ppc_breakpoint_opcode;
490
0
    trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
491
0
  } break;
492
493
67.4k
  default:
494
67.4k
    return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
495
67.4k
  }
496
497
0
  if (trap_opcode && trap_opcode_size) {
498
0
    if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
499
0
      return trap_opcode_size;
500
0
  }
501
0
  return 0;
502
0
}
503
504
bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches(
505
354k
    lldb_private::Target &target, const lldb::ModuleSP &module_sp) {
506
354k
  if (!module_sp)
507
0
    return false;
508
509
354k
  ObjectFile *obj_file = module_sp->GetObjectFile();
510
354k
  if (!obj_file)
511
0
    return false;
512
513
354k
  ObjectFile::Type obj_type = obj_file->GetType();
514
354k
  return obj_type == ObjectFile::eTypeDynamicLinker;
515
354k
}
516
517
void PlatformDarwin::x86GetSupportedArchitectures(
518
8.67k
    std::vector<ArchSpec> &archs) {
519
8.67k
  ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
520
8.67k
  archs.push_back(host_arch);
521
522
8.67k
  if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) {
523
0
    archs.push_back(ArchSpec("x86_64-apple-macosx"));
524
0
    archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));
525
8.67k
  } else {
526
8.67k
    ArchSpec host_arch64 = HostInfo::GetArchitecture(HostInfo::eArchKind64);
527
8.67k
    if (host_arch.IsExactMatch(host_arch64))
528
8.67k
      archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));
529
8.67k
  }
530
8.67k
}
531
532
1.54k
static llvm::ArrayRef<const char *> GetCompatibleArchs(ArchSpec::Core core) {
533
1.54k
  switch (core) {
534
1.50k
  default:
535
1.50k
    LLVM_FALLTHROUGH;
536
1.50k
  case ArchSpec::eCore_arm_arm64e: {
537
1.50k
    static const char *g_arm64e_compatible_archs[] = {
538
1.50k
        "arm64e",    "arm64",    "armv7",    "armv7f",   "armv7k",   "armv7s",
539
1.50k
        "armv7m",    "armv7em",  "armv6m",   "armv6",    "armv5",    "armv4",
540
1.50k
        "arm",       "thumbv7",  "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m",
541
1.50k
        "thumbv7em", "thumbv6m", "thumbv6",  "thumbv5",  "thumbv4t", "thumb",
542
1.50k
    };
543
1.50k
    return {g_arm64e_compatible_archs};
544
1.50k
  }
545
8
  case ArchSpec::eCore_arm_arm64: {
546
8
    static const char *g_arm64_compatible_archs[] = {
547
8
        "arm64",    "armv7",    "armv7f",   "armv7k",   "armv7s",   "armv7m",
548
8
        "armv7em",  "armv6m",   "armv6",    "armv5",    "armv4",    "arm",
549
8
        "thumbv7",  "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", "thumbv7em",
550
8
        "thumbv6m", "thumbv6",  "thumbv5",  "thumbv4t", "thumb",
551
8
    };
552
8
    return {g_arm64_compatible_archs};
553
1.50k
  }
554
4
  case ArchSpec::eCore_arm_armv7: {
555
4
    static const char *g_armv7_compatible_archs[] = {
556
4
        "armv7",   "armv6m",   "armv6",   "armv5",   "armv4",    "arm",
557
4
        "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
558
4
    };
559
4
    return {g_armv7_compatible_archs};
560
1.50k
  }
561
4
  case ArchSpec::eCore_arm_armv7f: {
562
4
    static const char *g_armv7f_compatible_archs[] = {
563
4
        "armv7f",  "armv7",   "armv6m",   "armv6",   "armv5",
564
4
        "armv4",   "arm",     "thumbv7f", "thumbv7", "thumbv6m",
565
4
        "thumbv6", "thumbv5", "thumbv4t", "thumb",
566
4
    };
567
4
    return {g_armv7f_compatible_archs};
568
1.50k
  }
569
4
  case ArchSpec::eCore_arm_armv7k: {
570
4
    static const char *g_armv7k_compatible_archs[] = {
571
4
        "armv7k",  "armv7",   "armv6m",   "armv6",   "armv5",
572
4
        "armv4",   "arm",     "thumbv7k", "thumbv7", "thumbv6m",
573
4
        "thumbv6", "thumbv5", "thumbv4t", "thumb",
574
4
    };
575
4
    return {g_armv7k_compatible_archs};
576
1.50k
  }
577
4
  case ArchSpec::eCore_arm_armv7s: {
578
4
    static const char *g_armv7s_compatible_archs[] = {
579
4
        "armv7s",  "armv7",   "armv6m",   "armv6",   "armv5",
580
4
        "armv4",   "arm",     "thumbv7s", "thumbv7", "thumbv6m",
581
4
        "thumbv6", "thumbv5", "thumbv4t", "thumb",
582
4
    };
583
4
    return {g_armv7s_compatible_archs};
584
1.50k
  }
585
4
  case ArchSpec::eCore_arm_armv7m: {
586
4
    static const char *g_armv7m_compatible_archs[] = {
587
4
        "armv7m",  "armv7",   "armv6m",   "armv6",   "armv5",
588
4
        "armv4",   "arm",     "thumbv7m", "thumbv7", "thumbv6m",
589
4
        "thumbv6", "thumbv5", "thumbv4t", "thumb",
590
4
    };
591
4
    return {g_armv7m_compatible_archs};
592
1.50k
  }
593
4
  case ArchSpec::eCore_arm_armv7em: {
594
4
    static const char *g_armv7em_compatible_archs[] = {
595
4
        "armv7em", "armv7",   "armv6m",    "armv6",   "armv5",
596
4
        "armv4",   "arm",     "thumbv7em", "thumbv7", "thumbv6m",
597
4
        "thumbv6", "thumbv5", "thumbv4t",  "thumb",
598
4
    };
599
4
    return {g_armv7em_compatible_archs};
600
1.50k
  }
601
4
  case ArchSpec::eCore_arm_armv6m: {
602
4
    static const char *g_armv6m_compatible_archs[] = {
603
4
        "armv6m",   "armv6",   "armv5",   "armv4",    "arm",
604
4
        "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
605
4
    };
606
4
    return {g_armv6m_compatible_archs};
607
1.50k
  }
608
4
  case ArchSpec::eCore_arm_armv6: {
609
4
    static const char *g_armv6_compatible_archs[] = {
610
4
        "armv6",   "armv5",   "armv4",    "arm",
611
4
        "thumbv6", "thumbv5", "thumbv4t", "thumb",
612
4
    };
613
4
    return {g_armv6_compatible_archs};
614
1.50k
  }
615
4
  case ArchSpec::eCore_arm_armv5: {
616
4
    static const char *g_armv5_compatible_archs[] = {
617
4
        "armv5", "armv4", "arm", "thumbv5", "thumbv4t", "thumb",
618
4
    };
619
4
    return {g_armv5_compatible_archs};
620
1.50k
  }
621
4
  case ArchSpec::eCore_arm_armv4: {
622
4
    static const char *g_armv4_compatible_archs[] = {
623
4
        "armv4",
624
4
        "arm",
625
4
        "thumbv4t",
626
4
        "thumb",
627
4
    };
628
4
    return {g_armv4_compatible_archs};
629
1.50k
  }
630
1.54k
  }
631
0
  return {};
632
1.54k
}
633
634
1.54k
const char *PlatformDarwin::GetCompatibleArch(ArchSpec::Core core, size_t idx) {
635
1.54k
  llvm::ArrayRef<const char *> compatible_archs = GetCompatibleArchs(core);
636
1.54k
  if (!compatible_archs.data())
637
0
    return nullptr;
638
1.54k
  if (idx < compatible_archs.size())
639
1.48k
    return compatible_archs[idx];
640
61
  return nullptr;
641
1.54k
}
642
643
/// The architecture selection rules for arm processors These cpu subtypes have
644
/// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f
645
/// processor.
646
void PlatformDarwin::ARMGetSupportedArchitectures(
647
60
    std::vector<ArchSpec> &archs, llvm::Optional<llvm::Triple::OSType> os) {
648
60
  const ArchSpec system_arch = GetSystemArchitecture();
649
60
  const ArchSpec::Core system_core = system_arch.GetCore();
650
651
60
  const char *compatible_arch;
652
60
  for (unsigned idx = 0;
653
1.50k
       (compatible_arch = GetCompatibleArch(system_core, idx)); 
++idx1.44k
) {
654
1.44k
    llvm::Triple triple;
655
1.44k
    triple.setArchName(compatible_arch);
656
1.44k
    triple.setVendor(llvm::Triple::VendorType::Apple);
657
1.44k
    if (os)
658
1.44k
      triple.setOS(*os);
659
1.44k
    archs.push_back(ArchSpec(triple));
660
1.44k
  }
661
60
}
662
663
0
static FileSpec GetXcodeSelectPath() {
664
0
  static FileSpec g_xcode_select_filespec;
665
666
0
  if (!g_xcode_select_filespec) {
667
0
    FileSpec xcode_select_cmd("/usr/bin/xcode-select");
668
0
    if (FileSystem::Instance().Exists(xcode_select_cmd)) {
669
0
      int exit_status = -1;
670
0
      int signo = -1;
671
0
      std::string command_output;
672
0
      Status status =
673
0
          Host::RunShellCommand("/usr/bin/xcode-select --print-path",
674
0
                                FileSpec(), // current working directory
675
0
                                &exit_status, &signo, &command_output,
676
0
                                std::chrono::seconds(2), // short timeout
677
0
                                false);                  // don't run in a shell
678
0
      if (status.Success() && exit_status == 0 && !command_output.empty()) {
679
0
        size_t first_non_newline = command_output.find_last_not_of("\r\n");
680
0
        if (first_non_newline != std::string::npos) {
681
0
          command_output.erase(first_non_newline + 1);
682
0
        }
683
0
        g_xcode_select_filespec = FileSpec(command_output);
684
0
      }
685
0
    }
686
0
  }
687
688
0
  return g_xcode_select_filespec;
689
0
}
690
691
1.33k
BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) {
692
1.33k
  BreakpointSP bp_sp;
693
1.33k
  static const char *g_bp_names[] = {
694
1.33k
      "start_wqthread", "_pthread_wqthread", "_pthread_start",
695
1.33k
  };
696
697
1.33k
  static const char *g_bp_modules[] = {"libsystem_c.dylib",
698
1.33k
                                       "libSystem.B.dylib"};
699
700
1.33k
  FileSpecList bp_modules;
701
4.01k
  for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); 
i++2.67k
) {
702
2.67k
    const char *bp_module = g_bp_modules[i];
703
2.67k
    bp_modules.EmplaceBack(bp_module);
704
2.67k
  }
705
706
1.33k
  bool internal = true;
707
1.33k
  bool hardware = false;
708
1.33k
  LazyBool skip_prologue = eLazyBoolNo;
709
1.33k
  bp_sp = target.CreateBreakpoint(&bp_modules, nullptr, g_bp_names,
710
1.33k
                                  llvm::array_lengthof(g_bp_names),
711
1.33k
                                  eFunctionNameTypeFull, eLanguageTypeUnknown,
712
1.33k
                                  0, skip_prologue, internal, hardware);
713
1.33k
  bp_sp->SetBreakpointKind("thread-creation");
714
715
1.33k
  return bp_sp;
716
1.33k
}
717
718
uint32_t
719
0
PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
720
0
  const FileSpec &shell = launch_info.GetShell();
721
0
  if (!shell)
722
0
    return 1;
723
724
0
  std::string shell_string = shell.GetPath();
725
0
  const char *shell_name = strrchr(shell_string.c_str(), '/');
726
0
  if (shell_name == nullptr)
727
0
    shell_name = shell_string.c_str();
728
0
  else
729
0
    shell_name++;
730
731
0
  if (strcmp(shell_name, "sh") == 0) {
732
    // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it
733
    // only does this if the COMMAND_MODE environment variable is set to
734
    // "legacy".
735
0
    if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy")
736
0
      return 2;
737
0
    return 1;
738
0
  } else if (strcmp(shell_name, "csh") == 0 ||
739
0
             strcmp(shell_name, "tcsh") == 0 ||
740
0
             strcmp(shell_name, "zsh") == 0) {
741
    // csh and tcsh always seem to re-exec themselves.
742
0
    return 2;
743
0
  } else
744
0
    return 1;
745
0
}
746
747
lldb::ProcessSP PlatformDarwin::DebugProcess(ProcessLaunchInfo &launch_info,
748
                                             Debugger &debugger, Target &target,
749
2.56k
                                             Status &error) {
750
2.56k
  ProcessSP process_sp;
751
752
2.56k
  if (IsHost()) {
753
    // We are going to hand this process off to debugserver which will be in
754
    // charge of setting the exit status.  However, we still need to reap it
755
    // from lldb. So, make sure we use a exit callback which does not set exit
756
    // status.
757
2.56k
    const bool monitor_signals = false;
758
2.56k
    launch_info.SetMonitorProcessCallback(
759
2.56k
        &ProcessLaunchInfo::NoOpMonitorCallback, monitor_signals);
760
2.56k
    process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
761
2.56k
  } else {
762
1
    if (m_remote_platform_sp)
763
1
      process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
764
1
                                                      target, error);
765
0
    else
766
0
      error.SetErrorString("the platform is not currently connected");
767
1
  }
768
2.56k
  return process_sp;
769
2.56k
}
770
771
770
void PlatformDarwin::CalculateTrapHandlerSymbolNames() {
772
770
  m_trap_handlers.push_back(ConstString("_sigtramp"));
773
770
}
774
775
0
static FileSpec GetCommandLineToolsLibraryPath() {
776
0
  static FileSpec g_command_line_tools_filespec;
777
778
0
  if (!g_command_line_tools_filespec) {
779
0
    FileSpec command_line_tools_path(GetXcodeSelectPath());
780
0
    command_line_tools_path.AppendPathComponent("Library");
781
0
    if (FileSystem::Instance().Exists(command_line_tools_path)) {
782
0
      g_command_line_tools_filespec = command_line_tools_path;
783
0
    }
784
0
  }
785
786
0
  return g_command_line_tools_filespec;
787
0
}
788
789
FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator(
790
0
    void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) {
791
0
  SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);
792
793
0
  FileSpec spec(path);
794
0
  if (XcodeSDK::SDKSupportsModules(enumerator_info->sdk_type, spec)) {
795
0
    enumerator_info->found_path = spec;
796
0
    return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
797
0
  }
798
799
0
  return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
800
0
}
801
802
FileSpec PlatformDarwin::FindSDKInXcodeForModules(XcodeSDK::Type sdk_type,
803
0
                                                  const FileSpec &sdks_spec) {
804
  // Look inside Xcode for the required installed iOS SDK version
805
806
0
  if (!FileSystem::Instance().IsDirectory(sdks_spec)) {
807
0
    return FileSpec();
808
0
  }
809
810
0
  const bool find_directories = true;
811
0
  const bool find_files = false;
812
0
  const bool find_other = true; // include symlinks
813
814
0
  SDKEnumeratorInfo enumerator_info;
815
816
0
  enumerator_info.sdk_type = sdk_type;
817
818
0
  FileSystem::Instance().EnumerateDirectory(
819
0
      sdks_spec.GetPath(), find_directories, find_files, find_other,
820
0
      DirectoryEnumerator, &enumerator_info);
821
822
0
  if (FileSystem::Instance().IsDirectory(enumerator_info.found_path))
823
0
    return enumerator_info.found_path;
824
0
  else
825
0
    return FileSpec();
826
0
}
827
828
1.42k
FileSpec PlatformDarwin::GetSDKDirectoryForModules(XcodeSDK::Type sdk_type) {
829
1.42k
  FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory();
830
1.42k
  sdks_spec.AppendPathComponent("Developer");
831
1.42k
  sdks_spec.AppendPathComponent("Platforms");
832
833
1.42k
  switch (sdk_type) {
834
1.42k
  case XcodeSDK::Type::MacOSX:
835
1.42k
    sdks_spec.AppendPathComponent("MacOSX.platform");
836
1.42k
    break;
837
0
  case XcodeSDK::Type::iPhoneSimulator:
838
0
    sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
839
0
    break;
840
0
  case XcodeSDK::Type::iPhoneOS:
841
0
    sdks_spec.AppendPathComponent("iPhoneOS.platform");
842
0
    break;
843
0
  case XcodeSDK::Type::WatchSimulator:
844
0
    sdks_spec.AppendPathComponent("WatchSimulator.platform");
845
0
    break;
846
0
  case XcodeSDK::Type::AppleTVSimulator:
847
0
    sdks_spec.AppendPathComponent("AppleTVSimulator.platform");
848
0
    break;
849
0
  default:
850
0
    llvm_unreachable("unsupported sdk");
851
1.42k
  }
852
853
1.42k
  sdks_spec.AppendPathComponent("Developer");
854
1.42k
  sdks_spec.AppendPathComponent("SDKs");
855
856
1.42k
  if (sdk_type == XcodeSDK::Type::MacOSX) {
857
1.42k
    llvm::VersionTuple version = HostInfo::GetOSVersion();
858
859
1.42k
    if (!version.empty()) {
860
1.42k
      if (XcodeSDK::SDKSupportsModules(XcodeSDK::Type::MacOSX, version)) {
861
        // If the Xcode SDKs are not available then try to use the
862
        // Command Line Tools one which is only for MacOSX.
863
1.42k
        if (!FileSystem::Instance().Exists(sdks_spec)) {
864
0
          sdks_spec = GetCommandLineToolsLibraryPath();
865
0
          sdks_spec.AppendPathComponent("SDKs");
866
0
        }
867
868
        // We slightly prefer the exact SDK for this machine.  See if it is
869
        // there.
870
871
1.42k
        FileSpec native_sdk_spec = sdks_spec;
872
1.42k
        StreamString native_sdk_name;
873
1.42k
        native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(),
874
1.42k
                               version.getMinor().getValueOr(0));
875
1.42k
        native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
876
877
1.42k
        if (FileSystem::Instance().Exists(native_sdk_spec)) {
878
1.42k
          return native_sdk_spec;
879
1.42k
        }
880
1.42k
      }
881
1.42k
    }
882
1.42k
  }
883
884
0
  return FindSDKInXcodeForModules(sdk_type, sdks_spec);
885
1.42k
}
886
887
std::tuple<llvm::VersionTuple, llvm::StringRef>
888
75
PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
889
75
  llvm::StringRef build;
890
75
  llvm::StringRef version_str;
891
75
  llvm::StringRef build_str;
892
75
  std::tie(version_str, build_str) = dir.split(' ');
893
75
  llvm::VersionTuple version;
894
75
  if (!version.tryParse(version_str) ||
895
75
      
build_str.empty()0
) {
896
75
    if (build_str.consume_front("(")) {
897
4
      size_t pos = build_str.find(')');
898
4
      build = build_str.slice(0, pos);
899
4
    }
900
75
  }
901
902
75
  return std::make_tuple(version, build);
903
75
}
904
905
llvm::Expected<StructuredData::DictionarySP>
906
9
PlatformDarwin::FetchExtendedCrashInformation(Process &process) {
907
9
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
908
909
9
  StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(process);
910
911
9
  if (!annotations || !annotations->GetSize()) {
912
3
    LLDB_LOG(log, "Couldn't extract crash information annotations");
913
3
    return nullptr;
914
3
  }
915
916
6
  StructuredData::DictionarySP extended_crash_info =
917
6
      std::make_shared<StructuredData::Dictionary>();
918
919
6
  extended_crash_info->AddItem("crash-info annotations", annotations);
920
921
6
  return extended_crash_info;
922
9
}
923
924
StructuredData::ArraySP
925
9
PlatformDarwin::ExtractCrashInfoAnnotations(Process &process) {
926
9
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
927
928
9
  ConstString section_name("__crash_info");
929
9
  Target &target = process.GetTarget();
930
9
  StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>();
931
932
360
  for (ModuleSP module : target.GetImages().Modules()) {
933
360
    SectionList *sections = module->GetSectionList();
934
935
360
    std::string module_name = module->GetSpecificationDescription();
936
937
    // The DYDL module is skipped since it's always loaded when running the
938
    // binary.
939
360
    if (module_name == "/usr/lib/dyld")
940
9
      continue;
941
942
351
    if (!sections) {
943
0
      LLDB_LOG(log, "Module {0} doesn't have any section!", module_name);
944
0
      continue;
945
0
    }
946
947
351
    SectionSP crash_info = sections->FindSectionByName(section_name);
948
351
    if (!crash_info) {
949
216
      LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name,
950
216
               section_name);
951
216
      continue;
952
216
    }
953
954
135
    addr_t load_addr = crash_info->GetLoadBaseAddress(&target);
955
956
135
    if (load_addr == LLDB_INVALID_ADDRESS) {
957
0
      LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}",
958
0
               module_name, section_name, load_addr);
959
0
      continue;
960
0
    }
961
962
135
    Status error;
963
135
    CrashInfoAnnotations annotations;
964
135
    size_t expected_size = sizeof(CrashInfoAnnotations);
965
135
    size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations,
966
135
                                                       expected_size, error);
967
968
135
    if (expected_size != bytes_read || error.Fail()) {
969
0
      LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}",
970
0
               section_name, module_name, error);
971
0
      continue;
972
0
    }
973
974
    // initial support added for version 5
975
135
    if (annotations.version < 5) {
976
0
      LLDB_LOG(log,
977
0
               "Annotation version lower than 5 unsupported! Module {0} has "
978
0
               "version {1} instead.",
979
0
               module_name, annotations.version);
980
0
      continue;
981
0
    }
982
983
135
    if (!annotations.message) {
984
123
      LLDB_LOG(log, "No message available for module {0}.", module_name);
985
123
      continue;
986
123
    }
987
988
12
    std::string message;
989
12
    bytes_read =
990
12
        process.ReadCStringFromMemory(annotations.message, message, error);
991
992
12
    if (message.empty() || bytes_read != message.size() || error.Fail()) {
993
0
      LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}",
994
0
               module_name, error);
995
0
      continue;
996
0
    }
997
998
    // Remove trailing newline from message
999
12
    if (message.back() == '\n')
1000
6
      message.pop_back();
1001
1002
12
    if (!annotations.message2)
1003
12
      LLDB_LOG(log, "No message2 available for module {0}.", module_name);
1004
1005
12
    std::string message2;
1006
12
    bytes_read =
1007
12
        process.ReadCStringFromMemory(annotations.message2, message2, error);
1008
1009
12
    if (!message2.empty() && 
bytes_read == message2.size()0
&&
error.Success()0
)
1010
0
      if (message2.back() == '\n')
1011
0
        message2.pop_back();
1012
1013
12
    StructuredData::DictionarySP entry_sp =
1014
12
        std::make_shared<StructuredData::Dictionary>();
1015
1016
12
    entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false));
1017
12
    entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString());
1018
12
    entry_sp->AddStringItem("message", message);
1019
12
    entry_sp->AddStringItem("message2", message2);
1020
12
    entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause);
1021
1022
12
    array_sp->AddItem(entry_sp);
1023
12
  }
1024
1025
9
  return array_sp;
1026
9
}
1027
1028
void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
1029
1.42k
    Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) {
1030
1.42k
  const std::vector<std::string> apple_arguments = {
1031
1.42k
      "-x",       "objective-c++", "-fobjc-arc",
1032
1.42k
      "-fblocks", "-D_ISO646_H",   "-D__ISO646_H",
1033
1.42k
      "-fgnuc-version=4.2.1"};
1034
1035
1.42k
  options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
1036
1037
1.42k
  StreamString minimum_version_option;
1038
1.42k
  bool use_current_os_version = false;
1039
  // If the SDK type is for the host OS, use its version number.
1040
1.42k
  auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); };
1041
1.42k
  switch (sdk_type) {
1042
1.42k
  case XcodeSDK::Type::MacOSX:
1043
1.42k
    use_current_os_version = get_host_os() == llvm::Triple::MacOSX;
1044
1.42k
    break;
1045
0
  case XcodeSDK::Type::iPhoneOS:
1046
0
    use_current_os_version = get_host_os() == llvm::Triple::IOS;
1047
0
    break;
1048
0
  case XcodeSDK::Type::AppleTVOS:
1049
0
    use_current_os_version = get_host_os() == llvm::Triple::TvOS;
1050
0
    break;
1051
0
  case XcodeSDK::Type::watchOS:
1052
0
    use_current_os_version = get_host_os() == llvm::Triple::WatchOS;
1053
0
    break;
1054
0
  default:
1055
0
    break;
1056
1.42k
  }
1057
1058
1.42k
  llvm::VersionTuple version;
1059
1.42k
  if (use_current_os_version)
1060
1.42k
    version = GetOSVersion();
1061
0
  else if (target) {
1062
    // Our OS doesn't match our executable so we need to get the min OS version
1063
    // from the object file
1064
0
    ModuleSP exe_module_sp = target->GetExecutableModule();
1065
0
    if (exe_module_sp) {
1066
0
      ObjectFile *object_file = exe_module_sp->GetObjectFile();
1067
0
      if (object_file)
1068
0
        version = object_file->GetMinimumOSVersion();
1069
0
    }
1070
0
  }
1071
  // Only add the version-min options if we got a version from somewhere
1072
1.42k
  if (!version.empty() && sdk_type != XcodeSDK::Type::Linux) {
1073
1.42k
#define OPTION(PREFIX, NAME, VAR, ...)                                         \
1074
4.19M
  const char *opt_##VAR = NAME;                                                \
1075
4.19M
  (void)opt_##VAR;
1076
1.42k
#include "clang/Driver/Options.inc"
1077
1.42k
#undef OPTION
1078
1.42k
    minimum_version_option << '-';
1079
1.42k
    switch (sdk_type) {
1080
1.42k
    case XcodeSDK::Type::MacOSX:
1081
1.42k
      minimum_version_option << opt_mmacosx_version_min_EQ;
1082
1.42k
      break;
1083
0
    case XcodeSDK::Type::iPhoneSimulator:
1084
0
      minimum_version_option << opt_mios_simulator_version_min_EQ;
1085
0
      break;
1086
0
    case XcodeSDK::Type::iPhoneOS:
1087
0
      minimum_version_option << opt_mios_version_min_EQ;
1088
0
      break;
1089
0
    case XcodeSDK::Type::AppleTVSimulator:
1090
0
      minimum_version_option << opt_mtvos_simulator_version_min_EQ;
1091
0
      break;
1092
0
    case XcodeSDK::Type::AppleTVOS:
1093
0
      minimum_version_option << opt_mtvos_version_min_EQ;
1094
0
      break;
1095
0
    case XcodeSDK::Type::WatchSimulator:
1096
0
      minimum_version_option << opt_mwatchos_simulator_version_min_EQ;
1097
0
      break;
1098
0
    case XcodeSDK::Type::watchOS:
1099
0
      minimum_version_option << opt_mwatchos_version_min_EQ;
1100
0
      break;
1101
0
    case XcodeSDK::Type::bridgeOS:
1102
0
    case XcodeSDK::Type::Linux:
1103
0
    case XcodeSDK::Type::unknown:
1104
0
      if (lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST)) {
1105
0
        XcodeSDK::Info info;
1106
0
        info.type = sdk_type;
1107
0
        LLDB_LOGF(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
1108
0
                  "Clang modules on %s are not supported",
1109
0
                  XcodeSDK::GetCanonicalName(info).c_str());
1110
0
      }
1111
0
      return;
1112
1.42k
    }
1113
1.42k
    minimum_version_option << version.getAsString();
1114
1.42k
    options.emplace_back(std::string(minimum_version_option.GetString()));
1115
1.42k
  }
1116
1117
1.42k
  FileSpec sysroot_spec;
1118
  // Scope for mutex locker below
1119
1.42k
  {
1120
1.42k
    std::lock_guard<std::mutex> guard(m_mutex);
1121
1.42k
    sysroot_spec = GetSDKDirectoryForModules(sdk_type);
1122
1.42k
  }
1123
1124
1.42k
  if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
1125
1.42k
    options.push_back("-isysroot");
1126
1.42k
    options.push_back(sysroot_spec.GetPath());
1127
1.42k
  }
1128
1.42k
}
1129
1130
0
ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) {
1131
0
  if (basename.IsEmpty())
1132
0
    return basename;
1133
1134
0
  StreamString stream;
1135
0
  stream.Printf("lib%s.dylib", basename.GetCString());
1136
0
  return ConstString(stream.GetString());
1137
0
}
1138
1139
1.45k
llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) {
1140
1.45k
  if (process && 
GetPluginName().contains("-simulator")0
) {
1141
0
    lldb_private::ProcessInstanceInfo proc_info;
1142
0
    if (Host::GetProcessInfo(process->GetID(), proc_info)) {
1143
0
      const Environment &env = proc_info.GetEnvironment();
1144
1145
0
      llvm::VersionTuple result;
1146
0
      if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION")))
1147
0
        return result;
1148
1149
0
      std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH");
1150
0
      if (!dyld_root_path.empty()) {
1151
0
        dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
1152
0
        ApplePropertyList system_version_plist(dyld_root_path.c_str());
1153
0
        std::string product_version;
1154
0
        if (system_version_plist.GetValueAsString("ProductVersion",
1155
0
                                                  product_version)) {
1156
0
          if (!result.tryParse(product_version))
1157
0
            return result;
1158
0
        }
1159
0
      }
1160
0
    }
1161
    // For simulator platforms, do NOT call back through
1162
    // Platform::GetOSVersion() as it might call Process::GetHostOSVersion()
1163
    // which we don't want as it will be incorrect
1164
0
    return llvm::VersionTuple();
1165
0
  }
1166
1167
1.45k
  return Platform::GetOSVersion(process);
1168
1.45k
}
1169
1170
0
lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
1171
  // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled
1172
  // in with any executable directories that should be searched.
1173
0
  static std::vector<FileSpec> g_executable_dirs;
1174
1175
  // Find the global list of directories that we will search for executables
1176
  // once so we don't keep doing the work over and over.
1177
0
  static llvm::once_flag g_once_flag;
1178
0
  llvm::call_once(g_once_flag, []() {
1179
1180
    // When locating executables, trust the DEVELOPER_DIR first if it is set
1181
0
    FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory();
1182
0
    if (xcode_contents_dir) {
1183
0
      FileSpec xcode_lldb_resources = xcode_contents_dir;
1184
0
      xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
1185
0
      xcode_lldb_resources.AppendPathComponent("LLDB.framework");
1186
0
      xcode_lldb_resources.AppendPathComponent("Resources");
1187
0
      if (FileSystem::Instance().Exists(xcode_lldb_resources)) {
1188
0
        FileSpec dir;
1189
0
        dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
1190
0
        g_executable_dirs.push_back(dir);
1191
0
      }
1192
0
    }
1193
    // Xcode might not be installed so we also check for the Command Line Tools.
1194
0
    FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath();
1195
0
    if (command_line_tools_dir) {
1196
0
      FileSpec cmd_line_lldb_resources = command_line_tools_dir;
1197
0
      cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks");
1198
0
      cmd_line_lldb_resources.AppendPathComponent("LLDB.framework");
1199
0
      cmd_line_lldb_resources.AppendPathComponent("Resources");
1200
0
      if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) {
1201
0
        FileSpec dir;
1202
0
        dir.GetDirectory().SetCString(
1203
0
            cmd_line_lldb_resources.GetPath().c_str());
1204
0
        g_executable_dirs.push_back(dir);
1205
0
      }
1206
0
    }
1207
0
  });
1208
1209
  // Now search the global list of executable directories for the executable we
1210
  // are looking for
1211
0
  for (const auto &executable_dir : g_executable_dirs) {
1212
0
    FileSpec executable_file;
1213
0
    executable_file.GetDirectory() = executable_dir.GetDirectory();
1214
0
    executable_file.GetFilename().SetCString(basename);
1215
0
    if (FileSystem::Instance().Exists(executable_file))
1216
0
      return executable_file;
1217
0
  }
1218
1219
0
  return FileSpec();
1220
0
}
1221
1222
lldb_private::Status
1223
2.56k
PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) {
1224
  // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if
1225
  // the OS_ACTIVITY_DT_MODE environment variable is set.  (It doesn't require
1226
  // any specific value; rather, it just needs to exist). We will set it here
1227
  // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set.  Xcode
1228
  // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
1229
  // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
1230
  // specifically want it unset.
1231
2.56k
  const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
1232
2.56k
  auto &env_vars = launch_info.GetEnvironment();
1233
2.56k
  if (!env_vars.count(disable_env_var)) {
1234
    // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get
1235
    // os_log and NSLog messages mirrored to the target process stderr.
1236
2.56k
    env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable");
1237
2.56k
  }
1238
1239
  // Let our parent class do the real launching.
1240
2.56k
  return PlatformPOSIX::LaunchProcess(launch_info);
1241
2.56k
}
1242
1243
lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths(
1244
    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
1245
    const FileSpecList *module_search_paths_ptr,
1246
224
    llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
1247
224
  const FileSpec &platform_file = module_spec.GetFileSpec();
1248
  // See if the file is present in any of the module_search_paths_ptr
1249
  // directories.
1250
224
  if (!module_sp && module_search_paths_ptr && platform_file) {
1251
    // create a vector of all the file / directory names in platform_file e.g.
1252
    // this might be
1253
    // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
1254
    //
1255
    // We'll need to look in the module_search_paths_ptr directories for both
1256
    // "UIFoundation" and "UIFoundation.framework" -- most likely the latter
1257
    // will be the one we find there.
1258
1259
221
    FileSpec platform_pull_upart(platform_file);
1260
221
    std::vector<std::string> path_parts;
1261
221
    path_parts.push_back(
1262
221
        platform_pull_upart.GetLastPathComponent().AsCString());
1263
907
    while (platform_pull_upart.RemoveLastPathComponent()) {
1264
686
      ConstString part = platform_pull_upart.GetLastPathComponent();
1265
686
      path_parts.push_back(part.AsCString());
1266
686
    }
1267
221
    const size_t path_parts_size = path_parts.size();
1268
1269
221
    size_t num_module_search_paths = module_search_paths_ptr->GetSize();
1270
250
    for (size_t i = 0; i < num_module_search_paths; 
++i29
) {
1271
31
      Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1272
31
      LLDB_LOGF(
1273
31
          log_verbose,
1274
31
          "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in "
1275
31
          "search-path %s",
1276
31
          module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
1277
      // Create a new FileSpec with this module_search_paths_ptr plus just the
1278
      // filename ("UIFoundation"), then the parent dir plus filename
1279
      // ("UIFoundation.framework/UIFoundation") etc - up to four names (to
1280
      // handle "Foo.framework/Contents/MacOS/Foo")
1281
1282
115
      for (size_t j = 0; j < 4 && 
j < path_parts_size - 1101
;
++j84
) {
1283
86
        FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
1284
1285
        // Add the components backwards.  For
1286
        // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts
1287
        // is
1288
        //   [0] UIFoundation
1289
        //   [1] UIFoundation.framework
1290
        //   [2] PrivateFrameworks
1291
        //
1292
        // and if 'j' is 2, we want to append path_parts[1] and then
1293
        // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the
1294
        // module_search_paths_ptr path.
1295
1296
287
        for (int k = j; k >= 0; 
--k201
) {
1297
201
          path_to_try.AppendPathComponent(path_parts[k]);
1298
201
        }
1299
1300
86
        if (FileSystem::Instance().Exists(path_to_try)) {
1301
2
          ModuleSpec new_module_spec(module_spec);
1302
2
          new_module_spec.GetFileSpec() = path_to_try;
1303
2
          Status new_error(
1304
2
              Platform::GetSharedModule(new_module_spec, process, module_sp,
1305
2
                                        nullptr, old_modules, did_create_ptr));
1306
1307
2
          if (module_sp) {
1308
2
            module_sp->SetPlatformFileSpec(path_to_try);
1309
2
            return new_error;
1310
2
          }
1311
2
        }
1312
86
      }
1313
31
    }
1314
221
  }
1315
222
  return Status();
1316
224
}
1317
1318
std::string PlatformDarwin::FindComponentInPath(llvm::StringRef path,
1319
5
                                                llvm::StringRef component) {
1320
5
  auto begin = llvm::sys::path::begin(path);
1321
5
  auto end = llvm::sys::path::end(path);
1322
21
  for (auto it = begin; it != end; 
++it16
) {
1323
20
    if (it->contains(component)) {
1324
4
      llvm::SmallString<128> buffer;
1325
4
      llvm::sys::path::append(buffer, begin, ++it,
1326
4
                              llvm::sys::path::Style::posix);
1327
4
      return buffer.str().str();
1328
4
    }
1329
20
  }
1330
1
  return {};
1331
5
}
1332
1333
0
FileSpec PlatformDarwin::GetCurrentToolchainDirectory() {
1334
0
  if (FileSpec fspec = HostInfo::GetShlibDir())
1335
0
    return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain"));
1336
0
  return {};
1337
0
}
1338
1339
0
FileSpec PlatformDarwin::GetCurrentCommandLineToolsDirectory() {
1340
0
  if (FileSpec fspec = HostInfo::GetShlibDir())
1341
0
    return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools"));
1342
0
  return {};
1343
0
}