diff options
Diffstat (limited to 'source/Core/DataBufferMemoryMap.cpp')
-rw-r--r-- | source/Core/DataBufferMemoryMap.cpp | 398 |
1 files changed, 179 insertions, 219 deletions
diff --git a/source/Core/DataBufferMemoryMap.cpp b/source/Core/DataBufferMemoryMap.cpp index 48fe9e58d07d..70e8a394f69e 100644 --- a/source/Core/DataBufferMemoryMap.cpp +++ b/source/Core/DataBufferMemoryMap.cpp @@ -17,7 +17,7 @@ #define MAP_EXTRA_HOST_READ_FLAGS 0 -#if defined (__APPLE__) +#if defined(__APPLE__) //---------------------------------------------------------------------- // Newer versions of MacOSX have a flag that will allow us to read from // binaries whose code signature is invalid without crashing by using @@ -27,12 +27,12 @@ // MAP_RESILIENT_MEDIA flag. //---------------------------------------------------------------------- #if defined(MAP_RESILIENT_CODESIGN) - #undef MAP_EXTRA_HOST_READ_FLAGS - #if defined(MAP_RESILIENT_MEDIA) - #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA - #else - #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN - #endif +#undef MAP_EXTRA_HOST_READ_FLAGS +#if defined(MAP_RESILIENT_MEDIA) +#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA +#else +#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN +#endif #endif // #if defined(MAP_RESILIENT_CODESIGN) #endif // #if defined (__APPLE__) @@ -47,10 +47,10 @@ // Project includes #include "lldb/Core/DataBufferMemoryMap.h" #include "lldb/Core/Error.h" +#include "lldb/Core/Log.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Core/Log.h" using namespace lldb; using namespace lldb_private; @@ -58,75 +58,53 @@ using namespace lldb_private; //---------------------------------------------------------------------- // Default Constructor //---------------------------------------------------------------------- -DataBufferMemoryMap::DataBufferMemoryMap() : - m_mmap_addr(nullptr), - m_mmap_size(0), - m_data(nullptr), - m_size(0) -{ -} +DataBufferMemoryMap::DataBufferMemoryMap() + : m_mmap_addr(nullptr), m_mmap_size(0), m_data(nullptr), m_size(0) {} //---------------------------------------------------------------------- // Virtual destructor since this class inherits from a pure virtual // base class. //---------------------------------------------------------------------- -DataBufferMemoryMap::~DataBufferMemoryMap() -{ - Clear(); -} +DataBufferMemoryMap::~DataBufferMemoryMap() { Clear(); } //---------------------------------------------------------------------- // Return a pointer to the bytes owned by this object, or nullptr if // the object contains no bytes. //---------------------------------------------------------------------- -uint8_t * -DataBufferMemoryMap::GetBytes() -{ - return m_data; -} +uint8_t *DataBufferMemoryMap::GetBytes() { return m_data; } //---------------------------------------------------------------------- // Return a const pointer to the bytes owned by this object, or nullptr // if the object contains no bytes. //---------------------------------------------------------------------- -const uint8_t * -DataBufferMemoryMap::GetBytes() const -{ - return m_data; -} +const uint8_t *DataBufferMemoryMap::GetBytes() const { return m_data; } //---------------------------------------------------------------------- // Return the number of bytes this object currently contains. //---------------------------------------------------------------------- -uint64_t -DataBufferMemoryMap::GetByteSize() const -{ - return m_size; -} +uint64_t DataBufferMemoryMap::GetByteSize() const { return m_size; } //---------------------------------------------------------------------- // Reverts this object to an empty state by unmapping any memory // that is currently owned. //---------------------------------------------------------------------- -void -DataBufferMemoryMap::Clear() -{ - if (m_mmap_addr != nullptr) - { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP)); - if (log) - log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %" PRIu64 "", (void *)m_mmap_addr, - (uint64_t)m_mmap_size); +void DataBufferMemoryMap::Clear() { + if (m_mmap_addr != nullptr) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP)); + if (log) + log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size " + "= %" PRIu64 "", + (void *)m_mmap_addr, (uint64_t)m_mmap_size); #ifdef _WIN32 - UnmapViewOfFile(m_mmap_addr); + UnmapViewOfFile(m_mmap_addr); #else - ::munmap((void *)m_mmap_addr, m_mmap_size); + ::munmap((void *)m_mmap_addr, m_mmap_size); #endif - m_mmap_addr = nullptr; - m_mmap_size = 0; - m_data = nullptr; - m_size = 0; - } + m_mmap_addr = nullptr; + m_mmap_size = 0; + m_data = nullptr; + m_size = 0; + } } //---------------------------------------------------------------------- @@ -137,48 +115,41 @@ DataBufferMemoryMap::Clear() // Returns the number of bytes mapped starting from the requested // offset. //---------------------------------------------------------------------- -size_t -DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec, - lldb::offset_t offset, - size_t length, - bool writeable) -{ - if (filespec != nullptr) - { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP)); - if (log) - { - log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i", - filespec->GetPath().c_str(), - offset, - (uint64_t)length, - writeable); - } - char path[PATH_MAX]; - if (filespec->GetPath(path, sizeof(path))) - { - uint32_t options = File::eOpenOptionRead; - if (writeable) - options |= File::eOpenOptionWrite; +size_t DataBufferMemoryMap::MemoryMapFromFileSpec(const FileSpec *filespec, + lldb::offset_t offset, + size_t length, + bool writeable) { + if (filespec != nullptr) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP)); + if (log) { + log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", " + "offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i", + filespec->GetPath().c_str(), offset, (uint64_t)length, + writeable); + } + char path[PATH_MAX]; + if (filespec->GetPath(path, sizeof(path))) { + uint32_t options = File::eOpenOptionRead; + if (writeable) + options |= File::eOpenOptionWrite; - File file; - Error error (file.Open(path, options)); - if (error.Success()) - { - const bool fd_is_file = true; - return MemoryMapFromFileDescriptor (file.GetDescriptor(), offset, length, writeable, fd_is_file); - } - } + File file; + Error error(file.Open(path, options)); + if (error.Success()) { + const bool fd_is_file = true; + return MemoryMapFromFileDescriptor(file.GetDescriptor(), offset, length, + writeable, fd_is_file); + } } - // We should only get here if there was an error - Clear(); - return 0; + } + // We should only get here if there was an error + Clear(); + return 0; } #ifdef _WIN32 static size_t win32memmapalignment = 0; -void LoadWin32MemMapAlignment () -{ +void LoadWin32MemMapAlignment() { SYSTEM_INFO data; GetSystemInfo(&data); win32memmapalignment = data.dwAllocationGranularity; @@ -197,151 +168,140 @@ void LoadWin32MemMapAlignment () // RETURNS // Number of bytes mapped starting from the requested offset. //---------------------------------------------------------------------- -size_t -DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, - lldb::offset_t offset, - size_t length, - bool writeable, - bool fd_is_file) -{ - Clear(); - if (fd >= 0) - { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP|LIBLLDB_LOG_VERBOSE)); - if (log) - { - log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i, fd_is_file=%i)", - fd, - offset, - (uint64_t)length, - writeable, - fd_is_file); - } +size_t DataBufferMemoryMap::MemoryMapFromFileDescriptor(int fd, + lldb::offset_t offset, + size_t length, + bool writeable, + bool fd_is_file) { + Clear(); + if (fd >= 0) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP | + LIBLLDB_LOG_VERBOSE)); + if (log) { + log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, " + "offset=0x%" PRIx64 ", length=0x%" PRIx64 + ", writeable=%i, fd_is_file=%i)", + fd, offset, (uint64_t)length, writeable, fd_is_file); + } #ifdef _WIN32 - HANDLE handle = (HANDLE)_get_osfhandle(fd); - DWORD file_size_low, file_size_high; - file_size_low = GetFileSize(handle, &file_size_high); - const lldb::offset_t file_size = llvm::Make_64(file_size_high, file_size_low); - const lldb::offset_t max_bytes_available = file_size - offset; - const size_t max_bytes_mappable = (size_t)std::min<lldb::offset_t>(SIZE_MAX, max_bytes_available); - if (length == SIZE_MAX || length > max_bytes_mappable) - { - // Cap the length if too much data was requested - length = max_bytes_mappable; - } + HANDLE handle = (HANDLE)_get_osfhandle(fd); + DWORD file_size_low, file_size_high; + file_size_low = GetFileSize(handle, &file_size_high); + const lldb::offset_t file_size = + llvm::Make_64(file_size_high, file_size_low); + const lldb::offset_t max_bytes_available = file_size - offset; + const size_t max_bytes_mappable = + (size_t)std::min<lldb::offset_t>(SIZE_MAX, max_bytes_available); + if (length == SIZE_MAX || length > max_bytes_mappable) { + // Cap the length if too much data was requested + length = max_bytes_mappable; + } - if (length > 0) - { - HANDLE fileMapping = CreateFileMapping(handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY, file_size_high, file_size_low, nullptr); - if (fileMapping != nullptr) - { - if (win32memmapalignment == 0) LoadWin32MemMapAlignment(); - lldb::offset_t realoffset = offset; - lldb::offset_t delta = 0; - if (realoffset % win32memmapalignment != 0) { - realoffset = realoffset / win32memmapalignment * win32memmapalignment; - delta = offset - realoffset; - } + if (length > 0) { + HANDLE fileMapping = CreateFileMapping( + handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY, + file_size_high, file_size_low, nullptr); + if (fileMapping != nullptr) { + if (win32memmapalignment == 0) + LoadWin32MemMapAlignment(); + lldb::offset_t realoffset = offset; + lldb::offset_t delta = 0; + if (realoffset % win32memmapalignment != 0) { + realoffset = realoffset / win32memmapalignment * win32memmapalignment; + delta = offset - realoffset; + } - LPVOID data = MapViewOfFile(fileMapping, writeable ? FILE_MAP_WRITE : FILE_MAP_READ, 0, realoffset, length + delta); - m_mmap_addr = (uint8_t *)data; - if (!data) { - Error error; - error.SetErrorToErrno (); - } else { - m_data = m_mmap_addr + delta; - m_size = length; - } - CloseHandle(fileMapping); - } + LPVOID data = MapViewOfFile(fileMapping, + writeable ? FILE_MAP_WRITE : FILE_MAP_READ, + 0, realoffset, length + delta); + m_mmap_addr = (uint8_t *)data; + if (!data) { + Error error; + error.SetErrorToErrno(); + } else { + m_data = m_mmap_addr + delta; + m_size = length; } + CloseHandle(fileMapping); + } + } #else - struct stat stat; - if (::fstat(fd, &stat) == 0) - { - if (S_ISREG(stat.st_mode) && - (stat.st_size > static_cast<off_t>(offset))) - { - const size_t max_bytes_available = stat.st_size - offset; - if (length == SIZE_MAX) - { - length = max_bytes_available; - } - else if (length > max_bytes_available) - { - // Cap the length if too much data was requested - length = max_bytes_available; - } + struct stat stat; + if (::fstat(fd, &stat) == 0) { + if (S_ISREG(stat.st_mode) && + (stat.st_size > static_cast<off_t>(offset))) { + const size_t max_bytes_available = stat.st_size - offset; + if (length == SIZE_MAX) { + length = max_bytes_available; + } else if (length > max_bytes_available) { + // Cap the length if too much data was requested + length = max_bytes_available; + } - if (length > 0) - { - int prot = PROT_READ; - int flags = MAP_PRIVATE; - if (writeable) - prot |= PROT_WRITE; - else - flags |= MAP_EXTRA_HOST_READ_FLAGS; + if (length > 0) { + int prot = PROT_READ; + int flags = MAP_PRIVATE; + if (writeable) + prot |= PROT_WRITE; + else + flags |= MAP_EXTRA_HOST_READ_FLAGS; - if (fd_is_file) - flags |= MAP_FILE; + if (fd_is_file) + flags |= MAP_FILE; - m_mmap_addr = (uint8_t *)::mmap(nullptr, length, prot, flags, fd, offset); - Error error; + m_mmap_addr = + (uint8_t *)::mmap(nullptr, length, prot, flags, fd, offset); + Error error; - if (m_mmap_addr == (void*)-1) - { - error.SetErrorToErrno (); - if (error.GetError() == EINVAL) - { - // We may still have a shot at memory mapping if we align things correctly - size_t page_offset = offset % HostInfo::GetPageSize(); - if (page_offset != 0) - { - m_mmap_addr = (uint8_t *)::mmap(nullptr, length + page_offset, prot, flags, fd, offset - page_offset); - if (m_mmap_addr == (void*)-1) - { - // Failed to map file - m_mmap_addr = nullptr; - } - else if (m_mmap_addr != nullptr) - { - // We recovered and were able to memory map - // after we aligned things to page boundaries + if (m_mmap_addr == (void *)-1) { + error.SetErrorToErrno(); + if (error.GetError() == EINVAL) { + // We may still have a shot at memory mapping if we align things + // correctly + size_t page_offset = offset % HostInfo::GetPageSize(); + if (page_offset != 0) { + m_mmap_addr = + (uint8_t *)::mmap(nullptr, length + page_offset, prot, + flags, fd, offset - page_offset); + if (m_mmap_addr == (void *)-1) { + // Failed to map file + m_mmap_addr = nullptr; + } else if (m_mmap_addr != nullptr) { + // We recovered and were able to memory map + // after we aligned things to page boundaries - // Save the actual mmap'ed size - m_mmap_size = length + page_offset; - // Our data is at an offset into the mapped data - m_data = m_mmap_addr + page_offset; - // Our pretend size is the size that was requested - m_size = length; - } - } - } - if (error.GetError() == ENOMEM) - { - error.SetErrorStringWithFormat("could not allocate %" PRId64 " bytes of memory to mmap in file", (uint64_t) length); - } - } - else - { - // We were able to map the requested data in one chunk - // where our mmap and actual data are the same. - m_mmap_size = length; - m_data = m_mmap_addr; - m_size = length; - } - - if (log) - { - log->Printf( - "DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = %p, m_mmap_size = %" PRIu64 - ", error = %s", - (void *)m_mmap_addr, (uint64_t)m_mmap_size, error.AsCString()); - } + // Save the actual mmap'ed size + m_mmap_size = length + page_offset; + // Our data is at an offset into the mapped data + m_data = m_mmap_addr + page_offset; + // Our pretend size is the size that was requested + m_size = length; } + } } + if (error.GetError() == ENOMEM) { + error.SetErrorStringWithFormat("could not allocate %" PRId64 + " bytes of memory to mmap in file", + (uint64_t)length); + } + } else { + // We were able to map the requested data in one chunk + // where our mmap and actual data are the same. + m_mmap_size = length; + m_data = m_mmap_addr; + m_size = length; + } + + if (log) { + log->Printf( + "DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = " + "%p, m_mmap_size = %" PRIu64 ", error = %s", + (void *)m_mmap_addr, (uint64_t)m_mmap_size, error.AsCString()); + } } -#endif + } } - return GetByteSize (); +#endif + } + return GetByteSize(); } |