Merge "<arpa/nameser.h>: don't use __INTRODUCED_IN_64 in a defined(__LP64__) block."
diff --git a/libc/bionic/atexit.cpp b/libc/bionic/atexit.cpp
index 5dbf322..dae15e0 100644
--- a/libc/bionic/atexit.cpp
+++ b/libc/bionic/atexit.cpp
@@ -73,8 +73,8 @@
// restart concurrent __cxa_finalize passes.
uint64_t total_appends_;
- static size_t page_start_of_index(size_t idx) { return PAGE_START(idx * sizeof(AtexitEntry)); }
- static size_t page_end_of_index(size_t idx) { return PAGE_END(idx * sizeof(AtexitEntry)); }
+ static size_t page_start_of_index(size_t idx) { return page_start(idx * sizeof(AtexitEntry)); }
+ static size_t page_end_of_index(size_t idx) { return page_end(idx * sizeof(AtexitEntry)); }
// Recompact the array if it will save at least one page of memory at the end.
bool needs_recompaction() const {
@@ -167,7 +167,7 @@
// than one.
bool AtexitArray::next_capacity(size_t capacity, size_t* result) {
if (capacity == 0) {
- *result = PAGE_END(sizeof(AtexitEntry)) / sizeof(AtexitEntry);
+ *result = page_end(sizeof(AtexitEntry)) / sizeof(AtexitEntry);
return true;
}
size_t num_bytes;
diff --git a/libc/bionic/bionic_allocator.cpp b/libc/bionic/bionic_allocator.cpp
index 98183d4..53f944f 100644
--- a/libc/bionic/bionic_allocator.cpp
+++ b/libc/bionic/bionic_allocator.cpp
@@ -95,12 +95,10 @@
return result;
}
-BionicSmallObjectAllocator::BionicSmallObjectAllocator(uint32_t type,
- size_t block_size)
+BionicSmallObjectAllocator::BionicSmallObjectAllocator(uint32_t type, size_t block_size)
: type_(type),
block_size_(block_size),
- blocks_per_page_((PAGE_SIZE - sizeof(small_object_page_info)) /
- block_size),
+ blocks_per_page_((page_size() - sizeof(small_object_page_info)) / block_size),
free_pages_cnt_(0),
page_list_(nullptr) {}
@@ -157,14 +155,13 @@
if (page_list_ == page) {
page_list_ = page->next_page;
}
- munmap(page, PAGE_SIZE);
+ munmap(page, page_size());
free_pages_cnt_--;
}
void BionicSmallObjectAllocator::free(void* ptr) {
small_object_page_info* const page =
- reinterpret_cast<small_object_page_info*>(
- PAGE_START(reinterpret_cast<uintptr_t>(ptr)));
+ reinterpret_cast<small_object_page_info*>(page_start(reinterpret_cast<uintptr_t>(ptr)));
if (reinterpret_cast<uintptr_t>(ptr) % block_size_ != 0) {
async_safe_fatal("invalid pointer: %p (block_size=%zd)", ptr, block_size_);
@@ -192,14 +189,13 @@
}
void BionicSmallObjectAllocator::alloc_page() {
- void* const map_ptr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* const map_ptr =
+ mmap(nullptr, page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_ptr == MAP_FAILED) {
async_safe_fatal("mmap failed: %s", strerror(errno));
}
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE,
- "bionic_alloc_small_objects");
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, page_size(), "bionic_alloc_small_objects");
small_object_page_info* const page =
reinterpret_cast<small_object_page_info*>(map_ptr);
@@ -269,10 +265,10 @@
size_t header_size = __BIONIC_ALIGN(kPageInfoSize, align);
size_t allocated_size;
if (__builtin_add_overflow(header_size, size, &allocated_size) ||
- PAGE_END(allocated_size) < allocated_size) {
+ page_end(allocated_size) < allocated_size) {
async_safe_fatal("overflow trying to alloc %zu bytes", size);
}
- allocated_size = PAGE_END(allocated_size);
+ allocated_size = page_end(allocated_size);
void* map_ptr = mmap(nullptr, allocated_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
@@ -317,7 +313,7 @@
void* BionicAllocator::memalign(size_t align, size_t size) {
// The Bionic allocator only supports alignment up to one page, which is good
// enough for ELF TLS.
- align = MIN(align, PAGE_SIZE);
+ align = MIN(align, page_size());
align = MAX(align, 16);
if (!powerof2(align)) {
align = BIONIC_ROUND_UP_POWER_OF_2(align);
@@ -327,7 +323,7 @@
}
inline page_info* BionicAllocator::get_page_info_unchecked(void* ptr) {
- uintptr_t header_page = PAGE_START(reinterpret_cast<size_t>(ptr) - kPageInfoSize);
+ uintptr_t header_page = page_start(reinterpret_cast<size_t>(ptr) - kPageInfoSize);
return reinterpret_cast<page_info*>(header_page);
}
diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp
index 79893e3..077f310 100644
--- a/libc/bionic/bionic_elf_tls.cpp
+++ b/libc/bionic/bionic_elf_tls.cpp
@@ -34,10 +34,11 @@
#include <sys/param.h>
#include <unistd.h>
+#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
#include "private/ScopedRWLock.h"
#include "private/ScopedSignalBlocker.h"
#include "private/bionic_globals.h"
-#include "platform/bionic/macros.h"
#include "private/bionic_tls.h"
#include "pthread_internal.h"
@@ -81,7 +82,7 @@
return false;
}
// Bionic only respects TLS alignment up to one page.
- *alignment = MIN(*alignment, PAGE_SIZE);
+ *alignment = MIN(*alignment, page_size());
return true;
}
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 6433b59..3eb8c19 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -40,6 +40,7 @@
#include <unistd.h>
#include <async_safe/log.h>
+#include <platform/bionic/page.h>
#include <platform/bionic/reserved_signals.h>
#include <sys/system_properties.h>
@@ -80,7 +81,7 @@
size_t required_count = max - inline_fds;
size_t required_size = sizeof(FdTableOverflow) + required_count * sizeof(FdEntry);
- size_t aligned_size = __BIONIC_ALIGN(required_size, PAGE_SIZE);
+ size_t aligned_size = __BIONIC_ALIGN(required_size, page_size());
size_t aligned_count = (aligned_size - sizeof(FdTableOverflow)) / sizeof(FdEntry);
void* allocation =
diff --git a/libc/bionic/getpagesize.cpp b/libc/bionic/getpagesize.cpp
index 3a59900..da97633 100644
--- a/libc/bionic/getpagesize.cpp
+++ b/libc/bionic/getpagesize.cpp
@@ -27,9 +27,10 @@
*/
#include <unistd.h>
+#include "platform/bionic/page.h"
// Portable code should use sysconf(_SC_PAGE_SIZE) directly instead.
int getpagesize() {
// We dont use sysconf(3) here because that drags in stdio, which makes static binaries fat.
- return PAGE_SIZE;
+ return page_size();
}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index d64d402..3b0ab82 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -129,8 +129,8 @@
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr);
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz);
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr);
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz);
// Check return value here? What do we do if we fail?
mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_end - seg_page_start, PROT_READ);
@@ -354,9 +354,9 @@
__libc_shared_globals()->initial_memtag_stack = memtag_stack;
if (memtag_stack) {
- void* page_start =
- reinterpret_cast<void*>(PAGE_START(reinterpret_cast<uintptr_t>(stack_top)));
- if (mprotect(page_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
+ void* pg_start =
+ reinterpret_cast<void*>(page_start(reinterpret_cast<uintptr_t>(stack_top)));
+ if (mprotect(pg_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %s\n",
strerror(errno));
}
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index ed6b9c6..f05dcb8 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -32,6 +32,7 @@
#include <unistd.h>
#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
#include "private/ErrnoRestorer.h"
// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
@@ -46,7 +47,7 @@
}
// Prevent allocations large enough for `end - start` to overflow.
- size_t rounded = __BIONIC_ALIGN(size, PAGE_SIZE);
+ size_t rounded = __BIONIC_ALIGN(size, page_size());
if (rounded < size || rounded > PTRDIFF_MAX) {
errno = ENOMEM;
return MAP_FAILED;
diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp
index d7c9353..88ec829 100644
--- a/libc/bionic/mremap.cpp
+++ b/libc/bionic/mremap.cpp
@@ -33,12 +33,13 @@
#include <unistd.h>
#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
extern "C" void* __mremap(void*, size_t, size_t, int, void*);
void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
// prevent allocations large enough for `end - start` to overflow
- size_t rounded = __BIONIC_ALIGN(new_size, PAGE_SIZE);
+ size_t rounded = __BIONIC_ALIGN(new_size, page_size());
if (rounded < new_size || rounded > PTRDIFF_MAX) {
errno = ENOMEM;
return MAP_FAILED;
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index 89aa289..cdae72c 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -36,8 +36,9 @@
#include <async_safe/log.h>
-#include "private/bionic_defs.h"
+#include "platform/bionic/page.h"
#include "private/ErrnoRestorer.h"
+#include "private/bionic_defs.h"
#include "pthread_internal.h"
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
@@ -143,10 +144,10 @@
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
int pthread_attr_setstack(pthread_attr_t* attr, void* stack_base, size_t stack_size) {
- if ((stack_size & (PAGE_SIZE - 1) || stack_size < PTHREAD_STACK_MIN)) {
+ if ((stack_size & (page_size() - 1) || stack_size < PTHREAD_STACK_MIN)) {
return EINVAL;
}
- if (reinterpret_cast<uintptr_t>(stack_base) & (PAGE_SIZE - 1)) {
+ if (reinterpret_cast<uintptr_t>(stack_base) & (page_size() - 1)) {
return EINVAL;
}
attr->stack_base = stack_base;
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 844f9d8..b46c6cf 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -42,6 +42,7 @@
#include "platform/bionic/macros.h"
#include "platform/bionic/mte.h"
+#include "platform/bionic/page.h"
#include "private/ErrnoRestorer.h"
#include "private/ScopedRWLock.h"
#include "private/bionic_constants.h"
@@ -71,7 +72,7 @@
// Allocate a temporary bionic_tls that the dynamic linker's main thread can
// use while it's loading the initial set of ELF modules.
bionic_tls* __allocate_temp_bionic_tls() {
- size_t allocation_size = __BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE);
+ size_t allocation_size = __BIONIC_ALIGN(sizeof(bionic_tls), page_size());
void* allocation = mmap(nullptr, allocation_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
@@ -84,7 +85,7 @@
}
void __free_temp_bionic_tls(bionic_tls* tls) {
- munmap(tls, __BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE));
+ munmap(tls, __BIONIC_ALIGN(sizeof(bionic_tls), page_size()));
}
static void __init_alternate_signal_stack(pthread_internal_t* thread) {
@@ -203,12 +204,11 @@
return 0;
}
-
// Allocate a thread's primary mapping. This mapping includes static TLS and
// optionally a stack. Static TLS includes ELF TLS segments and the bionic_tls
// struct.
//
-// The stack_guard_size must be a multiple of the PAGE_SIZE.
+// The stack_guard_size must be a multiple of the page_size().
ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size) {
const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
@@ -220,7 +220,7 @@
// Align the result to a page size.
const size_t unaligned_size = mmap_size;
- mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE);
+ mmap_size = __BIONIC_ALIGN(mmap_size, page_size());
if (mmap_size < unaligned_size) return {};
// Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out a
@@ -271,9 +271,9 @@
if (attr->stack_base == nullptr) {
// The caller didn't provide a stack, so allocate one.
- // Make sure the guard size is a multiple of PAGE_SIZE.
+ // Make sure the guard size is a multiple of page_size().
const size_t unaligned_guard_size = attr->guard_size;
- attr->guard_size = __BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
+ attr->guard_size = __BIONIC_ALIGN(attr->guard_size, page_size());
if (attr->guard_size < unaligned_guard_size) return EAGAIN;
mapping = __allocate_thread_mapping(attr->stack_size, attr->guard_size);
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 1c06c9e..3906e2e 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -38,6 +38,7 @@
#include <time.h>
#include <unistd.h>
+#include "platform/bionic/page.h"
#include "private/bionic_tls.h"
static long __sysconf_rlimit(int resource) {
diff --git a/libc/bionic/sysinfo.cpp b/libc/bionic/sysinfo.cpp
index 1e4a0e8..79fd55e 100644
--- a/libc/bionic/sysinfo.cpp
+++ b/libc/bionic/sysinfo.cpp
@@ -33,8 +33,9 @@
#include <string.h>
#include <unistd.h>
-#include "private/get_cpu_count_from_string.h"
+#include "platform/bionic/page.h"
#include "private/ScopedReaddir.h"
+#include "private/get_cpu_count_from_string.h"
int __get_cpu_count(const char* sys_file) {
int cpu_count = 1;
@@ -64,11 +65,11 @@
long get_phys_pages() {
struct sysinfo si;
sysinfo(&si);
- return (static_cast<int64_t>(si.totalram) * si.mem_unit) / PAGE_SIZE;
+ return (static_cast<int64_t>(si.totalram) * si.mem_unit) / page_size();
}
long get_avphys_pages() {
struct sysinfo si;
sysinfo(&si);
- return ((static_cast<int64_t>(si.freeram) + si.bufferram) * si.mem_unit) / PAGE_SIZE;
+ return ((static_cast<int64_t>(si.freeram) + si.bufferram) * si.mem_unit) / page_size();
}
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
index 9e7df6d..8297580 100644
--- a/libc/include/bits/fortify/socket.h
+++ b/libc/include/bits/fortify/socket.h
@@ -30,15 +30,15 @@
#error "Never include this file directly; instead, include <sys/socket.h>"
#endif
-extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
+extern ssize_t __sendto_chk(int, const void* _Nonnull, size_t, size_t, int, const struct sockaddr* _Nullable,
socklen_t) __INTRODUCED_IN(26);
-ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
- socklen_t*) __INTRODUCED_IN(21);
+ssize_t __recvfrom_chk(int, void* _Nullable, size_t, size_t, int, struct sockaddr* _Nullable,
+ socklen_t* _Nullable) __INTRODUCED_IN(21);
#if defined(__BIONIC_FORTIFY)
__BIONIC_FORTIFY_INLINE
-ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addr_len)
+ssize_t recvfrom(int fd, void* _Nullable const buf __pass_object_size0, size_t len, int flags, struct sockaddr* _Nullable src_addr, socklen_t* _Nullable addr_len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'recvfrom' called with size bigger than buffer") {
@@ -53,7 +53,7 @@
}
__BIONIC_FORTIFY_INLINE
-ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
+ssize_t sendto(int fd, const void* _Nonnull const buf __pass_object_size0, size_t len, int flags, const struct sockaddr* _Nullable dest_addr, socklen_t addr_len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'sendto' called with size bigger than buffer") {
@@ -68,7 +68,7 @@
}
__BIONIC_FORTIFY_INLINE
-ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len, int flags)
+ssize_t recv(int socket, void* _Nullable const buf __pass_object_size0, size_t len, int flags)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'recv' called with size bigger than buffer") {
@@ -76,7 +76,7 @@
}
__BIONIC_FORTIFY_INLINE
-ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
+ssize_t send(int socket, const void* _Nonnull const buf __pass_object_size0, size_t len, int flags)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'send' called with size bigger than buffer") {
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index f668b9f..3dc1cca 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -30,20 +30,20 @@
#error "Never include this file directly; instead, include <string.h>"
#endif
-void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
-void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
-char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
-char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
-size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
-size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
+void* _Nullable __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
+void* _Nullable __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
+char* _Nonnull __stpncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t) __INTRODUCED_IN(21);
+char* _Nonnull __strncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t) __INTRODUCED_IN(21);
+size_t __strlcpy_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t) __INTRODUCED_IN(17);
+size_t __strlcat_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t) __INTRODUCED_IN(17);
#if defined(__BIONIC_FORTIFY)
-extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+extern void* _Nullable __memrchr_real(const void* _Nonnull, int, size_t) __RENAME(memrchr);
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+void* _Nonnull memcpy(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t copy_amount)
__diagnose_as_builtin(__builtin_memcpy, 1, 2, 3)
__overloadable {
return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
@@ -51,7 +51,7 @@
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
+void* _Nonnull memmove(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t len)
__diagnose_as_builtin(__builtin_memmove, 1, 2, 3)
__overloadable {
return __builtin___memmove_chk(dst, src, len, __bos0(dst));
@@ -61,7 +61,7 @@
#if defined(__USE_GNU)
#if __ANDROID_API__ >= 30
__BIONIC_FORTIFY_INLINE
-void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+void* _Nonnull mempcpy(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t copy_amount)
__diagnose_as_builtin(__builtin_mempcpy, 1, 2, 3)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
@@ -78,7 +78,7 @@
#endif /* __USE_GNU */
__BIONIC_FORTIFY_INLINE
-char* stpcpy(char* const dst __pass_object_size, const char* src)
+char* _Nonnull stpcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
__overloadable
__clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
"'stpcpy' called with string bigger than buffer") {
@@ -90,7 +90,7 @@
}
__BIONIC_FORTIFY_INLINE
-char* strcpy(char* const dst __pass_object_size, const char* src)
+char* _Nonnull strcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
__diagnose_as_builtin(__builtin_strcpy, 1, 2)
__overloadable
__clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
@@ -103,7 +103,7 @@
}
__BIONIC_FORTIFY_INLINE
-char* strcat(char* const dst __pass_object_size, const char* src)
+char* _Nonnull strcat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
__overloadable
__clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
"'strcat' called with string bigger than buffer") {
@@ -117,7 +117,7 @@
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-char* strncat(char* const dst __pass_object_size, const char* src, size_t n)
+char* _Nonnull strncat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t n)
__diagnose_as_builtin(__builtin_strncat, 1, 2, 3)
__overloadable {
return __builtin___strncat_chk(dst, src, n, __bos(dst));
@@ -126,7 +126,7 @@
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
+void* _Nonnull memset(void* _Nonnull const s __pass_object_size0, int c, size_t n) __overloadable
__diagnose_as_builtin(__builtin_memset, 1, 2, 3)
/* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
__clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
@@ -139,7 +139,7 @@
#if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
__BIONIC_FORTIFY_INLINE
-void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
+void* _Nullable memchr(const void* _Nonnull const s __pass_object_size, int c, size_t n) __overloadable {
size_t bos = __bos(s);
if (__bos_trivially_ge(bos, n)) {
@@ -150,7 +150,7 @@
}
__BIONIC_FORTIFY_INLINE
-void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+void* _Nullable __memrchr_fortify(const void* _Nonnull const __pass_object_size s, int c, size_t n) __overloadable {
size_t bos = __bos(s);
if (__bos_trivially_ge(bos, n)) {
@@ -164,7 +164,7 @@
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+char* _Nonnull stpncpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull const src __pass_object_size, size_t n)
__diagnose_as_builtin(__builtin_stpncpy, 1, 2, 3)
__overloadable {
size_t bos_dst = __bos(dst);
@@ -180,7 +180,7 @@
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+char* _Nonnull strncpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull const src __pass_object_size, size_t n)
__diagnose_as_builtin(__builtin_strncpy, 1, 2, 3)
__overloadable {
size_t bos_dst = __bos(dst);
@@ -196,7 +196,7 @@
#endif
__BIONIC_FORTIFY_INLINE
-size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size)
+size_t strlcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t size)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
"'strlcpy' called with size bigger than buffer") {
@@ -208,7 +208,7 @@
}
__BIONIC_FORTIFY_INLINE
-size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size)
+size_t strlcat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t size)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
"'strlcat' called with size bigger than buffer") {
@@ -221,13 +221,13 @@
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* const s __pass_object_size0) __overloadable {
+size_t strlen(const char* _Nonnull const s __pass_object_size0) __overloadable {
return __strlen_chk(s, __bos0(s));
}
#endif
__BIONIC_FORTIFY_INLINE
-char* strchr(const char* const s __pass_object_size, int c) __overloadable {
+char* _Nullable strchr(const char* _Nonnull const s __pass_object_size, int c) __overloadable {
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
size_t bos = __bos(s);
@@ -239,7 +239,7 @@
}
__BIONIC_FORTIFY_INLINE
-char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
+char* _Nullable strrchr(const char* _Nonnull const s __pass_object_size, int c) __overloadable {
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
size_t bos = __bos(s);
@@ -254,18 +254,18 @@
#if defined(__cplusplus)
extern "C++" {
__BIONIC_FORTIFY_INLINE
-void* memrchr(void* const __pass_object_size s, int c, size_t n) {
+void* _Nullable memrchr(void* _Nonnull const __pass_object_size s, int c, size_t n) {
return __memrchr_fortify(s, c, n);
}
__BIONIC_FORTIFY_INLINE
-const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
+const void* _Nullable memrchr(const void* _Nonnull const __pass_object_size s, int c, size_t n) {
return __memrchr_fortify(s, c, n);
}
}
#else
__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+void* _Nullable memrchr(const void* _Nonnull const __pass_object_size s, int c, size_t n) __overloadable {
return __memrchr_fortify(s, c, n);
}
#endif
diff --git a/libc/include/bits/fortify/strings.h b/libc/include/bits/fortify/strings.h
index 5515ef9..a36f02c 100644
--- a/libc/include/bits/fortify/strings.h
+++ b/libc/include/bits/fortify/strings.h
@@ -29,7 +29,7 @@
#if defined(__BIONIC_FORTIFY)
__BIONIC_FORTIFY_INLINE
-void __bionic_bcopy(const void *src, void* const dst __pass_object_size0, size_t len)
+void __bionic_bcopy(const void * _Nonnull src, void* _Nonnull const dst __pass_object_size0, size_t len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(dst), len),
"'bcopy' called with size bigger than buffer") {
@@ -44,7 +44,7 @@
}
__BIONIC_FORTIFY_INLINE
-void __bionic_bzero(void* const b __pass_object_size0, size_t len)
+void __bionic_bzero(void* _Nonnull const b __pass_object_size0, size_t len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(b), len),
"'bzero' called with size bigger than buffer") {
diff --git a/libc/include/complex.h b/libc/include/complex.h
index 6bbeda3..f205abd 100644
--- a/libc/include/complex.h
+++ b/libc/include/complex.h
@@ -117,7 +117,7 @@
/* 7.3.8.1 The cabs functions */
double cabs(double complex __z) __INTRODUCED_IN(23);
float cabsf(float complex __z) __INTRODUCED_IN(23);
-long double cabsl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
+long double cabsl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.8.2 The cpow functions */
double complex cpow(double complex __x, double complex __z) __INTRODUCED_IN(26);
float complex cpowf(float complex __x, float complex __z) __INTRODUCED_IN(26);
@@ -125,7 +125,7 @@
/* 7.3.8.3 The csqrt functions */
double complex csqrt(double complex __z) __INTRODUCED_IN(23);
float complex csqrtf(float complex __z) __INTRODUCED_IN(23);
-long double complex csqrtl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
+long double complex csqrtl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9 Manipulation functions */
/* 7.3.9.1 The carg functions */
@@ -143,7 +143,7 @@
/* 7.3.9.4 The cproj functions */
double complex cproj(double complex __z) __INTRODUCED_IN(23);
float complex cprojf(float complex __z) __INTRODUCED_IN(23);
-long double complex cprojl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
+long double complex cprojl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.5 The creal functions */
double creal(double complex __z) __INTRODUCED_IN(23);
float crealf(float complex __z) __INTRODUCED_IN(23);
diff --git a/libc/include/iconv.h b/libc/include/iconv.h
index 7cf36dc..794a292 100644
--- a/libc/include/iconv.h
+++ b/libc/include/iconv.h
@@ -54,7 +54,7 @@
*
* Available since API level 28.
*/
-iconv_t _Nonnull iconv_open(const char* _Nonnull __src_encoding, const char* _Nonnull __dst_encoding) __INTRODUCED_IN(28);
+iconv_t _Nonnull iconv_open(const char* _Nonnull __dst_encoding, const char* _Nonnull __src_encoding) __INTRODUCED_IN(28);
/**
* [iconv(3)](http://man7.org/linux/man-pages/man3/iconv.3.html) converts characters from one
diff --git a/libc/platform/bionic/android_unsafe_frame_pointer_chase.h b/libc/platform/bionic/android_unsafe_frame_pointer_chase.h
index 2b9a32f..406ad92 100644
--- a/libc/platform/bionic/android_unsafe_frame_pointer_chase.h
+++ b/libc/platform/bionic/android_unsafe_frame_pointer_chase.h
@@ -44,4 +44,4 @@
* take stack traces efficiently. Normal applications should use APIs such as libunwindstack or
* _Unwind_Backtrace.
*/
-extern "C" size_t android_unsafe_frame_pointer_chase(uintptr_t* buf, size_t num_entries);
+extern "C" size_t android_unsafe_frame_pointer_chase(uintptr_t* _Nonnull buf, size_t num_entries);
diff --git a/libc/platform/bionic/fdtrack.h b/libc/platform/bionic/fdtrack.h
index fe6ca84..7fc304a 100644
--- a/libc/platform/bionic/fdtrack.h
+++ b/libc/platform/bionic/fdtrack.h
@@ -43,6 +43,8 @@
ANDROID_FDTRACK_EVENT_TYPE_CLOSE,
};
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
struct android_fdtrack_event {
// File descriptor for which this event occurred.
int fd;
@@ -57,12 +59,15 @@
} create;
} data;
};
+#pragma clang diagnostic pop
// Callback invoked upon file descriptor creation/closure.
-typedef void (*android_fdtrack_hook_t)(struct android_fdtrack_event*);
+typedef void (*_Nullable android_fdtrack_hook_t)(struct android_fdtrack_event* _Nullable);
// Register a hook which is called to track fd lifecycle events.
-bool android_fdtrack_compare_exchange_hook(android_fdtrack_hook_t* expected, android_fdtrack_hook_t value) __INTRODUCED_IN(30);
+// Set value to null to disable tracking.
+bool android_fdtrack_compare_exchange_hook(android_fdtrack_hook_t* _Nonnull expected,
+ android_fdtrack_hook_t value) __INTRODUCED_IN(30);
// Enable/disable fdtrack *on the current thread*.
// This is primarily useful when performing operations which you don't want to track
diff --git a/libc/platform/bionic/macros.h b/libc/platform/bionic/macros.h
index 9e13e0d..93268c1 100644
--- a/libc/platform/bionic/macros.h
+++ b/libc/platform/bionic/macros.h
@@ -40,12 +40,12 @@
}
template <typename T>
-static inline T* align_down(T* p, size_t align) {
+static inline T* _Nonnull align_down(T* _Nonnull p, size_t align) {
return reinterpret_cast<T*>(align_down(reinterpret_cast<uintptr_t>(p), align));
}
template <typename T>
-static inline T* align_up(T* p, size_t align) {
+static inline T* _Nonnull align_up(T* _Nonnull p, size_t align) {
return reinterpret_cast<T*>(align_up(reinterpret_cast<uintptr_t>(p), align));
}
@@ -94,6 +94,6 @@
}
template <typename T>
-static inline T* untag_address(T* p) {
+static inline T* _Nonnull untag_address(T* _Nonnull p) {
return reinterpret_cast<T*>(untag_address(reinterpret_cast<uintptr_t>(p)));
}
diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h
index 3c290fc..0a6546e 100644
--- a/libc/platform/bionic/malloc.h
+++ b/libc/platform/bionic/malloc.h
@@ -33,7 +33,8 @@
#include <stdint.h>
// Structures for android_mallopt.
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
typedef struct {
// Pointer to the buffer allocated by a call to M_GET_MALLOC_LEAK_INFO.
uint8_t* buffer;
@@ -47,7 +48,7 @@
// The maximum number of backtrace entries.
size_t backtrace_size;
} android_mallopt_leak_info_t;
-
+#pragma clang diagnostic pop
// Opcodes for android_mallopt.
enum {
@@ -105,6 +106,8 @@
#define M_MEMTAG_STACK_IS_ON M_MEMTAG_STACK_IS_ON
};
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
typedef struct {
// The null-terminated name that the zygote is spawning. Because native
// SpecializeCommon (where the GWP-ASan mallopt() is called from) happens
@@ -147,9 +150,9 @@
Action desire = DONT_TURN_ON_UNLESS_OVERRIDDEN;
} android_mallopt_gwp_asan_options_t;
-
+#pragma clang diagnostic pop
// Manipulates bionic-specific handling of memory allocation APIs such as
// malloc. Only for use by the Android platform and APEXes.
//
// On success, returns true. On failure, returns false and sets errno.
-extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size);
+extern "C" bool android_mallopt(int opcode, void* _Nullable arg, size_t arg_size);
diff --git a/libc/platform/bionic/page.h b/libc/platform/bionic/page.h
index d063a98..5f4bb6f 100644
--- a/libc/platform/bionic/page.h
+++ b/libc/platform/bionic/page.h
@@ -16,15 +16,39 @@
#pragma once
-// Get PAGE_SIZE and PAGE_MASK.
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/auxv.h>
+
+// For PAGE_SIZE.
#include <sys/user.h>
+inline size_t page_size() {
+ /*
+ * PAGE_SIZE defines the maximum supported page size. Since 4096 is the
+ * minimum supported page size we can just let it be constant folded if it's
+ * also the maximum.
+ */
+#if PAGE_SIZE == 4096
+ return PAGE_SIZE;
+#else
+ static size_t size = getauxval(AT_PAGESZ);
+ return size;
+#endif
+}
+
// Returns the address of the page containing address 'x'.
-#define PAGE_START(x) ((x) & PAGE_MASK)
+inline uintptr_t page_start(uintptr_t x) {
+ return x & ~(page_size() - 1);
+}
// Returns the offset of address 'x' in its page.
-#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
+inline uintptr_t page_offset(uintptr_t x) {
+ return x & (page_size() - 1);
+}
// Returns the address of the next page after address 'x', unless 'x' is
// itself at the start of a page.
-#define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1))
+inline uintptr_t page_end(uintptr_t x) {
+ return page_start(x + page_size() - 1);
+}
diff --git a/libc/platform/scudo_platform_tls_slot.h b/libc/platform/scudo_platform_tls_slot.h
index 9d017c0..a86b828 100644
--- a/libc/platform/scudo_platform_tls_slot.h
+++ b/libc/platform/scudo_platform_tls_slot.h
@@ -30,6 +30,6 @@
#include "bionic/tls.h"
-inline uintptr_t *getPlatformAllocatorTlsSlot() {
+inline uintptr_t* _Nonnull getPlatformAllocatorTlsSlot() {
return reinterpret_cast<uintptr_t*>(&__get_tls()[TLS_SLOT_SANITIZER]);
}
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index 65f54a5..3133f1f 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -179,6 +179,10 @@
int size = 0;
bool fast = false;
c = *fmt++;
+ if (c == 'f') {
+ fast = true;
+ c = *fmt++;
+ }
while (is_digit(c)) {
APPEND_DIGIT(size, c);
c = *fmt++;
diff --git a/libc/stdio/vfwscanf.cpp b/libc/stdio/vfwscanf.cpp
index 14b1754..3df4a87 100644
--- a/libc/stdio/vfwscanf.cpp
+++ b/libc/stdio/vfwscanf.cpp
@@ -223,6 +223,10 @@
int size = 0;
bool fast = false;
c = *fmt++;
+ if (c == 'f') {
+ fast = true;
+ c = *fmt++;
+ }
while (is_digit(c)) {
APPEND_DIGIT(size, c);
c = *fmt++;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 17b574f..5c26944 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -962,7 +962,7 @@
}
// Check if it is properly stored
- if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
+ if (entry.method != kCompressStored || (entry.offset % page_size()) != 0) {
close(fd);
return -1;
}
@@ -1171,7 +1171,7 @@
"load_library(ns=%s, task=%s, flags=0x%x, realpath=%s, search_linked_namespaces=%d)",
ns->get_name(), name, rtld_flags, realpath.c_str(), search_linked_namespaces);
- if ((file_offset % PAGE_SIZE) != 0) {
+ if ((file_offset % page_size()) != 0) {
DL_OPEN_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
return false;
}
diff --git a/linker/linker_cfi.cpp b/linker/linker_cfi.cpp
index 6bc2615..247a25d 100644
--- a/linker/linker_cfi.cpp
+++ b/linker/linker_cfi.cpp
@@ -50,8 +50,8 @@
ShadowWrite(uint16_t* s, uint16_t* e) {
shadow_start = reinterpret_cast<char*>(s);
shadow_end = reinterpret_cast<char*>(e);
- aligned_start = reinterpret_cast<char*>(PAGE_START(reinterpret_cast<uintptr_t>(shadow_start)));
- aligned_end = reinterpret_cast<char*>(PAGE_END(reinterpret_cast<uintptr_t>(shadow_end)));
+ aligned_start = reinterpret_cast<char*>(page_start(reinterpret_cast<uintptr_t>(shadow_start)));
+ aligned_end = reinterpret_cast<char*>(page_end(reinterpret_cast<uintptr_t>(shadow_end)));
tmp_start =
reinterpret_cast<char*>(mmap(nullptr, aligned_end - aligned_start, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
@@ -204,7 +204,7 @@
shadow_start = reinterpret_cast<uintptr_t* (*)(uintptr_t)>(cfi_init)(p);
CHECK(shadow_start != nullptr);
CHECK(*shadow_start == p);
- mprotect(shadow_start, PAGE_SIZE, PROT_READ);
+ mprotect(shadow_start, page_size(), PROT_READ);
return true;
}
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 26e2228..f7c8ea9 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -580,8 +580,8 @@
}
ElfW(Addr) seg_start = phdr->p_vaddr + si->load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(seg_start + phdr->p_memsz);
- ElfW(Addr) seg_file_end = PAGE_END(seg_start + phdr->p_filesz);
+ ElfW(Addr) seg_page_end = page_end(seg_start + phdr->p_memsz);
+ ElfW(Addr) seg_file_end = page_end(seg_start + phdr->p_filesz);
if (seg_page_end > seg_file_end) {
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME,
diff --git a/linker/linker_mapped_file_fragment.cpp b/linker/linker_mapped_file_fragment.cpp
index cbe5f66..6be1b2b 100644
--- a/linker/linker_mapped_file_fragment.cpp
+++ b/linker/linker_mapped_file_fragment.cpp
@@ -29,6 +29,7 @@
#include "linker_mapped_file_fragment.h"
#include "linker_debug.h"
#include "linker_utils.h"
+#include "platform/bionic/page.h"
#include <inttypes.h>
#include <stdlib.h>
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 73cfced..97ae709 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -116,7 +116,7 @@
can only memory-map at page boundaries, this means that the bias is
computed as:
- load_bias = phdr0_load_address - PAGE_START(phdr0->p_vaddr)
+ load_bias = phdr0_load_address - page_start(phdr0->p_vaddr)
(NOTE: The value must be used as a 32-bit unsigned integer, to deal with
possible wrap around UINT32_MAX for possible large p_vaddr values).
@@ -124,11 +124,11 @@
And that the phdr0_load_address must start at a page boundary, with
the segment's real content starting at:
- phdr0_load_address + PAGE_OFFSET(phdr0->p_vaddr)
+ phdr0_load_address + page_offset(phdr0->p_vaddr)
Note that ELF requires the following condition to make the mmap()-ing work:
- PAGE_OFFSET(phdr0->p_vaddr) == PAGE_OFFSET(phdr0->p_offset)
+ page_offset(phdr0->p_vaddr) == page_offset(phdr0->p_offset)
The load_bias must be added to any p_vaddr value read from the ELF file to
determine the corresponding memory address.
@@ -529,8 +529,8 @@
min_vaddr = 0;
}
- min_vaddr = PAGE_START(min_vaddr);
- max_vaddr = PAGE_END(max_vaddr);
+ min_vaddr = page_start(min_vaddr);
+ max_vaddr = page_end(max_vaddr);
if (out_min_vaddr != nullptr) {
*out_min_vaddr = min_vaddr;
@@ -545,7 +545,7 @@
// program header table. Used to determine whether the file should be loaded at
// a specific virtual address alignment for use with huge pages.
size_t phdr_table_get_maximum_alignment(const ElfW(Phdr)* phdr_table, size_t phdr_count) {
- size_t maximum_alignment = PAGE_SIZE;
+ size_t maximum_alignment = page_size();
for (size_t i = 0; i < phdr_count; ++i) {
const ElfW(Phdr)* phdr = &phdr_table[i];
@@ -563,7 +563,7 @@
#if defined(__LP64__)
return maximum_alignment;
#else
- return PAGE_SIZE;
+ return page_size();
#endif
}
@@ -574,7 +574,7 @@
int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
// Reserve enough space to properly align the library's start address.
mapping_align = std::max(mapping_align, start_align);
- if (mapping_align == PAGE_SIZE) {
+ if (mapping_align == page_size()) {
void* mmap_ptr = mmap(nullptr, size, PROT_NONE, mmap_flags, -1, 0);
if (mmap_ptr == MAP_FAILED) {
return nullptr;
@@ -593,7 +593,7 @@
constexpr size_t kMaxGapUnits = 32;
// Allocate enough space so that the end of the desired region aligned up is still inside the
// mapping.
- size_t mmap_size = align_up(size, mapping_align) + mapping_align - PAGE_SIZE;
+ size_t mmap_size = align_up(size, mapping_align) + mapping_align - page_size();
uint8_t* mmap_ptr =
reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
if (mmap_ptr == MAP_FAILED) {
@@ -610,7 +610,7 @@
mapping_align = std::max(mapping_align, kGapAlignment);
gap_size =
kGapAlignment * (is_first_stage_init() ? 1 : arc4random_uniform(kMaxGapUnits - 1) + 1);
- mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - PAGE_SIZE;
+ mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - page_size();
mmap_ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
if (mmap_ptr == MAP_FAILED) {
return nullptr;
@@ -665,12 +665,12 @@
load_size_ - address_space->reserved_size, load_size_, name_.c_str());
return false;
}
- size_t start_alignment = PAGE_SIZE;
+ size_t start_alignment = page_size();
if (get_transparent_hugepages_supported() && get_application_target_sdk_version() >= 31) {
size_t maximum_alignment = phdr_table_get_maximum_alignment(phdr_table_, phdr_num_);
// Limit alignment to PMD size as other alignments reduce the number of
// bits available for ASLR for no benefit.
- start_alignment = maximum_alignment == kPmdSize ? kPmdSize : PAGE_SIZE;
+ start_alignment = maximum_alignment == kPmdSize ? kPmdSize : page_size();
}
start = ReserveWithAlignmentPadding(load_size_, kLibraryAlignment, start_alignment, &gap_start_,
&gap_size_);
@@ -706,8 +706,8 @@
ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
ElfW(Addr) seg_end = seg_start + phdr->p_memsz;
- ElfW(Addr) seg_page_start = PAGE_START(seg_start);
- ElfW(Addr) seg_page_end = PAGE_END(seg_end);
+ ElfW(Addr) seg_page_start = page_start(seg_start);
+ ElfW(Addr) seg_page_end = page_end(seg_end);
ElfW(Addr) seg_file_end = seg_start + phdr->p_filesz;
@@ -715,7 +715,7 @@
ElfW(Addr) file_start = phdr->p_offset;
ElfW(Addr) file_end = file_start + phdr->p_filesz;
- ElfW(Addr) file_page_start = PAGE_START(file_start);
+ ElfW(Addr) file_page_start = page_start(file_start);
ElfW(Addr) file_length = file_end - file_page_start;
if (file_size_ <= 0) {
@@ -768,11 +768,11 @@
// if the segment is writable, and does not end on a page boundary,
// zero-fill it until the page limit.
- if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) {
- memset(reinterpret_cast<void*>(seg_file_end), 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end));
+ if ((phdr->p_flags & PF_W) != 0 && page_offset(seg_file_end) > 0) {
+ memset(reinterpret_cast<void*>(seg_file_end), 0, page_size() - page_offset(seg_file_end));
}
- seg_file_end = PAGE_END(seg_file_end);
+ seg_file_end = page_end(seg_file_end);
// seg_file_end is now the first page address after the file
// content. If seg_end is larger, we need to zero anything
@@ -811,8 +811,8 @@
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
int prot = PFLAGS_TO_PROT(phdr->p_flags) | extra_prot_flags;
if ((prot & PROT_WRITE) != 0) {
@@ -912,8 +912,8 @@
// the program is likely to fail at runtime. So in effect the
// linker must only emit a PT_GNU_RELRO segment if it ensures
// that it starts on a page boundary.
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
seg_page_end - seg_page_start,
@@ -972,8 +972,8 @@
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
ssize_t size = seg_page_end - seg_page_start;
ssize_t written = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<void*>(seg_page_start), size));
@@ -1035,8 +1035,8 @@
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
char* file_base = static_cast<char*>(temp_mapping) + *file_offset;
char* mem_base = reinterpret_cast<char*>(seg_page_start);
@@ -1053,15 +1053,15 @@
while (match_offset < size) {
// Skip over dissimilar pages.
while (match_offset < size &&
- memcmp(mem_base + match_offset, file_base + match_offset, PAGE_SIZE) != 0) {
- match_offset += PAGE_SIZE;
+ memcmp(mem_base + match_offset, file_base + match_offset, page_size()) != 0) {
+ match_offset += page_size();
}
// Count similar pages.
size_t mismatch_offset = match_offset;
while (mismatch_offset < size &&
- memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, PAGE_SIZE) == 0) {
- mismatch_offset += PAGE_SIZE;
+ memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, page_size()) == 0) {
+ mismatch_offset += page_size();
}
// Map over similar pages.
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index 29110ed..cd03eed 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -169,12 +169,6 @@
return true;
}
-constexpr off64_t kPageMask = ~static_cast<off64_t>(PAGE_SIZE-1);
-
-off64_t page_start(off64_t offset) {
- return offset & kPageMask;
-}
-
bool safe_add(off64_t* out, off64_t a, size_t b) {
CHECK(a >= 0);
if (static_cast<uint64_t>(INT64_MAX - a) < b) {
@@ -185,10 +179,6 @@
return true;
}
-size_t page_offset(off64_t offset) {
- return static_cast<size_t>(offset & (PAGE_SIZE-1));
-}
-
void split_path(const char* path, const char* delimiters,
std::vector<std::string>* paths) {
if (path != nullptr && path[0] != 0) {
diff --git a/linker/linker_utils.h b/linker/linker_utils.h
index 5073b10..3049e53 100644
--- a/linker/linker_utils.h
+++ b/linker/linker_utils.h
@@ -55,7 +55,5 @@
std::string dirname(const char* path);
-off64_t page_start(off64_t offset);
-size_t page_offset(off64_t offset);
bool safe_add(off64_t* out, off64_t a, size_t b);
bool is_first_stage_init();
diff --git a/linker/linker_utils_test.cpp b/linker/linker_utils_test.cpp
index 44907da..0b881d4 100644
--- a/linker/linker_utils_test.cpp
+++ b/linker/linker_utils_test.cpp
@@ -33,6 +33,7 @@
#include <gtest/gtest.h>
#include "linker_utils.h"
+#include "platform/bionic/page.h"
TEST(linker_utils, format_string) {
std::vector<std::pair<std::string, std::string>> params = {{ "LIB", "lib32"}, { "SDKVER", "42"}};
@@ -104,9 +105,9 @@
}
TEST(linker_utils, page_start) {
- ASSERT_EQ(0x0001000, page_start(0x0001000));
- ASSERT_EQ(0x3002000, page_start(0x300222f));
- ASSERT_EQ(0x6001000, page_start(0x6001fff));
+ ASSERT_EQ(0x0001000U, page_start(0x0001000));
+ ASSERT_EQ(0x3002000U, page_start(0x300222f));
+ ASSERT_EQ(0x6001000U, page_start(0x6001fff));
}
TEST(linker_utils, page_offset) {
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index d27861a..6a1831f 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -19,8 +19,6 @@
#include <sys/cdefs.h>
#if !defined(__INTRODUCED_IN)
#define __INTRODUCED_IN(x)
-#define __INTRODUCED_IN_32(x)
-#define __INTRODUCED_IN_64(x)
#endif
// libc++ actively gets in the way of including <complex.h> from C++, so we
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index c20597b..9cb0ffd 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -3487,28 +3487,51 @@
#endif
}
-TEST(STDIO_TEST, sscanf_w_base) {
+TEST(STDIO_TEST, sscanf_w_or_wf_base) {
#if defined(__BIONIC__)
#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
int8_t a;
EXPECT_EQ(1, sscanf("<0b101>", "<%w8b>", &a));
EXPECT_EQ(0b101, a);
+ int_fast8_t fast_a;
+ EXPECT_EQ(1, sscanf("<0b101>", "<%wf8b>", &fast_a));
+ EXPECT_EQ(0b101, fast_a);
int8_t b1;
EXPECT_EQ(1, sscanf("<0xFF>", "<%w8i>", &b1));
EXPECT_EQ(-1, b1);
int8_t b2;
EXPECT_EQ(1, sscanf("<0x1FF>", "<%w8i>", &b2));
EXPECT_EQ(-1, b2);
+ int_fast8_t fast_b;
+ EXPECT_EQ(1, sscanf("<0x1234123412341234>", "<%wf8x>", &fast_b));
+ EXPECT_EQ(0x34, fast_b);
int16_t c1;
EXPECT_EQ(1, sscanf("<0xFFFF>", "<%w16i>", &c1));
EXPECT_EQ(-1, c1);
uint16_t c2;
EXPECT_EQ(1, sscanf("<64>", "<%w16d>", &c2));
EXPECT_EQ(64, c2);
+ int_fast16_t fast_c;
+#if defined(__LP64__)
+ EXPECT_EQ(1, sscanf("<0x1111111122222222>", "<%wf16x>", &fast_c));
+ EXPECT_EQ(0x1111111122222222, fast_c);
+#else
+ EXPECT_EQ(1, sscanf("<0x1111111122222222>", "<%wf16x>", &fast_c));
+ EXPECT_EQ(0x22222222, fast_c);
+#endif
int32_t d;
EXPECT_EQ(1, sscanf("<021>", "<%w32o>", &d));
EXPECT_EQ(021, d);
+ int_fast32_t fast_d;
+#if defined(__LP64__)
+ EXPECT_EQ(1, sscanf("<0x3333333344444444>", "<%wf32x>", &fast_d));
+ EXPECT_EQ(0x3333333344444444, fast_d);
+#else
+ EXPECT_EQ(1, sscanf("<0x3333333344444444>", "<%wf32x>", &fast_d));
+ EXPECT_EQ(0x44444444, fast_d);
+#endif
uint32_t e;
EXPECT_EQ(1, sscanf("<-1>", "<%w32u>", &e));
EXPECT_EQ(4294967295, e);
@@ -3517,6 +3540,11 @@
EXPECT_EQ(0x3b, f);
EXPECT_EQ(1, sscanf("<0x3b>", "<%w64X>", &f));
EXPECT_EQ(0x3B, f);
+ uint_fast64_t fast_f;
+ EXPECT_EQ(1, sscanf("<0xaaaaaaaa>", "<%wf64x>", &fast_f));
+ EXPECT_EQ(0xaaaaaaaa, fast_f);
+ EXPECT_EQ(1, sscanf("<0xaaaaaaaa>", "<%wf64X>", &fast_f));
+ EXPECT_EQ(0xAAAAAAAA, fast_f);
#pragma clang diagnostic pop
#else
GTEST_SKIP() << "no %w in glibc";
@@ -3544,40 +3572,66 @@
#endif
}
-TEST(STDIO_TEST, sscanf_invalid_w_width) {
+TEST(STDIO_TEST, sscanf_invalid_w_or_wf_width) {
#if defined(__BIONIC__)
#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
int32_t a;
EXPECT_DEATH(sscanf("<100>", "<%w20d>", &a), "%w20 is unsupported");
+ int_fast32_t fast_a;
+ EXPECT_DEATH(sscanf("<100>", "<%wf20d>", &fast_a), "%wf20 is unsupported");
#pragma clang diagnostic pop
#else
GTEST_SKIP() << "no %w in glibc";
#endif
}
-TEST(STDIO_TEST, swscanf_w_base) {
+TEST(STDIO_TEST, swscanf_w_or_wf_base) {
#if defined(__BIONIC__)
#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
int8_t a;
EXPECT_EQ(1, swscanf(L"<0b101>", L"<%w8b>", &a));
EXPECT_EQ(0b101, a);
+ int_fast8_t fast_a;
+ EXPECT_EQ(1, swscanf(L"<0b101>", L"<%wf8b>", &fast_a));
+ EXPECT_EQ(0b101, fast_a);
int8_t b1;
EXPECT_EQ(1, swscanf(L"<0xFF>", L"<%w8i>", &b1));
EXPECT_EQ(-1, b1);
int8_t b2;
EXPECT_EQ(1, swscanf(L"<0x1FF>", L"<%w8i>", &b2));
EXPECT_EQ(-1, b2);
+ int_fast8_t fast_b;
+ EXPECT_EQ(1, swscanf(L"<0x1234123412341234>", L"<%wf8i>", &fast_b));
+ EXPECT_EQ(0x34, fast_b);
int16_t c1;
EXPECT_EQ(1, swscanf(L"<0xFFFF>", L"<%w16i>", &c1));
EXPECT_EQ(-1, c1);
uint16_t c2;
EXPECT_EQ(1, swscanf(L"<64>", L"<%w16d>", &c2));
EXPECT_EQ(64, c2);
+ int_fast16_t fast_c;
+#if defined(__LP64__)
+ EXPECT_EQ(1, swscanf(L"<0x1111111122222222>", L"<%wf16x>", &fast_c));
+ EXPECT_EQ(0x1111111122222222, fast_c);
+#else
+ EXPECT_EQ(1, swscanf(L"<0x1111111122222222>", L"<%wf16x>", &fast_c));
+ EXPECT_EQ(0x22222222, fast_c);
+#endif
int32_t d;
EXPECT_EQ(1, swscanf(L"<021>", L"<%w32o>", &d));
EXPECT_EQ(021, d);
+ int_fast32_t fast_d;
+#if defined(__LP64__)
+ EXPECT_EQ(1, swscanf(L"<0x3333333344444444>", L"<%wf32x>", &fast_d));
+ EXPECT_EQ(0x3333333344444444, fast_d);
+#else
+ EXPECT_EQ(1, swscanf(L"<0x3333333344444444>", L"<%wf32x>", &fast_d));
+ EXPECT_EQ(0x44444444, fast_d);
+#endif
uint32_t e;
EXPECT_EQ(1, swscanf(L"<-1>", L"<%w32u>", &e));
EXPECT_EQ(4294967295, e);
@@ -3586,6 +3640,11 @@
EXPECT_EQ(0x3b, f);
EXPECT_EQ(1, swscanf(L"<0x3b>", L"<%w64X>", &f));
EXPECT_EQ(0x3B, f);
+ uint_fast64_t fast_f;
+ EXPECT_EQ(1, swscanf(L"<0xaaaaaaaa>", L"<%wf64x>", &fast_f));
+ EXPECT_EQ(0xaaaaaaaa, fast_f);
+ EXPECT_EQ(1, swscanf(L"<0xaaaaaaaa>", L"<%wf64X>", &fast_f));
+ EXPECT_EQ(0xAAAAAAAA, fast_f);
#pragma clang diagnostic pop
#else
GTEST_SKIP() << "no %w in glibc";
@@ -3613,12 +3672,15 @@
#endif
}
-TEST(STDIO_TEST, swscanf_invalid_w_width) {
+TEST(STDIO_TEST, swscanf_invalid_w_or_wf_width) {
#if defined(__BIONIC__)
#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
int32_t a;
EXPECT_DEATH(swscanf(L"<100>", L"<%w20d>", &a), "%w20 is unsupported");
+ int_fast32_t fast_a;
+ EXPECT_DEATH(swscanf(L"<100>", L"<%wf20d>", &fast_a), "%wf20 is unsupported");
#pragma clang diagnostic pop
#else
GTEST_SKIP() << "no %w in glibc";