Exemplo n.º 1
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();
}
Exemplo n.º 2
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();
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
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);
}