bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
                                     uint32_t sdk_idx,
                                     lldb_private::FileSpec &local_file) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  if (sdk_idx < m_sdk_directory_infos.size()) {
    std::string sdkroot_path =
        m_sdk_directory_infos[sdk_idx].directory.GetPath();
    local_file.Clear();

    if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
      // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
      // the
      // SDK root directory and the file path.

      const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
      for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
        local_file.SetFile(sdkroot_path, FileSpec::Style::native);
        if (paths_to_try[i][0] != '\0')
          local_file.AppendPathComponent(paths_to_try[i]);
        local_file.AppendPathComponent(platform_file_path);
        FileSystem::Instance().Resolve(local_file);
        if (FileSystem::Instance().Exists(local_file)) {
          if (log)
            log->Printf("Found a copy of %s in the SDK dir %s/%s",
                        platform_file_path, sdkroot_path.c_str(),
                        paths_to_try[i]);
          return true;
        }
        local_file.Clear();
      }
    }
  }
  return false;
}
Example #2
0
uint32_t SymbolFilePDB::ResolveSymbolContext(
    const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
    uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) {
  if (resolve_scope & lldb::eSymbolContextCompUnit) {
    // Locate all compilation units with line numbers referencing the specified
    // file.  For example, if
    // `file_spec` is <vector>, then this should return all source files and
    // header files that reference
    // <vector>, either directly or indirectly.
    auto compilands = m_session_up->findCompilandsForSourceFile(
        file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);

    // For each one, either find get its previously parsed data, or parse it
    // afresh and add it to
    // the symbol context list.
    while (auto compiland = compilands->getNext()) {
      // If we're not checking inlines, then don't add line information for this
      // file unless the FileSpec
      // matches.
      if (!check_inlines) {
        // `getSourceFileName` returns the basename of the original source file
        // used to generate this compiland.
        // It does not return the full path.  Currently the only way to get that
        // is to do a basename lookup to
        // get the IPDBSourceFile, but this is ambiguous in the case of two
        // source files with the same name
        // contributing to the same compiland.  This is a moderately extreme
        // edge case, so we consider this ok
        // for now, although we need to find a long term solution.
        std::string source_file = compiland->getSourceFileName();
        auto pdb_file = m_session_up->findOneSourceFile(
            compiland.get(), source_file,
            PDB_NameSearchFlags::NS_CaseInsensitive);
        source_file = pdb_file->getFileName();
        FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
        if (!file_spec.FileEquals(this_spec))
          continue;
      }

      SymbolContext sc;
      auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
      sc.comp_unit = cu.get();
      sc.module_sp = cu->GetModule();
      sc_list.Append(sc);

      // If we were asked to resolve line entries, add all entries to the line
      // table that match the requested
      // line (or all lines if `line` == 0)
      if (resolve_scope & lldb::eSymbolContextLineEntry)
        ParseCompileUnitLineTable(sc, line);
    }
  }
  return sc_list.GetSize();
}
PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(
    const lldb_private::FileSpec &sdk_dir)
    : directory(sdk_dir), build(), user_cached(false) {
  llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
  llvm::StringRef build_str;
  std::tie(version, build_str) = ParseVersionBuildDir(dirname_str);
  build.SetString(build_str);
}
Example #4
0
PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo(
    const lldb_private::FileSpec &sdk_dir)
    : directory(sdk_dir), build(), version_major(0), version_minor(0),
      version_update(0), user_cached(false) {
    llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
    llvm::StringRef build_str;
    std::tie(version_major, version_minor, version_update, build_str) =
        ParseVersionBuildDir(dirname_str);
    build.SetString(build_str);
}
Example #5
0
lldb_private::Error
PlatformMacOSX::GetFileWithUUID (const lldb_private::FileSpec &platform_file,
                                 const lldb_private::UUID *uuid_ptr,
                                 lldb_private::FileSpec &local_file)
{
    if (IsRemote() && m_remote_platform_sp)
    {
        std::string local_os_build;
#if !defined(__linux__)
        HostInfo::GetOSBuildString(local_os_build);
#endif
        std::string remote_os_build;
        m_remote_platform_sp->GetOSBuildString(remote_os_build);
        if (local_os_build.compare(remote_os_build) == 0)
        {
            // same OS version: the local file is good enough
            local_file = platform_file;
            return Error();
        }
        else
        {
            // try to find the file in the cache
            std::string cache_path(GetLocalCacheDirectory());
            std::string module_path (platform_file.GetPath());
            cache_path.append(module_path);
            FileSpec module_cache_spec(cache_path.c_str(),false);
            if (module_cache_spec.Exists())
            {
                local_file = module_cache_spec;
                return Error();
            }
            // bring in the remote module file
            FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
            // try to make the local directory first
            Error err =
                FileSystem::MakeDirectory(module_cache_folder, eFilePermissionsDirectoryDefault);
            if (err.Fail())
                return err;
            err = GetFile(platform_file, module_cache_spec);
            if (err.Fail())
                return err;
            if (module_cache_spec.Exists())
            {
                local_file = module_cache_spec;
                return Error();
            }
            else
                return Error("unable to obtain valid module file");
        }
    }
    local_file = platform_file;
    return Error();
}
PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo(
    const lldb_private::FileSpec &sdk_dir)
    : directory(sdk_dir), build(), version_major(0), version_minor(0),
      version_update(0), user_cached(false) {
  const char *dirname_cstr = sdk_dir.GetFilename().GetCString();
  const char *pos = Args::StringToVersion(dirname_cstr, version_major,
                                          version_minor, version_update);

  if (pos && pos[0] == ' ' && pos[1] == '(') {
    const char *build_start = pos + 2;
    const char *end_paren = strchr(build_start, ')');
    if (end_paren && build_start < end_paren)
      build.SetCStringWithLength(build_start, end_paren - build_start);
  }
}
bool
PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path,
                                     const char *sdkroot_path,
                                     bool symbols_dirs_only,
                                     lldb_private::FileSpec &local_file)
{
    if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
    {
        char resolved_path[PATH_MAX];
        
        if (!symbols_dirs_only)
        {
            ::snprintf (resolved_path, 
                        sizeof(resolved_path), 
                        "%s/%s", 
                        sdkroot_path,
                        platform_file_path);
            
            local_file.SetFile(resolved_path, true);
            if (local_file.Exists())
                return true;
        }
            
        ::snprintf (resolved_path,
                    sizeof(resolved_path), 
                    "%s/Symbols.Internal/%s", 
                    sdkroot_path,
                    platform_file_path);
        
        local_file.SetFile(resolved_path, true);
        if (local_file.Exists())
            return true;
        ::snprintf (resolved_path,
                    sizeof(resolved_path), 
                    "%s/Symbols/%s", 
                    sdkroot_path, 
                    platform_file_path);
        
        local_file.SetFile(resolved_path, true);
        if (local_file.Exists())
            return true;                
    }
    return false;
}
bool
PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path,
                                     const char *sdkroot_path,
                                     bool symbols_dirs_only,
                                     lldb_private::FileSpec &local_file)
{
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
    if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
    {
        char resolved_path[PATH_MAX];
        
        if (!symbols_dirs_only)
        {
            ::snprintf (resolved_path, 
                        sizeof(resolved_path), 
                        "%s%s",
                        sdkroot_path,
                        platform_file_path);
            
            local_file.SetFile(resolved_path, true);
            if (local_file.Exists())
            {
                if (log)
                {
                    log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path);
                }
                return true;
            }
        }
            
        ::snprintf (resolved_path,
                    sizeof(resolved_path), 
                    "%s/Symbols.Internal%s",
                    sdkroot_path,
                    platform_file_path);
        
        local_file.SetFile(resolved_path, true);
        if (local_file.Exists())
        {
            if (log)
            {
                log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path);
            }
            return true;
        }
        ::snprintf (resolved_path,
                    sizeof(resolved_path), 
                    "%s/Symbols%s", 
                    sdkroot_path, 
                    platform_file_path);
        
        local_file.SetFile(resolved_path, true);
        if (local_file.Exists())
        {
            if (log)
            {
                log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path);
            }
            return true;                
        }
    }
    return false;
}
Example #9
0
lldb_private::Error
PlatformPOSIX::GetFile(const lldb_private::FileSpec &source,      // remote file path
                       const lldb_private::FileSpec &destination) // local file path
{
    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));

    // Check the args, first.
    std::string src_path (source.GetPath());
    if (src_path.empty())
        return Error("unable to get file path for source");
    std::string dst_path (destination.GetPath());
    if (dst_path.empty())
        return Error("unable to get file path for destination");
    if (IsHost())
    {
        if (FileSpec::Equal(source, destination, true))
            return Error("local scenario->source and destination are the same file path: no operation performed");
        // cp src dst
        StreamString cp_command;
        cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
        int status;
        RunShellCommand(cp_command.GetData(),
                        NULL,
                        &status,
                        NULL,
                        NULL,
                        10);
        if (status != 0)
            return Error("unable to perform copy");
        return Error();
    }
    else if (m_remote_platform_sp)
    {
        if (GetSupportsRSync())
        {
            StreamString command;
            if (GetIgnoresRemoteHostname())
            {
                if (!GetRSyncPrefix())
                    command.Printf("rsync %s %s %s",
                                   GetRSyncOpts(),
                                   src_path.c_str(),
                                   dst_path.c_str());
                else
                    command.Printf("rsync %s %s%s %s",
                                   GetRSyncOpts(),
                                   GetRSyncPrefix(),
                                   src_path.c_str(),
                                   dst_path.c_str());
            }
            else
                command.Printf("rsync %s %s:%s %s",
                               GetRSyncOpts(),
                               m_remote_platform_sp->GetHostname(),
                               src_path.c_str(),
                               dst_path.c_str());
            if (log)
                log->Printf("[GetFile] Running command: %s\n", command.GetData());
            int retcode;
            Host::RunShellCommand(command.GetData(),
                                  NULL,
                                  &retcode,
                                  NULL,
                                  NULL,
                                  60);
            if (retcode == 0)
                return Error();
            // If we are here, rsync has failed - let's try the slow way before giving up
        }
        // open src and dst
        // read/write, read/write, read/write, ...
        // close src
        // close dst
        if (log)
            log->Printf("[GetFile] Using block by block transfer....\n");
        Error error;
        user_id_t fd_src = OpenFile (source,
                                     File::eOpenOptionRead,
                                     lldb::eFilePermissionsFileDefault,
                                     error);

        if (fd_src == UINT64_MAX)
            return Error("unable to open source file");

        uint32_t permissions = 0;
        error = GetFilePermissions(source, permissions);

        if (permissions == 0)
            permissions = lldb::eFilePermissionsFileDefault;

        user_id_t fd_dst = FileCache::GetInstance().OpenFile(
            destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, permissions,
            error);

        if (fd_dst == UINT64_MAX)
        {
            if (error.Success())
                error.SetErrorString("unable to open destination file");
        }

        if (error.Success())
        {
            lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
            uint64_t offset = 0;
            error.Clear();
            while (error.Success())
            {
                const uint64_t n_read = ReadFile (fd_src,
                                                  offset,
                                                  buffer_sp->GetBytes(),
                                                  buffer_sp->GetByteSize(),
                                                  error);
                if (error.Fail())
                    break;
                if (n_read == 0)
                    break;
                if (FileCache::GetInstance().WriteFile(fd_dst, offset, buffer_sp->GetBytes(), n_read, error) != n_read)
                {
                    if (!error.Fail())
                        error.SetErrorString("unable to write to destination file");
                    break;
                }
                offset += n_read;
            }
        }
        // Ignore the close error of src.
        if (fd_src != UINT64_MAX)
            CloseFile(fd_src, error);
        // And close the dst file descriptot.
        if (fd_dst != UINT64_MAX && !FileCache::GetInstance().CloseFile(fd_dst, error))
        {
            if (!error.Fail())
                error.SetErrorString("unable to close destination file");

        }
        return error;
    }
    return Platform::GetFile(source,destination);
}
Example #10
0
lldb_private::Error
PlatformPOSIX::PutFile (const lldb_private::FileSpec& source,
                         const lldb_private::FileSpec& destination,
                         uint32_t uid,
                         uint32_t gid)
{
    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));

    if (IsHost())
    {
        if (FileSpec::Equal(source, destination, true))
            return Error();
        // cp src dst
        // chown uid:gid dst
        std::string src_path (source.GetPath());
        if (src_path.empty())
            return Error("unable to get file path for source");
        std::string dst_path (destination.GetPath());
        if (dst_path.empty())
            return Error("unable to get file path for destination");
        StreamString command;
        command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
        int status;
        RunShellCommand(command.GetData(),
                        NULL,
                        &status,
                        NULL,
                        NULL,
                        10);
        if (status != 0)
            return Error("unable to perform copy");
        if (uid == UINT32_MAX && gid == UINT32_MAX)
            return Error();
        if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
            return Error("unable to perform chown");
        return Error();
    }
    else if (m_remote_platform_sp)
    {
        if (GetSupportsRSync())
        {
            std::string src_path (source.GetPath());
            if (src_path.empty())
                return Error("unable to get file path for source");
            std::string dst_path (destination.GetPath());
            if (dst_path.empty())
                return Error("unable to get file path for destination");
            StreamString command;
            if (GetIgnoresRemoteHostname())
            {
                if (!GetRSyncPrefix())
                    command.Printf("rsync %s %s %s",
                                   GetRSyncOpts(),
                                   src_path.c_str(),
                                   dst_path.c_str());
                else
                    command.Printf("rsync %s %s %s%s",
                                   GetRSyncOpts(),
                                   src_path.c_str(),
                                   GetRSyncPrefix(),
                                   dst_path.c_str());
            }
            else
                command.Printf("rsync %s %s %s:%s",
                               GetRSyncOpts(),
                               src_path.c_str(),
                               GetHostname(),
                               dst_path.c_str());
            if (log)
                log->Printf("[PutFile] Running command: %s\n", command.GetData());
            int retcode;
            Host::RunShellCommand(command.GetData(),
                                  NULL,
                                  &retcode,
                                  NULL,
                                  NULL,
                                  60);
            if (retcode == 0)
            {
                // Don't chown a local file for a remote system
//                if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
//                    return Error("unable to perform chown");
                return Error();
            }
            // if we are still here rsync has failed - let's try the slow way before giving up
        }
    }
    return Platform::PutFile(source,destination,uid,gid);
}