From 8339d18223eed408bfefcd00f649a2b13ccac52c Mon Sep 17 00:00:00 2001 From: Vladimir Chtchetkine Date: Thu, 25 Mar 2010 10:57:29 -0700 Subject: Move file I/O out of ELFF, abstracting them in platform-independent fasion. Change-Id: Ie8800dc96db810e352618bfea8243ab008ae9d2c --- elff/elf.h | 16 -------- elff/elf_file.cc | 92 ++++++---------------------------------------- elff/elf_file.h | 3 +- elff/elf_mapped_section.cc | 75 +++++++------------------------------ elff/elf_mapped_section.h | 3 +- 5 files changed, 30 insertions(+), 159 deletions(-) (limited to 'elff') diff --git a/elff/elf.h b/elff/elf.h index de92ba6..f3f5abc 100644 --- a/elff/elf.h +++ b/elff/elf.h @@ -27,22 +27,6 @@ extern "C" { // ELF file definitions //============================================================================= -#ifdef WIN32 -typedef HANDLE ELF_FILE_HANDLE; -#define INVALID_ELF_FILE_HANDLE INVALID_HANDLE_VALUE -#define close_elf_file_handle CloseHandle -#else // WIN32 -typedef int ELF_FILE_HANDLE; -#define INVALID_ELF_FILE_HANDLE -1 -#define close_elf_file_handle close -#endif // WIN32 - -/* Checks if ELF file handle is valid. */ -static inline bool -elfhandle_is_valid(ELF_FILE_HANDLE handle) { - return handle != INVALID_ELF_FILE_HANDLE; -} - /* * ELF format documentation uses Elf##_Xxx notation for data types, where * ## stands for CPU architecture (32, or 64 bit), and Xxx stands for a diff --git a/elff/elf_file.cc b/elff/elf_file.cc index 70ed81c..39aa371 100644 --- a/elff/elf_file.cc +++ b/elff/elf_file.cc @@ -43,7 +43,7 @@ ElfFile::ElfFile() allocator_(NULL), fixed_base_address_(0), is_exec_(0), - elf_handle_(INVALID_ELF_FILE_HANDLE), + elf_handle_((MapFile*)-1), sec_entry_size_(0) { } @@ -55,8 +55,8 @@ ElfFile::~ElfFile() { cu_to_del = next_cu_to_del; } - if (elfhandle_is_valid(elf_handle_)) { - close_elf_file_handle(elf_handle_); + if (mapfile_is_valid(elf_handle_)) { + mapfile_close(elf_handle_); } if (elf_file_path_ != NULL) { @@ -88,33 +88,12 @@ ElfFile* ElfFile::Create(const char* path) { /* * Open ELF file, and read its header (the largest one possible). */ - -#ifdef WIN32 - HANDLE file_handle = CreateFile(path, GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_RANDOM_ACCESS, NULL); - assert(file_handle != INVALID_HANDLE_VALUE); - if (file_handle == INVALID_HANDLE_VALUE) { - _set_errno(GetLastError()); - return NULL; - } - - DWORD read_bytes; - BOOL res = ReadFile(file_handle, &header, sizeof(header), &read_bytes, NULL); - CloseHandle(file_handle); - assert(res && read_bytes == sizeof(header)); - if (!res || read_bytes != sizeof(header)) { - _set_errno(GetLastError()); - return NULL; - } -#else // WIN32 - int file_handle = open(path, O_RDONLY | O_BINARY, 0); - assert(file_handle >= 0); - if (file_handle < 0) { + MapFile* file_handle = mapfile_open(path, O_RDONLY | O_BINARY, 0); + if (!mapfile_is_valid(file_handle)) { return NULL; } - const ssize_t read_bytes = read(file_handle, &header, sizeof(header)); - close(file_handle); + const ssize_t read_bytes = mapfile_read(file_handle, &header, sizeof(header)); + mapfile_close(file_handle); assert(read_bytes != -1 && read_bytes == sizeof(header)); if (read_bytes == -1 || read_bytes != sizeof(header)) { if (read_bytes != -1) { @@ -122,7 +101,6 @@ ElfFile* ElfFile::Create(const char* path) { } return NULL; } -#endif // WIN32 /* Lets see if this is an ELF file at all. */ if (memcmp(elf_hdr->e_ident, ELFMAG, SELFMAG) != 0) { @@ -186,25 +164,8 @@ bool ElfFile::initialize(const Elf_CommonHdr* elf_hdr, const char* path) { is_exec_ = elf_hdr->e_type == 2; /* Reopen file for further reads and mappings. */ -#ifdef WIN32 - elf_handle_ = CreateFile(elf_file_path_, GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_RANDOM_ACCESS, NULL); - assert(elf_handle_ != INVALID_HANDLE_VALUE); - if (elf_handle_ == INVALID_HANDLE_VALUE) { - _set_errno(GetLastError()); - return false; - } -#else // WIN32 - elf_handle_ = open(elf_file_path_, O_RDONLY | O_BINARY, 0); - assert(elf_handle_ >= 0); - if (elf_handle_ < 0) { - elf_handle_ = INVALID_ELF_FILE_HANDLE; - return false; - } -#endif // WIN32 - - return true; + elf_handle_ = mapfile_open(elf_file_path_, O_RDONLY | O_BINARY, 0); + return mapfile_is_valid(elf_handle_); } bool ElfFile::get_pc_address_info(Elf_Xword address, @@ -386,39 +347,10 @@ bool ElfFileImpl::initialize(const Elf_CommonHdr* elf_hdr, _set_errno(ENOMEM); return false; } -#ifdef WIN32 - LARGE_INTEGER convert; - convert.QuadPart = sec_table_off; - if ((SetFilePointer(elf_handle_, convert.LowPart, - &convert.HighPart, - FILE_BEGIN) == INVALID_SET_FILE_POINTER) && - (GetLastError() != NO_ERROR)) { - _set_errno(GetLastError()); - return false; - } - DWORD read_bytes; - BOOL res = - ReadFile(elf_handle_, sec_table_, sec_table_size, &read_bytes, NULL); - assert(res && read_bytes == sec_table_size); - if (!res || read_bytes != sec_table_size) { - _set_errno(GetLastError()); - return false; - } -#else // WIN32 - ssize_t res = lseek(elf_handle_, sec_table_off, SEEK_SET); - assert(res != -1); - if (res == -1) { - return false; - } - res = read(elf_handle_, sec_table_, sec_table_size); - assert(res != -1 && res == sec_table_size); - if (res == -1 || res != sec_table_size) { - if (res != -1) { - _set_errno(EINVAL); - } - return false; + if (mapfile_read_at(elf_handle_, sec_table_off, sec_table_, + sec_table_size) < 0) { + return false; } -#endif // WIN32 /* Map ELF's string section (must have one!). */ const Elf_Half str_sec_index = pull_val(header->e_shstrndx); diff --git a/elff/elf_file.h b/elff/elf_file.h index 6c57bde..c92fdfb 100644 --- a/elff/elf_file.h +++ b/elff/elf_file.h @@ -20,6 +20,7 @@ #include "dwarf_die.h" #include "elf_mapped_section.h" #include "elff_api.h" +#include "android/utils/mapfile.h" /* Encapsulates architecture-independent functionality of an ELF file. * @@ -510,7 +511,7 @@ class ElfFile { Elf_Xword fixed_base_address_; /* Handle to the ELF file represented with this instance. */ - ELF_FILE_HANDLE elf_handle_; + MapFile* elf_handle_; /* Path to the ELF file represented with this instance. */ char* elf_file_path_; diff --git a/elff/elf_mapped_section.cc b/elff/elf_mapped_section.cc index 46fc6b6..60cd21f 100644 --- a/elff/elf_mapped_section.cc +++ b/elff/elf_mapped_section.cc @@ -26,70 +26,23 @@ ElfMappedSection::ElfMappedSection() ElfMappedSection::~ElfMappedSection() { if (mapped_at_ != NULL) { -#ifdef WIN32 - UnmapViewOfFile(mapped_at_); -#else // WIN32 - munmap(mapped_at_, diff_ptr(mapped_at_, data_) + size_); -#endif // WIN32 + mapfile_unmap(mapped_at_, diff_ptr(mapped_at_, data_) + size_); } } -bool ElfMappedSection::map(ELF_FILE_HANDLE handle, +bool ElfMappedSection::map(MapFile* handle, Elf_Xword offset, Elf_Word size) { - /* Get the mask for mapping offset alignment. */ -#ifdef WIN32 - SYSTEM_INFO sys_info; - GetSystemInfo(&sys_info); - const Elf_Xword align_mask = sys_info.dwAllocationGranularity - 1; -#else // WIN32 - const Elf_Xword align_mask = getpagesize() - 1; -#endif // WIN32 - - /* Adjust mapping offset and mapping size accordingly to - * the mapping alignment requirements. */ - const Elf_Xword map_offset = offset & ~align_mask; - const Elf_Word map_size = static_cast(offset - map_offset + size); - - /* Make sure mapping size doesn't exceed 4G: may happen on 64-bit ELFs, if - * section size is close to 4G, while section offset is badly misaligned. */ - assert(map_size >= size); - if (map_size < size) { - _set_errno(EFBIG); - return false; - } - - /* Map the section. */ -#ifdef WIN32 - LARGE_INTEGER converter; - converter.QuadPart = map_offset + map_size; - HANDLE map_handle = CreateFileMapping(handle, NULL, PAGE_READONLY, - converter.HighPart, converter.LowPart, - NULL); - assert(map_handle != NULL); - if (map_handle != NULL) { - converter.QuadPart = map_offset; - mapped_at_ = MapViewOfFile(map_handle, FILE_MAP_READ, converter.HighPart, - converter.LowPart, map_size); - assert(mapped_at_ != NULL); - /* Memory mapping (if successful) will hold extra references to the - * mapping, so we can close it right after we mapped file view. */ - CloseHandle(map_handle); - } - if (mapped_at_ == NULL) { - _set_errno(GetLastError()); - return false; - } -#else // WIN32 - mapped_at_ = mmap(0, map_size, PROT_READ, MAP_SHARED, handle, map_offset); - assert(mapped_at_ != MAP_FAILED); - if (mapped_at_ == MAP_FAILED) { - return false; - } -#endif // WIN32 - - data_ = INC_CPTR(mapped_at_, offset - map_offset); - size_ = size; - - return true; + void* section_ptr; + size_t mapped_bytes; + mapped_at_ = mapfile_map(handle, offset, size, PROT_READ, + §ion_ptr, &mapped_bytes); + if (mapped_at_ == NULL) { + return false; + } + + data_ = section_ptr; + size_ = (Elf_Word)mapped_bytes; + + return true; } diff --git a/elff/elf_mapped_section.h b/elff/elf_mapped_section.h index 2f3ca56..7da608d 100644 --- a/elff/elf_mapped_section.h +++ b/elff/elf_mapped_section.h @@ -19,6 +19,7 @@ #define ELFF_ELF_MAPPED_SECTION_H_ #include "elf_defs.h" +#include "android/utils/mapfile.h" /* Encapsulates a section of an ELF file, mapped to memory. */ class ElfMappedSection { @@ -45,7 +46,7 @@ class ElfMappedSection { * NOTE: if section has already been mapped, this method immediately * returns with success. */ - bool map(ELF_FILE_HANDLE handle, Elf_Xword offset, Elf_Word size); + bool map(MapFile* handle, Elf_Xword offset, Elf_Word size); /* Checks if section has been mapped. */ bool is_mapped() const { -- cgit v1.1