static int
LocateMacOSXFilesUsingDebugSymbols
(
    const ModuleSpec &module_spec,
    FileSpec *out_exec_fspec,   // If non-NULL, try and find the executable
    FileSpec *out_dsym_fspec    // If non-NULL try and find the debug symbol file
)
{
    int items_found = 0;

    if (out_exec_fspec)
        out_exec_fspec->Clear();

    if (out_dsym_fspec)
        out_dsym_fspec->Clear();

#if !defined (__arm__) // No DebugSymbols on the iOS devices

    const UUID *uuid = module_spec.GetUUIDPtr();
    const ArchSpec *arch = module_spec.GetArchitecturePtr();

    if (uuid && uuid->IsValid())
    {
        // Try and locate the dSYM file using DebugSymbols first
        const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
        if (module_uuid != NULL)
        {
            CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes (NULL,
                                                                            module_uuid[0],
                                                                            module_uuid[1],
                                                                            module_uuid[2],
                                                                            module_uuid[3],
                                                                            module_uuid[4],
                                                                            module_uuid[5],
                                                                            module_uuid[6],
                                                                            module_uuid[7],
                                                                            module_uuid[8],
                                                                            module_uuid[9],
                                                                            module_uuid[10],
                                                                            module_uuid[11],
                                                                            module_uuid[12],
                                                                            module_uuid[13],
                                                                            module_uuid[14],
                                                                            module_uuid[15]));

            if (module_uuid_ref.get())
            {
                CFCReleaser<CFURLRef> exec_url;
                const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
                if (exec_fspec)
                {
                    char exec_cf_path[PATH_MAX];
                    if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
                        exec_url.reset(::CFURLCreateFromFileSystemRepresentation (NULL,
                                                                                  (const UInt8 *)exec_cf_path,
                                                                                  strlen(exec_cf_path),
                                                                                  FALSE));
                }

                CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
                char path[PATH_MAX];

                if (dsym_url.get())
                {
                    if (out_dsym_fspec)
                    {
                        if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
                        {
                            out_dsym_fspec->SetFile(path, path[0] == '~');

                            if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory)
                            {
                                *out_dsym_fspec = Symbols::FindSymbolFileInBundle (*out_dsym_fspec, uuid, arch);
                                if (*out_dsym_fspec)
                                    ++items_found;
                            }
                            else
                            {
                                ++items_found;
                            }
                        }
                    }

                    CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));
                    CFDictionaryRef uuid_dict = NULL;
                    if (dict.get())
                    {
                        CFCString uuid_cfstr (uuid->GetAsString().c_str());
                        uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
                        if (uuid_dict)
                        {

                            CFStringRef actual_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSourcePath")));
                            if (actual_src_cfpath)
                            {
                                CFStringRef build_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGBuildSourcePath")));
                                if (build_src_cfpath)
                                {
                                    char actual_src_path[PATH_MAX];
                                    char build_src_path[PATH_MAX];
                                    ::CFStringGetFileSystemRepresentation (actual_src_cfpath, actual_src_path, sizeof(actual_src_path));
                                    ::CFStringGetFileSystemRepresentation (build_src_cfpath, build_src_path, sizeof(build_src_path));
                                    if (actual_src_path[0] == '~')
                                    {
                                        FileSpec resolved_source_path(actual_src_path, true);
                                        resolved_source_path.GetPath(actual_src_path, sizeof(actual_src_path));
                                    }
                                    module_spec.GetSourceMappingList().Append (ConstString(build_src_path), ConstString(actual_src_path), true);
                                }
                            }
                        }
                    }

                    if (out_exec_fspec)
                    {
                        bool success = false;
                        if (uuid_dict)
                        {
                            CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable")));
                            if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path)))
                            {
                                ++items_found;
                                out_exec_fspec->SetFile(path, path[0] == '~');
                                if (out_exec_fspec->Exists())
                                    success = true;
                            }
                        }

                        if (!success)
                        {
                            // No dictionary, check near the dSYM bundle for an executable that matches...
                            if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
                            {
                                char *dsym_extension_pos = ::strstr (path, ".dSYM");
                                if (dsym_extension_pos)
                                {
                                    *dsym_extension_pos = '\0';
                                    FileSpec file_spec (path, true);
                                    switch (file_spec.GetFileType())
                                    {
                                        case FileSpec::eFileTypeDirectory:  // Bundle directory?
                                            {
                                                CFCBundle bundle (path);
                                                CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ());
                                                if (bundle_exe_url.get())
                                                {
                                                    if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1))
                                                    {
                                                        FileSpec bundle_exe_file_spec (path, true);
                                                        
                                                        if (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid))
                                                        {
                                                            ++items_found;
                                                            *out_exec_fspec = bundle_exe_file_spec;
                                                        }
                                                    }
                                                }
                                            }
                                            break;
                                            
                                        case FileSpec::eFileTypePipe:       // Forget pipes
                                        case FileSpec::eFileTypeSocket:     // We can't process socket files
                                        case FileSpec::eFileTypeInvalid:    // File doesn't exist...
                                            break;

                                        case FileSpec::eFileTypeUnknown:
                                        case FileSpec::eFileTypeRegular:
                                        case FileSpec::eFileTypeSymbolicLink:
                                        case FileSpec::eFileTypeOther:
                                            if (FileAtPathContainsArchAndUUID (file_spec, arch, uuid))
                                            {
                                                ++items_found;
                                                *out_exec_fspec = file_spec;
                                            }
                                            break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
#endif // #if !defined (__arm__)

    return items_found;
}
Error
PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec,
                                            lldb::ModuleSP &exe_module_sp,
                                            const FileSpecList *module_search_paths_ptr)
{
    // copied from PlatformRemoteiOS

    Error error;
    // Nothing special to do here, just use the actual file and architecture

    ModuleSpec resolved_module_spec(module_spec);

    // Resolve any executable within an apk on Android?
    //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());

    if (resolved_module_spec.GetFileSpec().Exists() ||
        module_spec.GetUUID().IsValid())
    {
        if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
        {
            error = ModuleList::GetSharedModule (resolved_module_spec,
                                                 exe_module_sp,
                                                 module_search_paths_ptr,
                                                 NULL,
                                                 NULL);

            if (exe_module_sp && exe_module_sp->GetObjectFile())
                return error;
            exe_module_sp.reset();
        }
        // No valid architecture was specified or the exact arch wasn't
        // found so ask the platform for the architectures that we should be
        // using (in the correct order) and see if we can find a match that way
        StreamString arch_names;
        for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
        {
            error = ModuleList::GetSharedModule (resolved_module_spec,
                                                 exe_module_sp,
                                                 module_search_paths_ptr,
                                                 NULL,
                                                 NULL);
            // Did we find an executable using one of the
            if (error.Success())
            {
                if (exe_module_sp && exe_module_sp->GetObjectFile())
                    break;
                else
                    error.SetErrorToGenericError();
            }

            if (idx > 0)
                arch_names.PutCString (", ");
            arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
        }

        if (error.Fail() || !exe_module_sp)
        {
            if (resolved_module_spec.GetFileSpec().Readable())
            {
                error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
                                                resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                GetPluginName().GetCString(),
                                                arch_names.GetString().c_str());
            }
            else
            {
                error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
            }
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("'%s' does not exist",
                                        resolved_module_spec.GetFileSpec().GetPath().c_str());
    }

    return error;
}
Beispiel #3
0
static bool
LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec)
{
    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
    if (exec_fspec)
    {
        char path[PATH_MAX];
        if (exec_fspec->GetPath(path, sizeof(path)))
        {
            // Make sure the module isn't already just a dSYM file...
            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)
            {
                size_t obj_file_path_length = strlen(path);
                ::strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);
                ::strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);

                dsym_fspec.SetFile(path, false);

                ModuleSpecList module_specs;
                ModuleSpec matched_module_spec;
                if (dsym_fspec.Exists() &&
                    FileAtPathContainsArchAndUUID(dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
                {
                    return true;
                }
                else
                {
                    path[obj_file_path_length] = '\0';

                    char *last_dot = strrchr(path, '.');
                    while (last_dot != NULL && last_dot[0])
                    {
                        char *next_slash = strchr(last_dot, '/');
                        if (next_slash != NULL)
                        {
                            *next_slash = '\0';
                            ::strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);
                            ::strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);
                            dsym_fspec.SetFile(path, false);
                            if (dsym_fspec.Exists() &&
                                FileAtPathContainsArchAndUUID(dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
                            {
                                return true;
                            }
                            else
                            {
                                *last_dot = '\0';
                                char *prev_slash = strrchr(path, '/');
                                if (prev_slash != NULL)
                                    *prev_slash = '\0';
                                else
                                    break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
    }
    dsym_fspec.Clear();
    return false;
}
Beispiel #4
0
Error
ModuleCache::GetAndPut (const FileSpec &root_dir_spec,
                        const char *hostname,
                        const ModuleSpec &module_spec,
                        const ModuleDownloader &module_downloader,
                        const SymfileDownloader &symfile_downloader,
                        lldb::ModuleSP &cached_module_sp,
                        bool *did_create_ptr)
{
    const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ());
    auto error = MakeDirectory (module_spec_dir);
    if (error.Fail ())
        return error;

    // Open lock file.
    const auto lock_file_spec = JoinPath (module_spec_dir, kLockFileName);
    File lock_file (lock_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec);
    if (!lock_file)
    {
        error.SetErrorToErrno ();
        return Error("Failed to open lock file %s: %s", lock_file_spec.GetPath ().c_str (), error.AsCString ());
    }
    LockFile lock (lock_file.GetDescriptor ());
    error = lock.WriteLock (0, 1);
    if (error.Fail ())
        return Error("Failed to lock file %s:%s", lock_file_spec.GetPath ().c_str (), error.AsCString ());

    // Check local cache for a module.
    error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
    if (error.Success ())
        return error;

    const auto tmp_download_file_spec = JoinPath (module_spec_dir, kTempFileName);
    error = module_downloader (module_spec, tmp_download_file_spec);
    llvm::FileRemover tmp_file_remover (tmp_download_file_spec.GetPath ().c_str ());
    if (error.Fail ())
        return Error("Failed to download module: %s", error.AsCString ());

    // Put downloaded file into local module cache.
    error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec, module_spec.GetFileSpec ());
    if (error.Fail ())
        return Error ("Failed to put module into cache: %s", error.AsCString ());

    tmp_file_remover.releaseFile ();
    error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
    if (error.Fail ())
        return error;

    // Fetching a symbol file for the module
    const auto tmp_download_sym_file_spec = JoinPath (module_spec_dir, kTempSymFileName);
    error = symfile_downloader (cached_module_sp, tmp_download_sym_file_spec);
    llvm::FileRemover tmp_symfile_remover (tmp_download_sym_file_spec.GetPath ().c_str ());
    if (error.Fail ())
        // Failed to download a symfile but fetching the module was successful. The module might
        // contain the neccessary symbols and the debugging is also possible without a symfile.
        return Error ();

    FileSpec symfile_spec = GetSymbolFileSpec (cached_module_sp->GetFileSpec ());
    error = Put (root_dir_spec, hostname, module_spec, tmp_download_sym_file_spec, symfile_spec);
    if (error.Fail ())
        return Error ("Failed to put symbol file into cache: %s", error.AsCString ());
    
    tmp_symfile_remover.releaseFile();

    cached_module_sp->SetSymbolFileFileSpec (symfile_spec);
    return Error ();
}
Beispiel #5
0
Error
ModuleList::GetSharedModule(const ModuleSpec &module_spec,
                            ModuleSP &module_sp,
                            const FileSpecList *module_search_paths_ptr,
                            ModuleSP *old_module_sp_ptr,
                            bool *did_create_ptr,
                            bool always_create)
{
    ModuleList &shared_module_list = GetSharedModuleList ();
    Mutex::Locker locker(shared_module_list.m_modules_mutex);
    char path[PATH_MAX];

    Error error;

    module_sp.reset();

    if (did_create_ptr)
        *did_create_ptr = false;
    if (old_module_sp_ptr)
        old_module_sp_ptr->reset();

    const UUID *uuid_ptr = module_spec.GetUUIDPtr();
    const FileSpec &module_file_spec = module_spec.GetFileSpec();
    const ArchSpec &arch = module_spec.GetArchitecture();

    // Make sure no one else can try and get or create a module while this
    // function is actively working on it by doing an extra lock on the
    // global mutex list.
    if (!always_create)
    {
        ModuleList matching_module_list;
        const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
        if (num_matching_modules > 0)
        {
            for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
            {
                module_sp = matching_module_list.GetModuleAtIndex(module_idx);

                // Make sure the file for the module hasn't been modified
                if (module_sp->FileHasChanged())
                {
                    if (old_module_sp_ptr && !*old_module_sp_ptr)
                        *old_module_sp_ptr = module_sp;

                    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES));
                    if (log != nullptr)
                        log->Printf("module changed: %p, removing from global module list",
                                    static_cast<void*>(module_sp.get()));

                    shared_module_list.Remove (module_sp);
                    module_sp.reset();
                }
                else
                {
                    // The module matches and the module was not modified from
                    // when it was last loaded.
                    return error;
                }
            }
        }
    }

    if (module_sp)
        return error;

    module_sp.reset (new Module (module_spec));
    // Make sure there are a module and an object file since we can specify
    // a valid file path with an architecture that might not be in that file.
    // By getting the object file we can guarantee that the architecture matches
    if (module_sp->GetObjectFile())
    {
        // If we get in here we got the correct arch, now we just need
        // to verify the UUID if one was given
        if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
        {
            module_sp.reset();
        }
        else
        {
            if (module_sp->GetObjectFile() && module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
            {
                module_sp.reset();
            }
            else
            {
                if (did_create_ptr)
                {
                    *did_create_ptr = true;
                }

                shared_module_list.ReplaceEquivalent(module_sp);
                return error;
            }
        }
    }
    else
    {
        module_sp.reset();
    }

    if (module_search_paths_ptr)
    {
        const auto num_directories = module_search_paths_ptr->GetSize();
        for (size_t idx = 0; idx < num_directories; ++idx)
        {
            auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
            if (!search_path_spec.ResolvePath())
                continue;
            if (!search_path_spec.Exists() || !search_path_spec.IsDirectory())
                continue;
            search_path_spec.AppendPathComponent(module_spec.GetFileSpec().GetFilename().AsCString());
            if (!search_path_spec.Exists())
                continue;

            auto resolved_module_spec(module_spec);
            resolved_module_spec.GetFileSpec() = search_path_spec;
            module_sp.reset (new Module (resolved_module_spec));
            if (module_sp->GetObjectFile())
            {
                // If we get in here we got the correct arch, now we just need
                // to verify the UUID if one was given
                if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
                {
                    module_sp.reset();
                }
                else
                {
                    if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
                    {
                        module_sp.reset();
                    }
                    else
                    {
                        if (did_create_ptr)
                            *did_create_ptr = true;
    
                        shared_module_list.ReplaceEquivalent(module_sp);
                        return Error();
                    }
                }
            }
            else
            {
                module_sp.reset();
            }
        }
    }

    // Either the file didn't exist where at the path, or no path was given, so
    // we now have to use more extreme measures to try and find the appropriate
    // module.

    // Fixup the incoming path in case the path points to a valid file, yet
    // the arch or UUID (if one was passed in) don't match.
    ModuleSpec located_binary_modulespec = Symbols::LocateExecutableObjectFile (module_spec);

    // Don't look for the file if it appears to be the same one we already
    // checked for above...
    if (located_binary_modulespec.GetFileSpec() != module_file_spec)
    {
        if (!located_binary_modulespec.GetFileSpec().Exists())
        {
            located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
            if (path[0] == '\0')
                module_file_spec.GetPath(path, sizeof(path));
            // How can this check ever be true? This branch it is false, and we haven't modified file_spec.
            if (located_binary_modulespec.GetFileSpec().Exists())
            {
                std::string uuid_str;
                if (uuid_ptr && uuid_ptr->IsValid())
                    uuid_str = uuid_ptr->GetAsString();

                if (arch.IsValid())
                {
                    if (!uuid_str.empty())
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_str.c_str());
                    else
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
                }
            }
            else
            {
                error.SetErrorStringWithFormat("'%s' does not exist", path);
            }
            if (error.Fail())
                module_sp.reset();
            return error;
        }

        // Make sure no one else can try and get or create a module while this
        // function is actively working on it by doing an extra lock on the
        // global mutex list.
        ModuleSpec platform_module_spec(module_spec);
        platform_module_spec.GetFileSpec() = located_binary_modulespec.GetFileSpec();
        platform_module_spec.GetPlatformFileSpec() = located_binary_modulespec.GetFileSpec();
        platform_module_spec.GetSymbolFileSpec() = located_binary_modulespec.GetSymbolFileSpec();
        ModuleList matching_module_list;
        if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0)
        {
            module_sp = matching_module_list.GetModuleAtIndex(0);

            // If we didn't have a UUID in mind when looking for the object file,
            // then we should make sure the modification time hasn't changed!
            if (platform_module_spec.GetUUIDPtr() == nullptr)
            {
                TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime());
                if (file_spec_mod_time.IsValid())
                {
                    if (file_spec_mod_time != module_sp->GetModificationTime())
                    {
                        if (old_module_sp_ptr)
                            *old_module_sp_ptr = module_sp;
                        shared_module_list.Remove (module_sp);
                        module_sp.reset();
                    }
                }
            }
        }

        if (!module_sp)
        {
            module_sp.reset (new Module (platform_module_spec));
            // Make sure there are a module and an object file since we can specify
            // a valid file path with an architecture that might not be in that file.
            // By getting the object file we can guarantee that the architecture matches
            if (module_sp && module_sp->GetObjectFile())
            {
                if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
                {
                    module_sp.reset();
                }
                else
                {
                    if (did_create_ptr)
                        *did_create_ptr = true;

                    shared_module_list.ReplaceEquivalent(module_sp);
                }
            }
            else
            {
                located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));

                if (located_binary_modulespec.GetFileSpec())
                {
                    if (arch.IsValid())
                        error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
                    else
                        error.SetErrorStringWithFormat("unable to open '%s'", path);
                }
                else
                {
                    std::string uuid_str;
                    if (uuid_ptr && uuid_ptr->IsValid())
                        uuid_str = uuid_ptr->GetAsString();

                    if (!uuid_str.empty())
                        error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_str.c_str());
                    else
                        error.SetErrorStringWithFormat("cannot locate a module");
                }
            }
        }
    }

    return error;
}
Beispiel #6
0
static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
                                              FileSpec &dsym_fspec) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
  if (exec_fspec) {
    char path[PATH_MAX];
    if (exec_fspec->GetPath(path, sizeof(path))) {
      // Make sure the module isn't already just a dSYM file...
      if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) {
        if (log) {
          if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) {
            log->Printf(
                "Searching for dSYM bundle next to executable %s, UUID %s",
                path, module_spec.GetUUIDPtr()->GetAsString().c_str());
          } else {
            log->Printf("Searching for dSYM bundle next to executable %s",
                        path);
          }
        }
        ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
                  sizeof(path) - strlen(path) - 1);
        ::strncat(path, exec_fspec->GetFilename().AsCString(),
                  sizeof(path) - strlen(path) - 1);

        dsym_fspec.SetFile(path, false);

        ModuleSpecList module_specs;
        ModuleSpec matched_module_spec;
        if (dsym_fspec.Exists() &&
            FileAtPathContainsArchAndUUID(dsym_fspec,
                                          module_spec.GetArchitecturePtr(),
                                          module_spec.GetUUIDPtr())) {
          if (log) {
            log->Printf("dSYM with matching UUID & arch found at %s", path);
          }
          return true;
        } else {
          FileSpec parent_dirs = exec_fspec;

          // Remove the binary name from the FileSpec
          parent_dirs.RemoveLastPathComponent();

          // Add a ".dSYM" name to each directory component of the path,
          // stripping off components.  e.g. we may have a binary like
          // /S/L/F/Foundation.framework/Versions/A/Foundation
          // and
          // /S/L/F/Foundation.framework.dSYM
          //
          // so we'll need to start with /S/L/F/Foundation.framework/Versions/A,
          // add the .dSYM part to the "A", and if that doesn't exist, strip off
          // the "A" and try it again with "Versions", etc., until we find a
          // dSYM bundle or we've stripped off enough path components that
          // there's no need to continue.

          for (int i = 0; i < 4; i++) {
            // Does this part of the path have a "." character - could it be a
            // bundle's top level directory?
            const char *fn = parent_dirs.GetFilename().AsCString();
            if (fn == nullptr)
              break;
            if (::strchr(fn, '.') != nullptr) {
              dsym_fspec = parent_dirs;
              dsym_fspec.RemoveLastPathComponent();

              // If the current directory name is "Foundation.framework", see if
              // "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation"
              // exists & has the right uuid.
              std::string dsym_fn = fn;
              dsym_fn += ".dSYM";
              dsym_fspec.AppendPathComponent(dsym_fn.c_str());
              dsym_fspec.AppendPathComponent("Contents");
              dsym_fspec.AppendPathComponent("Resources");
              dsym_fspec.AppendPathComponent("DWARF");
              dsym_fspec.AppendPathComponent(
                  exec_fspec->GetFilename().AsCString());
              if (dsym_fspec.Exists() &&
                  FileAtPathContainsArchAndUUID(
                      dsym_fspec, module_spec.GetArchitecturePtr(),
                      module_spec.GetUUIDPtr())) {
                if (log) {
                  log->Printf("dSYM with matching UUID & arch found at %s",
                              dsym_fspec.GetPath().c_str());
                }
                return true;
              }
            }
            parent_dirs.RemoveLastPathComponent();
          }
        }
      }
    }
  }
  dsym_fspec.Clear();
  return false;
}
Beispiel #7
0
FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
  FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
  if (symbol_file_spec.IsAbsolute() && symbol_file_spec.Exists())
    return symbol_file_spec;

  const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
  if (symbol_filename && symbol_filename[0]) {
    FileSpecList debug_file_search_paths(
        Target::GetDefaultDebugFileSearchPaths());

    // Add module directory.
    const ConstString &file_dir = module_spec.GetFileSpec().GetDirectory();
    debug_file_search_paths.AppendIfUnique(
        FileSpec(file_dir.AsCString("."), true));

    // Add current working directory.
    debug_file_search_paths.AppendIfUnique(FileSpec(".", true));

#ifndef LLVM_ON_WIN32
    // Add /usr/lib/debug directory.
    debug_file_search_paths.AppendIfUnique(FileSpec("/usr/lib/debug", true));
#endif // LLVM_ON_WIN32

    std::string uuid_str;
    const UUID &module_uuid = module_spec.GetUUID();
    if (module_uuid.IsValid()) {
      // Some debug files are stored in the .build-id directory like this:
      //   /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
      uuid_str = module_uuid.GetAsString("");
      uuid_str.insert(2, 1, '/');
      uuid_str = uuid_str + ".debug";
    }

    size_t num_directories = debug_file_search_paths.GetSize();
    for (size_t idx = 0; idx < num_directories; ++idx) {
      FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
      dirspec.ResolvePath();
      if (!dirspec.Exists() || !dirspec.IsDirectory())
        continue;

      std::vector<std::string> files;
      std::string dirname = dirspec.GetPath();

      files.push_back(dirname + "/" + symbol_filename);
      files.push_back(dirname + "/.debug/" + symbol_filename);
      files.push_back(dirname + "/.build-id/" + uuid_str);

      // Some debug files may stored in the module directory like this:
      //   /usr/lib/debug/usr/lib/library.so.debug
      if (!file_dir.IsEmpty())
        files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename);

      const uint32_t num_files = files.size();
      for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
        const std::string &filename = files[idx_file];
        FileSpec file_spec(filename, true);

        if (llvm::sys::fs::equivalent(file_spec.GetPath(),
                                      module_spec.GetFileSpec().GetPath()))
          continue;

        if (file_spec.Exists()) {
          lldb_private::ModuleSpecList specs;
          const size_t num_specs =
              ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
          assert(num_specs <= 1 &&
                 "Symbol Vendor supports only a single architecture");
          if (num_specs == 1) {
            ModuleSpec mspec;
            if (specs.GetModuleSpecAtIndex(0, mspec)) {
              if (mspec.GetUUID() == module_uuid)
                return file_spec;
            }
          }
        }
      }
    }
  }

  return LocateExecutableSymbolFileDsym(module_spec);
}
Beispiel #8
0
Error ModuleCache::GetAndPut(const FileSpec &root_dir_spec,
                             const char *hostname,
                             const ModuleSpec &module_spec,
                             const ModuleDownloader &module_downloader,
                             const SymfileDownloader &symfile_downloader,
                             lldb::ModuleSP &cached_module_sp,
                             bool *did_create_ptr) {
  const auto module_spec_dir =
      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
  auto error = MakeDirectory(module_spec_dir);
  if (error.Fail())
    return error;

  ModuleLock lock(root_dir_spec, module_spec.GetUUID(), error);
  if (error.Fail())
    return Error("Failed to lock module %s: %s",
                 module_spec.GetUUID().GetAsString().c_str(),
                 error.AsCString());

  const auto escaped_hostname(GetEscapedHostname(hostname));
  // Check local cache for a module.
  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
              cached_module_sp, did_create_ptr);
  if (error.Success())
    return error;

  const auto tmp_download_file_spec = JoinPath(module_spec_dir, kTempFileName);
  error = module_downloader(module_spec, tmp_download_file_spec);
  llvm::FileRemover tmp_file_remover(tmp_download_file_spec.GetPath().c_str());
  if (error.Fail())
    return Error("Failed to download module: %s", error.AsCString());

  // Put downloaded file into local module cache.
  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
              tmp_download_file_spec, module_spec.GetFileSpec());
  if (error.Fail())
    return Error("Failed to put module into cache: %s", error.AsCString());

  tmp_file_remover.releaseFile();
  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
              cached_module_sp, did_create_ptr);
  if (error.Fail())
    return error;

  // Fetching a symbol file for the module
  const auto tmp_download_sym_file_spec =
      JoinPath(module_spec_dir, kTempSymFileName);
  error = symfile_downloader(cached_module_sp, tmp_download_sym_file_spec);
  llvm::FileRemover tmp_symfile_remover(
      tmp_download_sym_file_spec.GetPath().c_str());
  if (error.Fail())
    // Failed to download a symfile but fetching the module was successful. The
    // module might
    // contain the necessary symbols and the debugging is also possible without
    // a symfile.
    return Error();

  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
              tmp_download_sym_file_spec,
              GetSymbolFileSpec(module_spec.GetFileSpec()));
  if (error.Fail())
    return Error("Failed to put symbol file into cache: %s", error.AsCString());

  tmp_symfile_remover.releaseFile();

  FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec());
  cached_module_sp->SetSymbolFileFileSpec(symfile_spec);
  return Error();
}
Beispiel #9
0
Error
PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec,
                                    Process* process,
                                    ModuleSP &module_sp,
                                    const FileSpecList *module_search_paths_ptr,
                                    ModuleSP *old_module_sp_ptr,
                                    bool *did_create_ptr)
{
    // For iOS, the SDK files are all cached locally on the host
    // system. So first we ask for the file in the cached SDK,
    // then we attempt to get a shared module for the right architecture
    // with the right UUID.
    const FileSpec &platform_file = module_spec.GetFileSpec();

    Error error;
    char platform_file_path[PATH_MAX];
    
    if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
    {
        ModuleSpec platform_module_spec(module_spec);

        UpdateSDKDirectoryInfosIfNeeded();

        const uint32_t num_sdk_infos = m_sdk_directory_infos.size();

        // If we are connected we migth be able to correctly deduce the SDK directory
        // using the OS build.
        const uint32_t connected_sdk_idx = GetConnectedSDKIndex ();
        if (connected_sdk_idx < num_sdk_infos)
        {
            if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec()))
            {
                module_sp.reset();
                error = ResolveExecutable (platform_module_spec,
                                           module_sp,
                                           NULL);
                if (module_sp)
                {
                    m_last_module_sdk_idx = connected_sdk_idx;
                    error.Clear();
                    return error;
                }
            }
        }

        // Try the last SDK index if it is set as most files from an SDK
        // will tend to be valid in that same SDK.
        if (m_last_module_sdk_idx < num_sdk_infos)
        {
            if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec()))
            {
                module_sp.reset();
                error = ResolveExecutable (platform_module_spec,
                                           module_sp,
                                           NULL);
                if (module_sp)
                {
                    error.Clear();
                    return error;
                }
            }
        }
        
        // First try for an exact match of major, minor and update:
        // If a particalar SDK version was specified via --version or --build, look for a match on disk.
        const SDKDirectoryInfo *current_sdk_info = GetSDKDirectoryForCurrentOSVersion();
        const uint32_t current_sdk_idx = GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
        if (current_sdk_idx < num_sdk_infos && current_sdk_idx != m_last_module_sdk_idx)
        {
            if (GetFileInSDK (platform_file_path, current_sdk_idx, platform_module_spec.GetFileSpec()))
            {
                module_sp.reset();
                error = ResolveExecutable (platform_module_spec,
                                           module_sp,
                                           NULL);
                if (module_sp)
                {
                    m_last_module_sdk_idx = current_sdk_idx;
                    error.Clear();
                    return error;
                }
            }
        }

        // Second try all SDKs that were found.
        for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
        {
            if (m_last_module_sdk_idx == sdk_idx)
            {
                // Skip the last module SDK index if we already searched
                // it above
                continue;
            }
            if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec()))
            {
                //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
                
                error = ResolveExecutable (platform_module_spec, module_sp, NULL);
                if (module_sp)
                {
                    // Remember the index of the last SDK that we found a file
                    // in in case the wrong SDK was selected.
                    m_last_module_sdk_idx = sdk_idx;
                    error.Clear();
                    return error;
                }
            }
        }
    }
    // Not the module we are looking for... Nothing to see here...
    module_sp.reset();

    // This may not be an SDK-related module.  Try whether we can bring in the thing to our local cache.
    error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
    if (error.Success())
        return error;

    const bool always_create = false;
    error = ModuleList::GetSharedModule (module_spec,
                                         module_sp,
                                         module_search_paths_ptr,
                                         old_module_sp_ptr,
                                         did_create_ptr,
                                         always_create);

    if (module_sp)
        module_sp->SetPlatformFileSpec(platform_file);

    return error;
}
Beispiel #10
0
FileSpec
PlatformDarwin::LocateExecutableScriptingResource (const ModuleSpec &module_spec)
{
    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
    const ArchSpec *arch = module_spec.GetArchitecturePtr();
    const UUID *uuid = module_spec.GetUUIDPtr();
    
    const char* module_directory = exec_fspec->GetDirectory().GetCString();

    // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
    // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
    // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
    // which should be stripped while leaving "this.binary.file" as-is.
    const char* module_basename = exec_fspec->GetFileNameStrippingExtension().GetCString();
    
    if (!module_directory || !module_basename)
        return FileSpec();
    
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "LocateExecutableScriptingResource (file = %s, arch = %s, uuid = %p)",
                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
                        arch ? arch->GetArchitectureName() : "<NULL>",
                        uuid);
    
    // FIXME: for Python, we cannot allow dots in the middle of the filenames we import.
    // Theoretically, different scripting languages may have different sets of
    // forbidden tokens in filenames, and that should be dealt with by each ScriptInterpreter.
    // For now, we just replace dots with underscores, but if we ever support anything
    // other than Python we will need to rework this
    std::auto_ptr<char> module_basename_fixed_ap(new char[strlen(module_basename)+1]);
    char* module_basename_fixed = module_basename_fixed_ap.get();
    strcpy(module_basename_fixed, module_basename);
    while (*module_basename_fixed)
    {
        if (*module_basename_fixed == '.')
            *module_basename_fixed = '_';
        module_basename_fixed++;
    }
    module_basename_fixed = module_basename_fixed_ap.get();
    
    FileSpec symbol_fspec (Symbols::LocateExecutableSymbolFile(module_spec));
    
    FileSpec script_fspec;
    
    StreamString path_string;
    
    if (symbol_fspec && symbol_fspec.Exists())
    {
        // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
        // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
        path_string.Printf("%s/../Python/%s.py",symbol_fspec.GetDirectory().AsCString(""),module_basename_fixed);
        script_fspec.SetFile(path_string.GetData(), true);
        if (!script_fspec.Exists())
            script_fspec.Clear();
    }
    
    // no symbols or symbols did not have a scripting resource
    if (!symbol_fspec || !script_fspec)
    {
        path_string.Clear();
        path_string.Printf("%s.framework",module_basename);
        if (module_directory && strstr(module_directory, path_string.GetData()))
        {
            // we are going to be in foo.framework/Versions/X/foo
            path_string.Clear();
            // let's go to foo.framework/Versions/X/Resources/Python/foo.py
            path_string.Printf("%s/Resources/Python/%s.py",module_directory,module_basename_fixed);
            script_fspec.SetFile(path_string.GetData(), true);
            if (!script_fspec.Exists())
                script_fspec.Clear();
        }
    }
    
    return script_fspec;
}
Beispiel #11
0
Error
PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
                                 ModuleSP &module_sp,
                                 const FileSpecList *module_search_paths_ptr,
                                 ModuleSP *old_module_sp_ptr,
                                 bool *did_create_ptr)
{
    Error error;
    module_sp.reset();
    
    if (IsRemote())
    {
        // If we have a remote platform always, let it try and locate
        // the shared module first.
        if (m_remote_platform_sp)
        {
            error = m_remote_platform_sp->GetSharedModule (module_spec,
                                                           module_sp,
                                                           module_search_paths_ptr,
                                                           old_module_sp_ptr,
                                                           did_create_ptr);
        }
    }
    
    if (!module_sp)
    {
        // Fall back to the local platform and find the file locally
        error = Platform::GetSharedModule (module_spec,
                                           module_sp,
                                           module_search_paths_ptr,
                                           old_module_sp_ptr,
                                           did_create_ptr);
        
        const FileSpec &platform_file = module_spec.GetFileSpec();
        if (!module_sp && module_search_paths_ptr && platform_file)
        {
            // We can try to pull off part of the file path up to the bundle
            // directory level and try any module search paths...
            FileSpec bundle_directory;
            if (Host::GetBundleDirectory (platform_file, bundle_directory))
            {
                char platform_path[PATH_MAX];
                char bundle_dir[PATH_MAX];
                platform_file.GetPath (platform_path, sizeof(platform_path));
                const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
                char new_path[PATH_MAX];
                size_t num_module_search_paths = module_search_paths_ptr->GetSize();
                for (size_t i=0; i<num_module_search_paths; ++i)
                {
                    const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
                    if (search_path_len < sizeof(new_path))
                    {
                        snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
                        FileSpec new_file_spec (new_path, false);
                        if (new_file_spec.Exists())
                        {
                            ModuleSpec new_module_spec (module_spec);
                            new_module_spec.GetFileSpec() = new_file_spec;
                            Error new_error (Platform::GetSharedModule (new_module_spec,
                                                                        module_sp,
                                                                        NULL,
                                                                        old_module_sp_ptr,
                                                                        did_create_ptr));
                            
                            if (module_sp)
                            {
                                module_sp->SetPlatformFileSpec(new_file_spec);
                                return new_error;
                            }
                        }
                    }
                }
            }
        }
    }
    if (module_sp)
        module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
    return error;
}
Beispiel #12
0
Error
PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec,
                                    ModuleSP &module_sp,
                                    const FileSpecList *module_search_paths_ptr,
                                    ModuleSP *old_module_sp_ptr,
                                    bool *did_create_ptr)
{
    // For iOS, the SDK files are all cached locally on the host
    // system. So first we ask for the file in the cached SDK,
    // then we attempt to get a shared module for the right architecture
    // with the right UUID.
    const FileSpec &platform_file = module_spec.GetFileSpec();

    FileSpec local_file;
    const UUID *module_uuid_ptr = module_spec.GetUUIDPtr();
    Error error (GetSymbolFile (platform_file, module_uuid_ptr, local_file));
    if (error.Success())
    {
        error = ResolveExecutable (local_file, module_spec.GetArchitecture(), module_sp, NULL);
        if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
        {
            //printf ("found in user specified SDK\n");
            error.Clear();
            return error;
        }

        char platform_file_path[PATH_MAX];
        if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
        {
            FileSpec local_file;
            const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
            // Try the last SDK index if it is set as most files from an SDK
            // will tend to be valid in that same SDK.
            if (m_last_module_sdk_idx < num_sdk_infos)
            {
                if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, local_file))
                {
                    //printf ("sdk[%u] last: '%s'\n", m_last_module_sdk_idx, local_file.GetPath().c_str());
                    module_sp.reset();
                    error = ResolveExecutable (local_file,
                                               module_spec.GetArchitecture(),
                                               module_sp,
                                               NULL);
                    if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
                    {
                        //printf ("sdk[%u] last found\n", m_last_module_sdk_idx);
                        error.Clear();
                        return error;
                    }
                }
            }
            
            // First try for an exact match of major, minor and update
            for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
            {
                if (m_last_module_sdk_idx == sdk_idx)
                {
                    // Skip the last module SDK index if we already searched
                    // it above
                    continue;
                }
                if (GetFileInSDK (platform_file_path, sdk_idx, local_file))
                {
                    //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
                    
                    error = ResolveExecutable (local_file,
                                               module_spec.GetArchitecture(),
                                               module_sp,
                                               NULL);
                    if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
                    {
                        // Remember the index of the last SDK that we found a file
                        // in in case the wrong SDK was selected.
                        m_last_module_sdk_idx = sdk_idx;
                        //printf ("sdk[%u]: found (setting last to %u)\n", sdk_idx, m_last_module_sdk_idx);
                        error.Clear();
                        return error;
                    }
                }
            }
        }
        // Not the module we are looking for... Nothing to see here...
        module_sp.reset();
    }
    else
    {
        // This may not be an SDK-related module.  Try whether we can bring in the thing to our local cache.
        error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
        if (error.Success())
            return error;
        else
            error.Clear(); // Clear the error and fall-through.
    }

    const bool always_create = false;
    error = ModuleList::GetSharedModule (module_spec, 
                                         module_sp,
                                         module_search_paths_ptr,
                                         old_module_sp_ptr,
                                         did_create_ptr,
                                         always_create);

    if (module_sp)
        module_sp->SetPlatformFileSpec(platform_file);

    return error;
}
Error
PlatformDarwinKernel::GetSharedModule (const ModuleSpec &module_spec,
                                       Process *process,
                                       ModuleSP &module_sp,
                                       const FileSpecList *module_search_paths_ptr,
                                       ModuleSP *old_module_sp_ptr,
                                       bool *did_create_ptr)
{
    Error error;
    module_sp.reset();
    const FileSpec &platform_file = module_spec.GetFileSpec();

    // Treat the file's path as a kext bundle ID (e.g. "com.apple.driver.AppleIRController") and search our kext index.
    std::string kext_bundle_id = platform_file.GetPath();
    if (!kext_bundle_id.empty())
    {
        ConstString kext_bundle_cs(kext_bundle_id.c_str());
        if (m_name_to_kext_path_map.count(kext_bundle_cs) > 0)
        {
            for (BundleIDToKextIterator it = m_name_to_kext_path_map.begin (); it != m_name_to_kext_path_map.end (); ++it)
            {
                if (it->first == kext_bundle_cs)
                {
                    error = ExamineKextForMatchingUUID (it->second, module_spec.GetUUID(), module_spec.GetArchitecture(), module_sp);
                    if (module_sp.get())
                    {
                        return error;
                    }
                }
            }
        }
    }

    if (kext_bundle_id.compare("mach_kernel") == 0 && module_spec.GetUUID().IsValid())
    {
        for (auto possible_kernel : m_kernel_binaries)
        {
            if (possible_kernel.Exists())
            {
                ModuleSpec kern_spec (possible_kernel);
                kern_spec.GetUUID() = module_spec.GetUUID();
                ModuleSP module_sp (new Module (kern_spec));
                if (module_sp && module_sp->GetObjectFile() && module_sp->MatchesModuleSpec (kern_spec))
                {
                    // module_sp is an actual kernel binary we want to add.
                    if (process)
                    {
                        process->GetTarget().GetImages().AppendIfNeeded (module_sp);
                        error.Clear();
                        return error;
                    }
                    else
                    {
                        error = ModuleList::GetSharedModule (kern_spec, module_sp, NULL, NULL, NULL);
                        if (module_sp 
                            && module_sp->GetObjectFile() 
                            && module_sp->GetObjectFile()->GetType() != ObjectFile::Type::eTypeCoreFile)
                        {
                            return error;
                        }
                        module_sp.reset();
                    }
                }
            }
        }
    }

    // Else fall back to treating the file's path as an actual file path - defer to PlatformDarwin's GetSharedModule.
    return PlatformDarwin::GetSharedModule (module_spec, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
}
Error
PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec,
                                           lldb_private::Process* process,
                                           ModuleSP &module_sp,
                                           const FileSpecList *module_search_paths_ptr,
                                           ModuleSP *old_module_sp_ptr,
                                           bool *did_create_ptr)
{
    // For Apple Watch, the SDK files are all cached locally on the host
    // system. So first we ask for the file in the cached SDK,
    // then we attempt to get a shared module for the right architecture
    // with the right UUID.
    const FileSpec &platform_file = module_spec.GetFileSpec();
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);

    Error error;
    char platform_file_path[PATH_MAX];
    
    if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
    {
        ModuleSpec platform_module_spec(module_spec);

        UpdateSDKDirectoryInfosIfNeeded();

        const uint32_t num_sdk_infos = m_sdk_directory_infos.size();

        // If we are connected we migth be able to correctly deduce the SDK directory
        // using the OS build.
        const uint32_t connected_sdk_idx = GetConnectedSDKIndex ();
        if (connected_sdk_idx < num_sdk_infos)
        {
            if (log)
            {
                log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str());
            }
            if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec()))
            {
                module_sp.reset();
                error = ResolveExecutable(platform_module_spec,
                                          module_sp,
                                          nullptr);
                if (module_sp)
                {
                    m_last_module_sdk_idx = connected_sdk_idx;
                    error.Clear();
                    return error;
                }
            }
        }

        // Try the last SDK index if it is set as most files from an SDK
        // will tend to be valid in that same SDK.
        if (m_last_module_sdk_idx < num_sdk_infos)
        {
            if (log)
            {
                log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str());
            }
            if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec()))
            {
                module_sp.reset();
                error = ResolveExecutable(platform_module_spec,
                                          module_sp,
                                          nullptr);
                if (module_sp)
                {
                    error.Clear();
                    return error;
                }
            }
        }
        
        // First try for an exact match of major, minor and update
        for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
        {
            if (m_last_module_sdk_idx == sdk_idx)
            {
                // Skip the last module SDK index if we already searched
                // it above
                continue;
            }
            if (log)
            {
                log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
            }
            if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec()))
            {
                //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
                
                error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
                if (module_sp)
                {
                    // Remember the index of the last SDK that we found a file
                    // in in case the wrong SDK was selected.
                    m_last_module_sdk_idx = sdk_idx;
                    error.Clear();
                    return error;
                }
            }
        }
    }
    // Not the module we are looking for... Nothing to see here...
    module_sp.reset();

    // This may not be an SDK-related module.  Try whether we can bring in the thing to our local cache.
    error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
    if (error.Success())
        return error;

    const bool always_create = false;
    error = ModuleList::GetSharedModule (module_spec,
                                         module_sp,
                                         module_search_paths_ptr,
                                         old_module_sp_ptr,
                                         did_create_ptr,
                                         always_create);

    if (module_sp)
        module_sp->SetPlatformFileSpec(platform_file);

    return error;
}
bool
Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup)
{
    bool success = false;
    const UUID *uuid_ptr = module_spec.GetUUIDPtr();
    const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();

    // It's expensive to check for the DBGShellCommands defaults setting, only do it once per
    // lldb run and cache the result.  
    static bool g_have_checked_for_dbgshell_command = false;
    static const char *g_dbgshell_command = NULL;
    if (g_have_checked_for_dbgshell_command == false)
    {
        g_have_checked_for_dbgshell_command = true;
        CFTypeRef defaults_setting = CFPreferencesCopyAppValue (CFSTR ("DBGShellCommands"), CFSTR ("com.apple.DebugSymbols"));
        if (defaults_setting && CFGetTypeID (defaults_setting) == CFStringGetTypeID())
        { 
            char cstr_buf[PATH_MAX];
            if (CFStringGetCString ((CFStringRef) defaults_setting, cstr_buf, sizeof (cstr_buf), kCFStringEncodingUTF8))
            {
                g_dbgshell_command = strdup (cstr_buf);  // this malloc'ed memory will never be freed
            }
        }
        if (defaults_setting)
        {
            CFRelease (defaults_setting);
        }
    }

    // When g_dbgshell_command is NULL, the user has not enabled the use of an external program
    // to find the symbols, don't run it for them.
    if (force_lookup == false && g_dbgshell_command == NULL)
    {
        return false;
    }

    if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists()))
    {
        static bool g_located_dsym_for_uuid_exe = false;
        static bool g_dsym_for_uuid_exe_exists = false;
        static char g_dsym_for_uuid_exe_path[PATH_MAX];
        if (!g_located_dsym_for_uuid_exe)
        {
            g_located_dsym_for_uuid_exe = true;
            const char *dsym_for_uuid_exe_path_cstr = getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
            FileSpec dsym_for_uuid_exe_spec;
            if (dsym_for_uuid_exe_path_cstr)
            {
                dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true);
                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
            }
            
            if (!g_dsym_for_uuid_exe_exists)
            {
                dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
                if (!g_dsym_for_uuid_exe_exists)
                {
                    long bufsize;
                    if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1)
                    {
                        char buffer[bufsize];
                        struct passwd pwd;
                        struct passwd *tilde_rc = NULL;
                        // we are a library so we need to use the reentrant version of getpwnam()
                        if (getpwnam_r ("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 
                            && tilde_rc 
                            && tilde_rc->pw_dir)
                        {
                            std::string dsymforuuid_path(tilde_rc->pw_dir);
                            dsymforuuid_path += "/bin/dsymForUUID";
                            dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false);
                            g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
                        }
                    }
                }
            }
            if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL)
            {
                dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true);
                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
            }

            if (g_dsym_for_uuid_exe_exists)
                dsym_for_uuid_exe_spec.GetPath (g_dsym_for_uuid_exe_path, sizeof(g_dsym_for_uuid_exe_path));
        }
        if (g_dsym_for_uuid_exe_exists)
        {
            std::string uuid_str;
            char file_path[PATH_MAX];
            file_path[0] = '\0';

            if (uuid_ptr)
                uuid_str = uuid_ptr->GetAsString();

            if (file_spec_ptr)
                file_spec_ptr->GetPath(file_path, sizeof(file_path));
            
            StreamString command;
            if (!uuid_str.empty())
                command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_str.c_str());
            else if (file_path && file_path[0])
                command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, file_path);
            
            if (!command.GetString().empty())
            {
                int exit_status = -1;
                int signo = -1;
                std::string command_output;
                Error error = Host::RunShellCommand (command.GetData(),
                                                     NULL,              // current working directory
                                                     &exit_status,      // Exit status
                                                     &signo,            // Signal int *
                                                     &command_output,   // Command output
                                                     30,                // Large timeout to allow for long dsym download times
                                                     NULL);             // Don't run in a shell (we don't need shell expansion)
                if (error.Success() && exit_status == 0 && !command_output.empty())
                {
                    CFCData data (CFDataCreateWithBytesNoCopy (NULL,
                                                               (const UInt8 *)command_output.data(),
                                                               command_output.size(),
                                                               kCFAllocatorNull));
                    
                    CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
                    
                    if (plist.get() && CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
                    {
                        if (!uuid_str.empty())
                        {
                            CFCString uuid_cfstr(uuid_str.c_str());
                            CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue (plist.get(), uuid_cfstr.get());
                            success = GetModuleSpecInfoFromUUIDDictionary (uuid_dict, module_spec);
                        }
                        else
                        {
                            const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
                            if (num_values > 0)
                            {
                                std::vector<CFStringRef> keys (num_values, NULL);
                                std::vector<CFDictionaryRef> values (num_values, NULL);
                                ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]);
                                if (num_values == 1)
                                {
                                    return GetModuleSpecInfoFromUUIDDictionary (values[0], module_spec);
                                }
                                else
                                {
                                    for (CFIndex i=0; i<num_values; ++i)
                                    {
                                        ModuleSpec curr_module_spec;
                                        if (GetModuleSpecInfoFromUUIDDictionary (values[i], curr_module_spec))
                                        {
                                            if (module_spec.GetArchitecture().IsCompatibleMatch(curr_module_spec.GetArchitecture()))
                                            {
                                                module_spec = curr_module_spec;
                                                return true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return success;
}
Beispiel #16
0
static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
                                                ModuleSpec &module_spec) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  bool success = false;
  if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
    std::string str;
    CFStringRef cf_str;
    CFDictionaryRef cf_dict;

    cf_str = (CFStringRef)CFDictionaryGetValue(
        (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      if (CFCString::FileSystemRepresentation(cf_str, str)) {
        module_spec.GetFileSpec().SetFile(str.c_str(), true);
        if (log) {
          log->Printf(
              "From dsymForUUID plist: Symbol rich executable is at '%s'",
              str.c_str());
        }
      }
    }

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGDSYMPath"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      if (CFCString::FileSystemRepresentation(cf_str, str)) {
        module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true);
        success = true;
        if (log) {
          log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
        }
      }
    }

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGArchitecture"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      if (CFCString::FileSystemRepresentation(cf_str, str))
        module_spec.GetArchitecture().SetTriple(str.c_str());
    }

    std::string DBGBuildSourcePath;
    std::string DBGSourcePath;

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGBuildSourcePath"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
    }

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGSourcePath"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
    }

    if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
      if (DBGSourcePath[0] == '~') {
        FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
        DBGSourcePath = resolved_source_path.GetPath();
      }
      module_spec.GetSourceMappingList().Append(
          ConstString(DBGBuildSourcePath.c_str()),
          ConstString(DBGSourcePath.c_str()), true);
    }

    cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
        (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
    if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
      // If we see DBGVersion with a value of 2 or higher, this is a new style
      // DBGSourcePathRemapping dictionary
      bool new_style_source_remapping_dictionary = false;
      std::string original_DBGSourcePath_value = DBGSourcePath;
      cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                                 CFSTR("DBGVersion"));
      if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
        std::string version;
        CFCString::FileSystemRepresentation(cf_str, version);
        if (!version.empty() && isdigit(version[0])) {
          int version_number = atoi(version.c_str());
          if (version_number > 1) {
            new_style_source_remapping_dictionary = true;
          }
        }
      }

      CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
      if (kv_pair_count > 0) {
        CFStringRef *keys =
            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
        CFStringRef *values =
            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
        if (keys != nullptr && values != nullptr) {
          CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
                                       (const void **)keys,
                                       (const void **)values);
        }
        for (CFIndex i = 0; i < kv_pair_count; i++) {
          DBGBuildSourcePath.clear();
          DBGSourcePath.clear();
          if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
            CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
          }
          if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
            CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
          }
          if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
            // In the "old style" DBGSourcePathRemapping dictionary, the
            // DBGSourcePath values
            // (the "values" half of key-value path pairs) were wrong.  Ignore
            // them and use the
            // universal DBGSourcePath string from earlier.
            if (new_style_source_remapping_dictionary == true &&
                !original_DBGSourcePath_value.empty()) {
              DBGSourcePath = original_DBGSourcePath_value;
            }
            if (DBGSourcePath[0] == '~') {
              FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
              DBGSourcePath = resolved_source_path.GetPath();
            }
            module_spec.GetSourceMappingList().Append(
                ConstString(DBGBuildSourcePath.c_str()),
                ConstString(DBGSourcePath.c_str()), true);
          }
        }
        if (keys)
          free(keys);
        if (values)
          free(values);
      }
    }
  }
  return success;
}
Beispiel #17
0
Error PlatformRemoteAppleWatch::GetSharedModule(
    const ModuleSpec &module_spec, lldb_private::Process *process,
    ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
    ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
    // For Apple Watch, the SDK files are all cached locally on the host
    // system. So first we ask for the file in the cached SDK,
    // then we attempt to get a shared module for the right architecture
    // with the right UUID.
    const FileSpec &platform_file = module_spec.GetFileSpec();
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
               LIBLLDB_LOG_VERBOSE);

    Error error;
    char platform_file_path[PATH_MAX];

    if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
        ModuleSpec platform_module_spec(module_spec);

        UpdateSDKDirectoryInfosIfNeeded();

        const uint32_t num_sdk_infos = m_sdk_directory_infos.size();

        // If we are connected we migth be able to correctly deduce the SDK
        // directory
        // using the OS build.
        const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
        if (connected_sdk_idx < num_sdk_infos) {
            if (log) {
                log->Printf("Searching for %s in sdk path %s", platform_file_path,
                            m_sdk_directory_infos[connected_sdk_idx]
                            .directory.GetPath()
                            .c_str());
            }
            if (GetFileInSDK(platform_file_path, connected_sdk_idx,
                             platform_module_spec.GetFileSpec())) {
                module_sp.reset();
                error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
                if (module_sp) {
                    m_last_module_sdk_idx = connected_sdk_idx;
                    error.Clear();
                    return error;
                }
            }
        }

        // Try the last SDK index if it is set as most files from an SDK
        // will tend to be valid in that same SDK.
        if (m_last_module_sdk_idx < num_sdk_infos) {
            if (log) {
                log->Printf("Searching for %s in sdk path %s", platform_file_path,
                            m_sdk_directory_infos[m_last_module_sdk_idx]
                            .directory.GetPath()
                            .c_str());
            }
            if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
                             platform_module_spec.GetFileSpec())) {
                module_sp.reset();
                error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
                if (module_sp) {
                    error.Clear();
                    return error;
                }
            }
        }

        // First try for an exact match of major, minor and update
        for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
            if (m_last_module_sdk_idx == sdk_idx) {
                // Skip the last module SDK index if we already searched
                // it above
                continue;
            }
            if (log) {
                log->Printf("Searching for %s in sdk path %s", platform_file_path,
                            m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
            }
            if (GetFileInSDK(platform_file_path, sdk_idx,
                             platform_module_spec.GetFileSpec())) {
                // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());

                error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
                if (module_sp) {
                    // Remember the index of the last SDK that we found a file
                    // in in case the wrong SDK was selected.
                    m_last_module_sdk_idx = sdk_idx;
                    error.Clear();
                    return error;
                }
            }
        }
    }
    // Not the module we are looking for... Nothing to see here...
    module_sp.reset();

    // This may not be an SDK-related module.  Try whether we can bring in the
    // thing to our local cache.
    error = GetSharedModuleWithLocalCache(module_spec, module_sp,
                                          module_search_paths_ptr,
                                          old_module_sp_ptr, did_create_ptr);
    if (error.Success())
        return error;

    // See if the file is present in any of the module_search_paths_ptr
    // directories.
    if (!module_sp && module_search_paths_ptr && platform_file) {
        // create a vector of all the file / directory names in platform_file
        // e.g. this might be
        // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
        //
        // We'll need to look in the module_search_paths_ptr directories for
        // both "UIFoundation" and "UIFoundation.framework" -- most likely the
        // latter will be the one we find there.

        FileSpec platform_pull_apart(platform_file);
        std::vector<std::string> path_parts;
        ConstString unix_root_dir("/");
        while (true) {
            ConstString part = platform_pull_apart.GetLastPathComponent();
            platform_pull_apart.RemoveLastPathComponent();
            if (part.IsEmpty() || part == unix_root_dir)
                break;
            path_parts.push_back(part.AsCString());
        }
        const size_t path_parts_size = path_parts.size();

        size_t num_module_search_paths = module_search_paths_ptr->GetSize();
        for (size_t i = 0; i < num_module_search_paths; ++i) {
            // Create a new FileSpec with this module_search_paths_ptr
            // plus just the filename ("UIFoundation"), then the parent
            // dir plus filename ("UIFoundation.framework/UIFoundation")
            // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")

            for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
                FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));

                // Add the components backwards.  For
                // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
                // path_parts is
                //   [0] UIFoundation
                //   [1] UIFoundation.framework
                //   [2] PrivateFrameworks
                //
                // and if 'j' is 2, we want to append path_parts[1] and then
                // path_parts[0], aka
                // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
                // path.

                for (int k = j; k >= 0; --k) {
                    path_to_try.AppendPathComponent(path_parts[k]);
                }

                if (path_to_try.Exists()) {
                    ModuleSpec new_module_spec(module_spec);
                    new_module_spec.GetFileSpec() = path_to_try;
                    Error new_error(Platform::GetSharedModule(
                                        new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
                                        did_create_ptr));

                    if (module_sp) {
                        module_sp->SetPlatformFileSpec(path_to_try);
                        return new_error;
                    }
                }
            }
        }
    }

    const bool always_create = false;
    error = ModuleList::GetSharedModule(
                module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
                did_create_ptr, always_create);

    if (module_sp)
        module_sp->SetPlatformFileSpec(platform_file);

    return error;
}
Beispiel #18
0
int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
                                       ModuleSpec &return_module_spec) {
  return_module_spec = module_spec;
  return_module_spec.GetFileSpec().Clear();
  return_module_spec.GetSymbolFileSpec().Clear();

  int items_found = 0;

#if !defined(__arm__) && !defined(__arm64__) &&                                \
    !defined(__aarch64__) // No DebugSymbols on the iOS devices

  const UUID *uuid = module_spec.GetUUIDPtr();
  const ArchSpec *arch = module_spec.GetArchitecturePtr();

  if (uuid && uuid->IsValid()) {
    // Try and locate the dSYM file using DebugSymbols first
    const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
    if (module_uuid != NULL) {
      CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
          NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
          module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
          module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11],
          module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15]));

      if (module_uuid_ref.get()) {
        CFCReleaser<CFURLRef> exec_url;
        const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
        Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
        if (exec_fspec) {
          char exec_cf_path[PATH_MAX];
          if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
            exec_url.reset(::CFURLCreateFromFileSystemRepresentation(
                NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path),
                FALSE));
        }

        CFCReleaser<CFURLRef> dsym_url(
            ::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
        char path[PATH_MAX];

        if (dsym_url.get()) {
          if (::CFURLGetFileSystemRepresentation(
                  dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
            if (log) {
              log->Printf("DebugSymbols framework returned dSYM path of %s for "
                          "UUID %s -- looking for the dSYM",
                          path, uuid->GetAsString().c_str());
            }
            FileSpec dsym_filespec(path, path[0] == '~');

            if (dsym_filespec.GetFileType() == FileSpec::eFileTypeDirectory) {
              dsym_filespec =
                  Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch);
              ++items_found;
            } else {
              ++items_found;
            }
            return_module_spec.GetSymbolFileSpec() = dsym_filespec;
          }

          bool success = false;
          if (log) {
            if (::CFURLGetFileSystemRepresentation(
                    dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
              log->Printf("DebugSymbols framework returned dSYM path of %s for "
                          "UUID %s -- looking for an exec file",
                          path, uuid->GetAsString().c_str());
            }
          }

          CFCReleaser<CFDictionaryRef> dict(
              ::DBGCopyDSYMPropertyLists(dsym_url.get()));
          CFDictionaryRef uuid_dict = NULL;
          if (dict.get()) {
            CFCString uuid_cfstr(uuid->GetAsString().c_str());
            uuid_dict = static_cast<CFDictionaryRef>(
                ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get()));
          }
          if (uuid_dict) {
            CFStringRef exec_cf_path =
                static_cast<CFStringRef>(::CFDictionaryGetValue(
                    uuid_dict, CFSTR("DBGSymbolRichExecutable")));
            if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
                                    exec_cf_path, path, sizeof(path))) {
              if (log) {
                log->Printf("plist bundle has exec path of %s for UUID %s",
                            path, uuid->GetAsString().c_str());
              }
              ++items_found;
              FileSpec exec_filespec(path, path[0] == '~');
              if (exec_filespec.Exists()) {
                success = true;
                return_module_spec.GetFileSpec() = exec_filespec;
              }
            }
          }

          if (!success) {
            // No dictionary, check near the dSYM bundle for an executable that
            // matches...
            if (::CFURLGetFileSystemRepresentation(
                    dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
              char *dsym_extension_pos = ::strstr(path, ".dSYM");
              if (dsym_extension_pos) {
                *dsym_extension_pos = '\0';
                if (log) {
                  log->Printf("Looking for executable binary next to dSYM "
                              "bundle with name with name %s",
                              path);
                }
                FileSpec file_spec(path, true);
                ModuleSpecList module_specs;
                ModuleSpec matched_module_spec;
                switch (file_spec.GetFileType()) {
                case FileSpec::eFileTypeDirectory: // Bundle directory?
                {
                  CFCBundle bundle(path);
                  CFCReleaser<CFURLRef> bundle_exe_url(
                      bundle.CopyExecutableURL());
                  if (bundle_exe_url.get()) {
                    if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
                                                           true, (UInt8 *)path,
                                                           sizeof(path) - 1)) {
                      FileSpec bundle_exe_file_spec(path, true);
                      if (ObjectFile::GetModuleSpecifications(
                              bundle_exe_file_spec, 0, 0, module_specs) &&
                          module_specs.FindMatchingModuleSpec(
                              module_spec, matched_module_spec))

                      {
                        ++items_found;
                        return_module_spec.GetFileSpec() = bundle_exe_file_spec;
                        if (log) {
                          log->Printf("Executable binary %s next to dSYM is "
                                      "compatible; using",
                                      path);
                        }
                      }
                    }
                  }
                } break;

                case FileSpec::eFileTypePipe:   // Forget pipes
                case FileSpec::eFileTypeSocket: // We can't process socket files
                case FileSpec::eFileTypeInvalid: // File doesn't exist...
                  break;

                case FileSpec::eFileTypeUnknown:
                case FileSpec::eFileTypeRegular:
                case FileSpec::eFileTypeSymbolicLink:
                case FileSpec::eFileTypeOther:
                  if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0,
                                                          module_specs) &&
                      module_specs.FindMatchingModuleSpec(module_spec,
                                                          matched_module_spec))

                  {
                    ++items_found;
                    return_module_spec.GetFileSpec() = file_spec;
                    if (log) {
                      log->Printf("Executable binary %s next to dSYM is "
                                  "compatible; using",
                                  path);
                    }
                  }
                  break;
                }
              }
            }
          }
        }
      }
    }
  }
#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined
       // (__aarch64__)

  return items_found;
}
Beispiel #19
0
Error
PlatformFreeBSD::ResolveExecutable (const ModuleSpec &module_spec,
                                    lldb::ModuleSP &exe_module_sp,
                                    const FileSpecList *module_search_paths_ptr)
{
    Error error;
    // Nothing special to do here, just use the actual file and architecture

    char exe_path[PATH_MAX];
    ModuleSpec resolved_module_spec(module_spec);

    if (IsHost())
    {
        // If we have "ls" as the module_spec's file, resolve the executable location based on
        // the current path variables
        if (!resolved_module_spec.GetFileSpec().Exists())
        {
            module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
            resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
        }

        if (!resolved_module_spec.GetFileSpec().Exists())
            resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();

        if (resolved_module_spec.GetFileSpec().Exists())
            error.Clear();
        else
        {
            error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
        }
    }
    else
    {
        if (m_remote_platform_sp)
        {
            error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
        }
        else
        {
            // We may connect to a process and use the provided executable (Don't use local $PATH).

            // Resolve any executable within a bundle on MacOSX
            Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());

            if (resolved_module_spec.GetFileSpec().Exists())
            {
                error.Clear();
            }
            else
            {
                error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_module_spec.GetFileSpec().GetPath().c_str());
            }
        }
    }

    if (error.Success())
    {
        if (resolved_module_spec.GetArchitecture().IsValid())
        {
            error = ModuleList::GetSharedModule (resolved_module_spec,
                                                 exe_module_sp,
                                                 module_search_paths_ptr,
                                                 NULL,
                                                 NULL);

            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
            {
                exe_module_sp.reset();
                error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
                                                resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                resolved_module_spec.GetArchitecture().GetArchitectureName());
            }
        }
        else
        {
            // No valid architecture was specified, ask the platform for
            // the architectures that we should be using (in the correct order)
            // and see if we can find a match that way
            StreamString arch_names;
            for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
            {
                error = ModuleList::GetSharedModule (resolved_module_spec,
                                                     exe_module_sp,
                                                     module_search_paths_ptr,
                                                     NULL,
                                                     NULL);
                // Did we find an executable using one of the
                if (error.Success())
                {
                    if (exe_module_sp && exe_module_sp->GetObjectFile())
                        break;
                    else
                        error.SetErrorToGenericError();
                }

                if (idx > 0)
                    arch_names.PutCString (", ");
                arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
            }

            if (error.Fail() || !exe_module_sp)
            {
                if (resolved_module_spec.GetFileSpec().Readable())
                {
                    error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
                                                    resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                    GetPluginName().GetCString(),
                                                    arch_names.GetString().c_str());
                }
                else
                {
                    error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
                }
            }
        }
    }

    return error;
}
Error PlatformiOSSimulator::ResolveExecutable(
    const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
    const FileSpecList *module_search_paths_ptr) {
    Error error;
    // Nothing special to do here, just use the actual file and architecture

    ModuleSpec resolved_module_spec(module_spec);

    // If we have "ls" as the exe_file, resolve the executable loation based on
    // the current path variables
    // TODO: resolve bare executables in the Platform SDK
    //    if (!resolved_exe_file.Exists())
    //        resolved_exe_file.ResolveExecutableLocation ();

    // Resolve any executable within a bundle on MacOSX
    // TODO: verify that this handles shallow bundles, if not then implement one
    // ourselves
    Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());

    if (resolved_module_spec.GetFileSpec().Exists()) {
        if (resolved_module_spec.GetArchitecture().IsValid()) {
            error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                                NULL, NULL, NULL);

            if (exe_module_sp && exe_module_sp->GetObjectFile())
                return error;
            exe_module_sp.reset();
        }
        // No valid architecture was specified or the exact ARM slice wasn't
        // found so ask the platform for the architectures that we should be
        // using (in the correct order) and see if we can find a match that way
        StreamString arch_names;
        ArchSpec platform_arch;
        for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
                    idx, resolved_module_spec.GetArchitecture());
                ++idx) {
            // Only match x86 with x86 and x86_64 with x86_64...
            if (!module_spec.GetArchitecture().IsValid() ||
                    module_spec.GetArchitecture().GetCore() ==
                    resolved_module_spec.GetArchitecture().GetCore()) {
                error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                                    NULL, NULL, NULL);
                // Did we find an executable using one of the
                if (error.Success()) {
                    if (exe_module_sp && exe_module_sp->GetObjectFile())
                        break;
                    else
                        error.SetErrorToGenericError();
                }

                if (idx > 0)
                    arch_names.PutCString(", ");
                arch_names.PutCString(platform_arch.GetArchitectureName());
            }
        }

        if (error.Fail() || !exe_module_sp) {
            if (resolved_module_spec.GetFileSpec().Readable()) {
                error.SetErrorStringWithFormat(
                    "'%s' doesn't contain any '%s' platform architectures: %s",
                    resolved_module_spec.GetFileSpec().GetPath().c_str(),
                    GetPluginName().GetCString(), arch_names.GetString().c_str());
            } else {
                error.SetErrorStringWithFormat(
                    "'%s' is not readable",
                    resolved_module_spec.GetFileSpec().GetPath().c_str());
            }
        }
    } else {
        error.SetErrorStringWithFormat("'%s' does not exist",
                                       module_spec.GetFileSpec().GetPath().c_str());
    }

    return error;
}
Beispiel #21
0
static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
                                              FileSpec &dsym_fspec) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
  if (exec_fspec) {
    char path[PATH_MAX];
    if (exec_fspec->GetPath(path, sizeof(path))) {
      // Make sure the module isn't already just a dSYM file...
      if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) {
        if (log) {
          if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) {
            log->Printf(
                "Searching for dSYM bundle next to executable %s, UUID %s",
                path, module_spec.GetUUIDPtr()->GetAsString().c_str());
          } else {
            log->Printf("Searching for dSYM bundle next to executable %s",
                        path);
          }
        }
        size_t obj_file_path_length = strlen(path);
        ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
                  sizeof(path) - strlen(path) - 1);
        ::strncat(path, exec_fspec->GetFilename().AsCString(),
                  sizeof(path) - strlen(path) - 1);

        dsym_fspec.SetFile(path, false);

        ModuleSpecList module_specs;
        ModuleSpec matched_module_spec;
        if (dsym_fspec.Exists() &&
            FileAtPathContainsArchAndUUID(dsym_fspec,
                                          module_spec.GetArchitecturePtr(),
                                          module_spec.GetUUIDPtr())) {
          if (log) {
            log->Printf("dSYM with matching UUID & arch found at %s", path);
          }
          return true;
        } else {
          path[obj_file_path_length] = '\0';

          char *last_dot = strrchr(path, '.');
          while (last_dot != NULL && last_dot[0]) {
            char *next_slash = strchr(last_dot, '/');
            if (next_slash != NULL) {
              *next_slash = '\0';
              ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
                        sizeof(path) - strlen(path) - 1);
              ::strncat(path, exec_fspec->GetFilename().AsCString(),
                        sizeof(path) - strlen(path) - 1);
              dsym_fspec.SetFile(path, false);
              if (dsym_fspec.Exists() &&
                  FileAtPathContainsArchAndUUID(
                      dsym_fspec, module_spec.GetArchitecturePtr(),
                      module_spec.GetUUIDPtr())) {
                if (log) {
                  log->Printf("dSYM with matching UUID & arch found at %s",
                              path);
                }
                return true;
              } else {
                *last_dot = '\0';
                char *prev_slash = strrchr(path, '/');
                if (prev_slash != NULL)
                  *prev_slash = '\0';
                else
                  break;
              }
            } else {
              break;
            }
          }
        }
      }
    }
  }
  dsym_fspec.Clear();
  return false;
}
static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
                                                ModuleSpec &module_spec) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  bool success = false;
  if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
    std::string str;
    CFStringRef cf_str;
    CFDictionaryRef cf_dict;

    cf_str = (CFStringRef)CFDictionaryGetValue(
        (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      if (CFCString::FileSystemRepresentation(cf_str, str)) {
        module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
        FileSystem::Instance().Resolve(module_spec.GetFileSpec());
        if (log) {
          log->Printf(
              "From dsymForUUID plist: Symbol rich executable is at '%s'",
              str.c_str());
        }
      }
    }

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGDSYMPath"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      if (CFCString::FileSystemRepresentation(cf_str, str)) {
        module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
                                                FileSpec::Style::native);
        FileSystem::Instance().Resolve(module_spec.GetFileSpec());
        success = true;
        if (log) {
          log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
        }
      }
    }

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGArchitecture"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      if (CFCString::FileSystemRepresentation(cf_str, str))
        module_spec.GetArchitecture().SetTriple(str.c_str());
    }

    std::string DBGBuildSourcePath;
    std::string DBGSourcePath;

    // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
    // If DBGVersion 2, strip last two components of path remappings from
    //                  entries to fix an issue with a specific set of
    //                  DBGSourcePathRemapping entries that lldb worked
    //                  with.
    // If DBGVersion 3, trust & use the source path remappings as-is.
    //
    cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
        (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
    if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
      // If we see DBGVersion with a value of 2 or higher, this is a new style
      // DBGSourcePathRemapping dictionary
      bool new_style_source_remapping_dictionary = false;
      bool do_truncate_remapping_names = false;
      std::string original_DBGSourcePath_value = DBGSourcePath;
      cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                                 CFSTR("DBGVersion"));
      if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
        std::string version;
        CFCString::FileSystemRepresentation(cf_str, version);
        if (!version.empty() && isdigit(version[0])) {
          int version_number = atoi(version.c_str());
          if (version_number > 1) {
            new_style_source_remapping_dictionary = true;
          }
          if (version_number == 2) {
            do_truncate_remapping_names = true;
          }
        }
      }

      CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
      if (kv_pair_count > 0) {
        CFStringRef *keys =
            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
        CFStringRef *values =
            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
        if (keys != nullptr && values != nullptr) {
          CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
                                       (const void **)keys,
                                       (const void **)values);
        }
        for (CFIndex i = 0; i < kv_pair_count; i++) {
          DBGBuildSourcePath.clear();
          DBGSourcePath.clear();
          if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
            CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
          }
          if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
            CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
          }
          if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
            // In the "old style" DBGSourcePathRemapping dictionary, the
            // DBGSourcePath values (the "values" half of key-value path pairs)
            // were wrong.  Ignore them and use the universal DBGSourcePath
            // string from earlier.
            if (new_style_source_remapping_dictionary &&
                !original_DBGSourcePath_value.empty()) {
              DBGSourcePath = original_DBGSourcePath_value;
            }
            if (DBGSourcePath[0] == '~') {
              FileSpec resolved_source_path(DBGSourcePath.c_str());
              FileSystem::Instance().Resolve(resolved_source_path);
              DBGSourcePath = resolved_source_path.GetPath();
            }
            // With version 2 of DBGSourcePathRemapping, we can chop off the
            // last two filename parts from the source remapping and get a more
            // general source remapping that still works. Add this as another
            // option in addition to the full source path remap.
            module_spec.GetSourceMappingList().Append(
                ConstString(DBGBuildSourcePath.c_str()),
                ConstString(DBGSourcePath.c_str()), true);
            if (do_truncate_remapping_names) {
              FileSpec build_path(DBGBuildSourcePath.c_str());
              FileSpec source_path(DBGSourcePath.c_str());
              build_path.RemoveLastPathComponent();
              build_path.RemoveLastPathComponent();
              source_path.RemoveLastPathComponent();
              source_path.RemoveLastPathComponent();
              module_spec.GetSourceMappingList().Append(
                  ConstString(build_path.GetPath().c_str()),
                  ConstString(source_path.GetPath().c_str()), true);
            }
          }
        }
        if (keys)
          free(keys);
        if (values)
          free(values);
      }
    }

    // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
    // source remappings list.

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGBuildSourcePath"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
    }

    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
                                               CFSTR("DBGSourcePath"));
    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
      CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
    }

    if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
      if (DBGSourcePath[0] == '~') {
        FileSpec resolved_source_path(DBGSourcePath.c_str());
        FileSystem::Instance().Resolve(resolved_source_path);
        DBGSourcePath = resolved_source_path.GetPath();
      }
      module_spec.GetSourceMappingList().Append(
          ConstString(DBGBuildSourcePath.c_str()),
          ConstString(DBGSourcePath.c_str()), true);
    }
  }
  return success;
}