diff options
author | Lang Hames <lhames@gmail.com> | 2019-05-08 02:11:07 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2019-05-08 02:11:07 +0000 |
commit | e4b4ab6d26f885f4b12624e5d375521070d8ba3d (patch) | |
tree | 96ade27def86606cec98d22008bebdcf22eafb90 /llvm/lib/Support | |
parent | 83eb9c5b588c4848a7ed08b10ad6c6fb1945eae6 (diff) | |
download | bcm5719-llvm-e4b4ab6d26f885f4b12624e5d375521070d8ba3d.tar.gz bcm5719-llvm-e4b4ab6d26f885f4b12624e5d375521070d8ba3d.zip |
[Support] Add error handling to sys::Process::getPageSize().
This patch changes the return type of sys::Process::getPageSize to
Expected<unsigned> to account for the fact that the underlying syscalls used to
obtain the page size may fail (see below).
For clients who use the page size as an optimization only this patch adds a new
method, getPageSizeEstimate, which calls through to getPageSize but discards
any error returned and substitues a "reasonable" page size estimate estimate
instead. All existing LLVM clients are updated to call getPageSizeEstimate
rather than getPageSize.
On Unix, sys::Process::getPageSize is implemented in terms of getpagesize or
sysconf, depending on which macros are set. The sysconf call is documented to
return -1 on failure. On Darwin getpagesize is implemented in terms of sysconf
and may also fail (though the manpage documentation does not mention this).
These failures have been observed in practice when highly restrictive sandbox
permissions have been applied. Without this patch, the result is that
getPageSize returns -1, which wreaks havoc on any subsequent code that was
assuming a sane page size value.
<rdar://problem/41654857>
Reviewers: dblaikie, echristo
Subscribers: kristina, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59107
llvm-svn: 360221
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/MemoryBuffer.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Support/Unix/Memory.inc | 4 | ||||
-rw-r--r-- | llvm/lib/Support/Unix/Path.inc | 2 | ||||
-rw-r--r-- | llvm/lib/Support/Unix/Process.inc | 5 | ||||
-rw-r--r-- | llvm/lib/Support/Windows/Process.inc | 2 |
5 files changed, 9 insertions, 6 deletions
diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp index 3f13d4d3552..92e39e118b9 100644 --- a/llvm/lib/Support/MemoryBuffer.cpp +++ b/llvm/lib/Support/MemoryBuffer.cpp @@ -417,7 +417,7 @@ static ErrorOr<std::unique_ptr<MB>> getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, bool IsVolatile) { - static int PageSize = sys::Process::getPageSize(); + static int PageSize = sys::Process::getPageSizeEstimate(); // Default is to map the full file. if (MapSize == uint64_t(-1)) { diff --git a/llvm/lib/Support/Unix/Memory.inc b/llvm/lib/Support/Unix/Memory.inc index b8f5df5f72e..affdb7e70d9 100644 --- a/llvm/lib/Support/Unix/Memory.inc +++ b/llvm/lib/Support/Unix/Memory.inc @@ -103,7 +103,7 @@ Memory::allocateMappedMemory(size_t NumBytes, // Use any near hint and the page size to set a page-aligned starting address uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) + NearBlock->size() : 0; - static const size_t PageSize = Process::getPageSize(); + static const size_t PageSize = Process::getPageSizeEstimate(); if (Start && Start % PageSize) Start += PageSize - Start % PageSize; @@ -149,7 +149,7 @@ Memory::releaseMappedMemory(MemoryBlock &M) { std::error_code Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { - static const size_t PageSize = Process::getPageSize(); + static const size_t PageSize = Process::getPageSizeEstimate(); if (M.Address == nullptr || M.Size == 0) return std::error_code(); diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index fb14422ba33..c2f78e79b87 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -786,7 +786,7 @@ const char *mapped_file_region::const_data() const { } int mapped_file_region::alignment() { - return Process::getPageSize(); + return Process::getPageSizeEstimate(); } std::error_code detail::directory_iterator_construct(detail::DirIterState &it, diff --git a/llvm/lib/Support/Unix/Process.inc b/llvm/lib/Support/Unix/Process.inc index 7c834f97114..78c123493e1 100644 --- a/llvm/lib/Support/Unix/Process.inc +++ b/llvm/lib/Support/Unix/Process.inc @@ -69,7 +69,7 @@ static std::pair<std::chrono::microseconds, std::chrono::microseconds> getRUsage // On Cygwin, getpagesize() returns 64k(AllocationGranularity) and // offset in mmap(3) should be aligned to the AllocationGranularity. -unsigned Process::getPageSize() { +Expected<unsigned> Process::getPageSize() { #if defined(HAVE_GETPAGESIZE) static const int page_size = ::getpagesize(); #elif defined(HAVE_SYSCONF) @@ -77,6 +77,9 @@ unsigned Process::getPageSize() { #else #error Cannot get the page size on this machine #endif + if (page_size == -1) + return errorCodeToError(std::error_code(errno, std::generic_category())); + return static_cast<unsigned>(page_size); } diff --git a/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc index b3c9aa0b83c..4b91f9f7fc6 100644 --- a/llvm/lib/Support/Windows/Process.inc +++ b/llvm/lib/Support/Windows/Process.inc @@ -56,7 +56,7 @@ static unsigned computePageSize() { return static_cast<unsigned>(info.dwPageSize); } -unsigned Process::getPageSize() { +Expected<unsigned> Process::getPageSize() { static unsigned Ret = computePageSize(); return Ret; } |