1c00cf4a0SZachary Turner //===-- FileCache.cpp -------------------------------------------*- C++ -*-===// 2c00cf4a0SZachary Turner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c00cf4a0SZachary Turner // 7c00cf4a0SZachary Turner //===----------------------------------------------------------------------===// 8c00cf4a0SZachary Turner 9c00cf4a0SZachary Turner #include "lldb/Host/FileCache.h" 10c00cf4a0SZachary Turner 11c00cf4a0SZachary Turner #include "lldb/Host/File.h" 1250bc1ed2SJonas Devlieghere #include "lldb/Host/FileSystem.h" 13c00cf4a0SZachary Turner 14c00cf4a0SZachary Turner using namespace lldb; 15c00cf4a0SZachary Turner using namespace lldb_private; 16c00cf4a0SZachary Turner 17c00cf4a0SZachary Turner FileCache *FileCache::m_instance = nullptr; 18c00cf4a0SZachary Turner 19b9c1b51eSKate Stone FileCache &FileCache::GetInstance() { 20c00cf4a0SZachary Turner if (m_instance == nullptr) 21c00cf4a0SZachary Turner m_instance = new FileCache(); 22c00cf4a0SZachary Turner 23c00cf4a0SZachary Turner return *m_instance; 24c00cf4a0SZachary Turner } 25c00cf4a0SZachary Turner 26b9c1b51eSKate Stone lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, 2797206d57SZachary Turner uint32_t mode, Status &error) { 2850bc1ed2SJonas Devlieghere if (!file_spec) { 29c00cf4a0SZachary Turner error.SetErrorString("empty path"); 30c00cf4a0SZachary Turner return UINT64_MAX; 31c00cf4a0SZachary Turner } 32*2fce1137SLawrence D'Anna auto file = FileSystem::Instance().Open(file_spec, flags, mode); 33*2fce1137SLawrence D'Anna if (!file) { 34*2fce1137SLawrence D'Anna error = file.takeError(); 35c00cf4a0SZachary Turner return UINT64_MAX; 36*2fce1137SLawrence D'Anna } 37*2fce1137SLawrence D'Anna lldb::user_id_t fd = file.get()->GetDescriptor(); 38*2fce1137SLawrence D'Anna m_cache[fd] = std::move(file.get()); 39c00cf4a0SZachary Turner return fd; 40c00cf4a0SZachary Turner } 41c00cf4a0SZachary Turner 4297206d57SZachary Turner bool FileCache::CloseFile(lldb::user_id_t fd, Status &error) { 43b9c1b51eSKate Stone if (fd == UINT64_MAX) { 44c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor"); 45c00cf4a0SZachary Turner return false; 46c00cf4a0SZachary Turner } 47c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd); 48b9c1b51eSKate Stone if (pos == m_cache.end()) { 49c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 50c00cf4a0SZachary Turner return false; 51c00cf4a0SZachary Turner } 52*2fce1137SLawrence D'Anna FileUP &file_up = pos->second; 53*2fce1137SLawrence D'Anna if (!file_up) { 54c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file"); 55c00cf4a0SZachary Turner return false; 56c00cf4a0SZachary Turner } 57*2fce1137SLawrence D'Anna error = file_up->Close(); 58c00cf4a0SZachary Turner m_cache.erase(pos); 59c00cf4a0SZachary Turner return error.Success(); 60c00cf4a0SZachary Turner } 61c00cf4a0SZachary Turner 62b9c1b51eSKate Stone uint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, 6397206d57SZachary Turner const void *src, uint64_t src_len, 6497206d57SZachary Turner Status &error) { 65b9c1b51eSKate Stone if (fd == UINT64_MAX) { 66c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor"); 67c00cf4a0SZachary Turner return UINT64_MAX; 68c00cf4a0SZachary Turner } 69c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd); 70b9c1b51eSKate Stone if (pos == m_cache.end()) { 71c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 72c00cf4a0SZachary Turner return false; 73c00cf4a0SZachary Turner } 74*2fce1137SLawrence D'Anna FileUP &file_up = pos->second; 75*2fce1137SLawrence D'Anna if (!file_up) { 76c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file"); 77c00cf4a0SZachary Turner return UINT64_MAX; 78c00cf4a0SZachary Turner } 79*2fce1137SLawrence D'Anna if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset || 80b9c1b51eSKate Stone error.Fail()) 81c00cf4a0SZachary Turner return UINT64_MAX; 82c00cf4a0SZachary Turner size_t bytes_written = src_len; 83*2fce1137SLawrence D'Anna error = file_up->Write(src, bytes_written); 84c00cf4a0SZachary Turner if (error.Fail()) 85c00cf4a0SZachary Turner return UINT64_MAX; 86c00cf4a0SZachary Turner return bytes_written; 87c00cf4a0SZachary Turner } 88c00cf4a0SZachary Turner 89b9c1b51eSKate Stone uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, 9097206d57SZachary Turner uint64_t dst_len, Status &error) { 91b9c1b51eSKate Stone if (fd == UINT64_MAX) { 92c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor"); 93c00cf4a0SZachary Turner return UINT64_MAX; 94c00cf4a0SZachary Turner } 95c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd); 96b9c1b51eSKate Stone if (pos == m_cache.end()) { 97c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 98c00cf4a0SZachary Turner return false; 99c00cf4a0SZachary Turner } 100*2fce1137SLawrence D'Anna FileUP &file_up = pos->second; 101*2fce1137SLawrence D'Anna if (!file_up) { 102c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file"); 103c00cf4a0SZachary Turner return UINT64_MAX; 104c00cf4a0SZachary Turner } 105*2fce1137SLawrence D'Anna if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset || 106b9c1b51eSKate Stone error.Fail()) 107c00cf4a0SZachary Turner return UINT64_MAX; 108c00cf4a0SZachary Turner size_t bytes_read = dst_len; 109*2fce1137SLawrence D'Anna error = file_up->Read(dst, bytes_read); 110c00cf4a0SZachary Turner if (error.Fail()) 111c00cf4a0SZachary Turner return UINT64_MAX; 112c00cf4a0SZachary Turner return bytes_read; 113c00cf4a0SZachary Turner } 114