| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/fml/mapping.h" |
| |
| #include <algorithm> |
| #include <sstream> |
| |
| namespace fml { |
| |
| // FileMapping |
| |
| uint8_t* FileMapping::GetMutableMapping() { |
| return mutable_mapping_; |
| } |
| |
| std::unique_ptr<FileMapping> FileMapping::CreateReadOnly( |
| const std::string& path) { |
| return CreateReadOnly(OpenFile(path.c_str(), false, FilePermission::kRead), |
| ""); |
| } |
| |
| std::unique_ptr<FileMapping> FileMapping::CreateReadOnly( |
| const fml::UniqueFD& base_fd, |
| const std::string& sub_path) { |
| if (!sub_path.empty()) { |
| return CreateReadOnly( |
| OpenFile(base_fd, sub_path.c_str(), false, FilePermission::kRead), ""); |
| } |
| |
| auto mapping = std::make_unique<FileMapping>( |
| base_fd, std::initializer_list<Protection>{Protection::kRead}); |
| |
| if (!mapping->IsValid()) { |
| return nullptr; |
| } |
| |
| return mapping; |
| } |
| |
| std::unique_ptr<FileMapping> FileMapping::CreateReadExecute( |
| const std::string& path) { |
| return CreateReadExecute( |
| OpenFile(path.c_str(), false, FilePermission::kRead)); |
| } |
| |
| std::unique_ptr<FileMapping> FileMapping::CreateReadExecute( |
| const fml::UniqueFD& base_fd, |
| const std::string& sub_path) { |
| if (!sub_path.empty()) { |
| return CreateReadExecute( |
| OpenFile(base_fd, sub_path.c_str(), false, FilePermission::kRead), ""); |
| } |
| |
| auto mapping = std::make_unique<FileMapping>( |
| base_fd, std::initializer_list<Protection>{Protection::kRead, |
| Protection::kExecute}); |
| |
| if (!mapping->IsValid()) { |
| return nullptr; |
| } |
| |
| return mapping; |
| } |
| |
| // Data Mapping |
| |
| DataMapping::DataMapping(std::vector<uint8_t> data) : data_(std::move(data)) {} |
| |
| DataMapping::DataMapping(const std::string& string) |
| : data_(string.begin(), string.end()) {} |
| |
| DataMapping::~DataMapping() = default; |
| |
| size_t DataMapping::GetSize() const { |
| return data_.size(); |
| } |
| |
| const uint8_t* DataMapping::GetMapping() const { |
| return data_.data(); |
| } |
| |
| bool DataMapping::IsDontNeedSafe() const { |
| return false; |
| } |
| |
| // NonOwnedMapping |
| NonOwnedMapping::NonOwnedMapping(const uint8_t* data, |
| size_t size, |
| const ReleaseProc& release_proc, |
| bool dontneed_safe) |
| : data_(data), |
| size_(size), |
| release_proc_(release_proc), |
| dontneed_safe_(dontneed_safe) {} |
| |
| NonOwnedMapping::~NonOwnedMapping() { |
| if (release_proc_) { |
| release_proc_(data_, size_); |
| } |
| } |
| |
| size_t NonOwnedMapping::GetSize() const { |
| return size_; |
| } |
| |
| const uint8_t* NonOwnedMapping::GetMapping() const { |
| return data_; |
| } |
| |
| bool NonOwnedMapping::IsDontNeedSafe() const { |
| return dontneed_safe_; |
| } |
| |
| // MallocMapping |
| MallocMapping::MallocMapping() : data_(nullptr), size_(0) {} |
| |
| MallocMapping::MallocMapping(uint8_t* data, size_t size) |
| : data_(data), size_(size) {} |
| |
| MallocMapping::MallocMapping(fml::MallocMapping&& mapping) |
| : data_(mapping.data_), size_(mapping.size_) { |
| mapping.data_ = nullptr; |
| mapping.size_ = 0; |
| } |
| |
| MallocMapping::~MallocMapping() { |
| free(data_); |
| data_ = nullptr; |
| } |
| |
| MallocMapping MallocMapping::Copy(const void* begin, size_t length) { |
| auto result = |
| MallocMapping(reinterpret_cast<uint8_t*>(malloc(length)), length); |
| FML_CHECK(result.GetMapping() != nullptr); |
| memcpy(const_cast<uint8_t*>(result.GetMapping()), begin, length); |
| return result; |
| } |
| |
| size_t MallocMapping::GetSize() const { |
| return size_; |
| } |
| |
| const uint8_t* MallocMapping::GetMapping() const { |
| return data_; |
| } |
| |
| bool MallocMapping::IsDontNeedSafe() const { |
| return false; |
| } |
| |
| uint8_t* MallocMapping::Release() { |
| uint8_t* result = data_; |
| data_ = nullptr; |
| size_ = 0; |
| return result; |
| } |
| |
| // Symbol Mapping |
| |
| SymbolMapping::SymbolMapping(fml::RefPtr<fml::NativeLibrary> native_library, |
| const char* symbol_name) |
| : native_library_(std::move(native_library)) { |
| if (native_library_ && symbol_name != nullptr) { |
| mapping_ = native_library_->ResolveSymbol(symbol_name); |
| |
| if (mapping_ == nullptr) { |
| // Apparently, dart_bootstrap seems to account for the Mac behavior of |
| // requiring the underscore prefixed symbol name on non-Mac platforms as |
| // well. As a fallback, check the underscore prefixed variant of the |
| // symbol name and allow callers to not have handle this on a per platform |
| // toolchain quirk basis. |
| |
| std::stringstream underscore_symbol_name; |
| underscore_symbol_name << "_" << symbol_name; |
| mapping_ = |
| native_library_->ResolveSymbol(underscore_symbol_name.str().c_str()); |
| } |
| } |
| } |
| |
| SymbolMapping::~SymbolMapping() = default; |
| |
| size_t SymbolMapping::GetSize() const { |
| return 0; |
| } |
| |
| const uint8_t* SymbolMapping::GetMapping() const { |
| return mapping_; |
| } |
| |
| bool SymbolMapping::IsDontNeedSafe() const { |
| return true; |
| } |
| |
| } // namespace fml |