diff options
Diffstat (limited to 'libc/bionic')
-rw-r--r-- | libc/bionic/__cmsg_nxthdr.cpp (renamed from libc/bionic/cmsg_nxthdr.cpp) | 3 | ||||
-rw-r--r-- | libc/bionic/ctype.cpp | 89 | ||||
-rw-r--r-- | libc/bionic/dlmalloc.h | 2 | ||||
-rw-r--r-- | libc/bionic/jemalloc_wrapper.cpp | 2 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_check.cpp | 26 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_common.cpp | 12 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_common.h | 13 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_leak.cpp | 41 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_qemu.cpp | 37 | ||||
-rw-r--r-- | libc/bionic/pthread_create.cpp | 19 | ||||
-rw-r--r-- | libc/bionic/strcoll_l.cpp | 33 | ||||
-rw-r--r-- | libc/bionic/strerror_r.cpp | 5 | ||||
-rw-r--r-- | libc/bionic/strftime_l.cpp | 34 | ||||
-rw-r--r-- | libc/bionic/strtold_l.cpp | 33 | ||||
-rw-r--r-- | libc/bionic/strtoll_l.cpp | 33 | ||||
-rw-r--r-- | libc/bionic/strtoull_l.cpp | 34 | ||||
-rw-r--r-- | libc/bionic/strxfrm_l.cpp | 33 | ||||
-rw-r--r-- | libc/bionic/stubs.cpp | 3 | ||||
-rw-r--r-- | libc/bionic/wchar.cpp | 22 | ||||
-rw-r--r-- | libc/bionic/wctype.cpp | 25 |
20 files changed, 412 insertions, 87 deletions
diff --git a/libc/bionic/cmsg_nxthdr.cpp b/libc/bionic/__cmsg_nxthdr.cpp index 8a2b33e0d..f96278890 100644 --- a/libc/bionic/cmsg_nxthdr.cpp +++ b/libc/bionic/__cmsg_nxthdr.cpp @@ -37,6 +37,3 @@ cmsghdr* __cmsg_nxthdr(msghdr* msg, cmsghdr* cmsg) { } return ptr; } - -// TODO: remove after NDK refresh. -__weak_alias(cmsg_nxthdr, __cmsg_nxthdr); diff --git a/libc/bionic/ctype.cpp b/libc/bionic/ctype.cpp new file mode 100644 index 000000000..3960d9d4c --- /dev/null +++ b/libc/bionic/ctype.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <ctype.h> + +int isalnum_l(int c, locale_t) { + return isalnum(c); +} + +int isalpha_l(int c, locale_t) { + return isalpha(c); +} + +int isascii_l(int c, locale_t) { + return isascii(c); +} + +int isblank_l(int c, locale_t) { + return isblank(c); +} + +int iscntrl_l(int c, locale_t) { + return iscntrl(c); +} + +int isdigit_l(int c, locale_t) { + return isdigit(c); +} + +int isgraph_l(int c, locale_t) { + return isgraph(c); +} + +int islower_l(int c, locale_t) { + return islower(c); +} + +int isprint_l(int c, locale_t) { + return isprint(c); +} + +int ispunct_l(int c, locale_t) { + return ispunct(c); +} + +int isspace_l(int c, locale_t) { + return isspace(c); +} + +int isupper_l(int c, locale_t) { + return isupper(c); +} + +int isxdigit_l(int c, locale_t) { + return isxdigit(c); +} + +int toupper_l(int c, locale_t) { + return toupper(c); +} + +int tolower_l(int c, locale_t) { + return tolower(c); +} diff --git a/libc/bionic/dlmalloc.h b/libc/bionic/dlmalloc.h index e0656877f..46efa911f 100644 --- a/libc/bionic/dlmalloc.h +++ b/libc/bionic/dlmalloc.h @@ -32,6 +32,8 @@ #define USE_SPIN_LOCKS 0 #define DEFAULT_MMAP_THRESHOLD (64U * 1024U) +#define malloc_getpagesize getpagesize() + /* Export two symbols used by the VM. */ __BEGIN_DECLS int dlmalloc_trim(size_t) __LIBC_ABI_PUBLIC__; diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp index d1fe96056..e33d560a4 100644 --- a/libc/bionic/jemalloc_wrapper.cpp +++ b/libc/bionic/jemalloc_wrapper.cpp @@ -21,7 +21,7 @@ #include "private/bionic_macros.h" void* je_pvalloc(size_t bytes) { - size_t pagesize = sysconf(_SC_PAGESIZE); + size_t pagesize = getpagesize(); size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { return NULL; diff --git a/libc/bionic/malloc_debug_check.cpp b/libc/bionic/malloc_debug_check.cpp index e4e4c2eb0..1c63d4dcf 100644 --- a/libc/bionic/malloc_debug_check.cpp +++ b/libc/bionic/malloc_debug_check.cpp @@ -123,6 +123,7 @@ static pthread_mutex_t backlog_lock = PTHREAD_MUTEX_INITIALIZER; static unsigned g_malloc_debug_backlog = 100; __LIBC_HIDDEN__ HashTable* g_hash_table; +__LIBC_HIDDEN__ const MallocDebug* g_malloc_dispatch; static inline void init_front_guard(hdr_t* hdr) { memset(hdr->front_guard, FRONT_GUARD, FRONT_GUARD_LEN); @@ -324,7 +325,7 @@ static inline void add_to_backlog(hdr_t* hdr) { while (backlog_num > g_malloc_debug_backlog) { hdr_t* gone = backlog_tail; del_from_backlog_locked(gone); - Malloc(free)(gone->base); + g_malloc_dispatch->free(gone->base); } } @@ -336,7 +337,7 @@ extern "C" void* chk_malloc(size_t bytes) { errno = ENOMEM; return NULL; } - hdr_t* hdr = static_cast<hdr_t*>(Malloc(malloc)(size)); + hdr_t* hdr = static_cast<hdr_t*>(g_malloc_dispatch->malloc(size)); if (hdr) { hdr->base = hdr; hdr->bt_depth = get_backtrace(hdr->bt, MAX_BACKTRACE_DEPTH); @@ -364,7 +365,7 @@ extern "C" void* chk_memalign(size_t alignment, size_t bytes) { return NULL; } - void* base = Malloc(malloc)(sizeof(hdr_t) + size + sizeof(ftr_t)); + void* base = g_malloc_dispatch->malloc(sizeof(hdr_t) + size + sizeof(ftr_t)); if (base != NULL) { // Check that the actual pointer that will be returned is aligned // properly. @@ -461,7 +462,7 @@ extern "C" void* chk_realloc(void* ptr, size_t bytes) { user(hdr), bytes); log_backtrace(bt, depth); // just get a whole new allocation and leak the old one - return Malloc(realloc)(0, bytes); + return g_malloc_dispatch->realloc(0, bytes); // return realloc(user(hdr), bytes); // assuming it was allocated externally } } @@ -474,15 +475,15 @@ extern "C" void* chk_realloc(void* ptr, size_t bytes) { if (hdr->base != hdr) { // An allocation from memalign, so create another allocation and // copy the data out. - void* newMem = Malloc(malloc)(size); + void* newMem = g_malloc_dispatch->malloc(size); if (newMem == NULL) { return NULL; } memcpy(newMem, hdr, sizeof(hdr_t) + hdr->size); - Malloc(free)(hdr->base); + g_malloc_dispatch->free(hdr->base); hdr = static_cast<hdr_t*>(newMem); } else { - hdr = static_cast<hdr_t*>(Malloc(realloc)(hdr, size)); + hdr = static_cast<hdr_t*>(g_malloc_dispatch->realloc(hdr, size)); } if (hdr) { hdr->base = hdr; @@ -501,7 +502,7 @@ extern "C" void* chk_calloc(size_t nmemb, size_t bytes) { errno = ENOMEM; return NULL; } - hdr_t* hdr = static_cast<hdr_t*>(Malloc(calloc)(1, size)); + hdr_t* hdr = static_cast<hdr_t*>(g_malloc_dispatch->calloc(1, size)); if (hdr) { hdr->base = hdr; hdr->bt_depth = get_backtrace(hdr->bt, MAX_BACKTRACE_DEPTH); @@ -524,7 +525,7 @@ extern "C" size_t chk_malloc_usable_size(const void* ptr) { } extern "C" struct mallinfo chk_mallinfo() { - return Malloc(mallinfo)(); + return g_malloc_dispatch->mallinfo(); } extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size) { @@ -538,7 +539,7 @@ extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size) } extern "C" void* chk_pvalloc(size_t bytes) { - size_t pagesize = sysconf(_SC_PAGESIZE); + size_t pagesize = getpagesize(); size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow return NULL; @@ -547,7 +548,7 @@ extern "C" void* chk_pvalloc(size_t bytes) { } extern "C" void* chk_valloc(size_t size) { - return chk_memalign(sysconf(_SC_PAGESIZE), size); + return chk_memalign(getpagesize(), size); } static void ReportMemoryLeaks() { @@ -584,8 +585,9 @@ static void ReportMemoryLeaks() { } } -extern "C" bool malloc_debug_initialize(HashTable* hash_table) { +extern "C" bool malloc_debug_initialize(HashTable* hash_table, const MallocDebug* malloc_dispatch) { g_hash_table = hash_table; + g_malloc_dispatch = malloc_dispatch; char debug_backlog[PROP_VALUE_MAX]; if (__system_property_get("libc.debug.malloc.backlog", debug_backlog)) { diff --git a/libc/bionic/malloc_debug_common.cpp b/libc/bionic/malloc_debug_common.cpp index 9399237fb..be16625b8 100644 --- a/libc/bionic/malloc_debug_common.cpp +++ b/libc/bionic/malloc_debug_common.cpp @@ -46,6 +46,16 @@ #include "private/ScopedPthreadMutexLocker.h" +#if defined(USE_JEMALLOC) +#include "jemalloc.h" +#define Malloc(function) je_ ## function +#elif defined(USE_DLMALLOC) +#include "dlmalloc.h" +#define Malloc(function) dl ## function +#else +#error "Either one of USE_DLMALLOC or USE_JEMALLOC must be defined." +#endif + // In a VM process, this is set to 1 after fork()ing out of zygote. int gMallocLeakZygoteChild = 0; @@ -408,7 +418,7 @@ static void malloc_init_impl() { dlclose(malloc_impl_handle); return; } - if (!malloc_debug_initialize(&g_hash_table)) { + if (!malloc_debug_initialize(&g_hash_table, &__libc_malloc_default_dispatch)) { dlclose(malloc_impl_handle); return; } diff --git a/libc/bionic/malloc_debug_common.h b/libc/bionic/malloc_debug_common.h index fb2f03d06..5c73da31a 100644 --- a/libc/bionic/malloc_debug_common.h +++ b/libc/bionic/malloc_debug_common.h @@ -51,17 +51,6 @@ #define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *))) #endif -#ifdef USE_JEMALLOC -#include "jemalloc.h" -#define Malloc(function) je_ ## function -#else -#ifndef USE_DLMALLOC -#error "Either one of USE_DLMALLOC or USE_JEMALLOC must be defined." -#endif -#include "dlmalloc.h" -#define Malloc(function) dl ## function -#endif - // ============================================================================= // Structures // ============================================================================= @@ -116,7 +105,7 @@ struct MallocDebug { #endif }; -typedef bool (*MallocDebugInit)(HashTable*); +typedef bool (*MallocDebugInit)(HashTable*, const MallocDebug*); typedef void (*MallocDebugFini)(int); // ============================================================================= diff --git a/libc/bionic/malloc_debug_leak.cpp b/libc/bionic/malloc_debug_leak.cpp index 308d40b9a..d9824f09f 100644 --- a/libc/bionic/malloc_debug_leak.cpp +++ b/libc/bionic/malloc_debug_leak.cpp @@ -62,6 +62,7 @@ extern int gMallocLeakZygoteChild; extern HashTable* g_hash_table; +extern const MallocDebug* g_malloc_dispatch; // ============================================================================= // stack trace functions @@ -143,7 +144,7 @@ static HashEntry* record_backtrace(uintptr_t* backtrace, size_t numEntries, size entry->allocations++; } else { // create a new entry - entry = static_cast<HashEntry*>(Malloc(malloc)(sizeof(HashEntry) + numEntries*sizeof(uintptr_t))); + entry = static_cast<HashEntry*>(g_malloc_dispatch->malloc(sizeof(HashEntry) + numEntries*sizeof(uintptr_t))); if (!entry) { return NULL; } @@ -208,11 +209,11 @@ static void remove_entry(HashEntry* entry) { #define CHK_SENTINEL_VALUE 0xeb extern "C" void* fill_calloc(size_t n_elements, size_t elem_size) { - return Malloc(calloc)(n_elements, elem_size); + return g_malloc_dispatch->calloc(n_elements, elem_size); } extern "C" void* fill_malloc(size_t bytes) { - void* buffer = Malloc(malloc)(bytes); + void* buffer = g_malloc_dispatch->malloc(bytes); if (buffer) { memset(buffer, CHK_SENTINEL_VALUE, bytes); } @@ -220,17 +221,17 @@ extern "C" void* fill_malloc(size_t bytes) { } extern "C" void fill_free(void* mem) { - size_t bytes = Malloc(malloc_usable_size)(mem); + size_t bytes = g_malloc_dispatch->malloc_usable_size(mem); memset(mem, CHK_FILL_FREE, bytes); - Malloc(free)(mem); + g_malloc_dispatch->free(mem); } extern "C" void* fill_realloc(void* mem, size_t bytes) { - size_t oldSize = Malloc(malloc_usable_size)(mem); - void* newMem = Malloc(realloc)(mem, bytes); + size_t oldSize = g_malloc_dispatch->malloc_usable_size(mem); + void* newMem = g_malloc_dispatch->realloc(mem, bytes); if (newMem) { // If this is larger than before, fill the extra with our pattern. - size_t newSize = Malloc(malloc_usable_size)(newMem); + size_t newSize = g_malloc_dispatch->malloc_usable_size(newMem); if (newSize > oldSize) { memset(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(newMem)+oldSize), CHK_FILL_FREE, newSize-oldSize); } @@ -239,7 +240,7 @@ extern "C" void* fill_realloc(void* mem, size_t bytes) { } extern "C" void* fill_memalign(size_t alignment, size_t bytes) { - void* buffer = Malloc(memalign)(alignment, bytes); + void* buffer = g_malloc_dispatch->memalign(alignment, bytes); if (buffer) { memset(buffer, CHK_SENTINEL_VALUE, bytes); } @@ -249,11 +250,11 @@ extern "C" void* fill_memalign(size_t alignment, size_t bytes) { extern "C" size_t fill_malloc_usable_size(const void* mem) { // Since we didn't allocate extra bytes before or after, we can // report the normal usable size here. - return Malloc(malloc_usable_size)(mem); + return g_malloc_dispatch->malloc_usable_size(mem); } extern "C" struct mallinfo fill_mallinfo() { - return Malloc(mallinfo)(); + return g_malloc_dispatch->mallinfo(); } extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size) { @@ -267,7 +268,7 @@ extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size) } extern "C" void* fill_pvalloc(size_t bytes) { - size_t pagesize = sysconf(_SC_PAGESIZE); + size_t pagesize = getpagesize(); size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow return NULL; @@ -276,7 +277,7 @@ extern "C" void* fill_pvalloc(size_t bytes) { } extern "C" void* fill_valloc(size_t size) { - return fill_memalign(sysconf(_SC_PAGESIZE), size); + return fill_memalign(getpagesize(), size); } // ============================================================================= @@ -298,7 +299,7 @@ extern "C" void* leak_malloc(size_t bytes) { return NULL; } - void* base = Malloc(malloc)(size); + void* base = g_malloc_dispatch->malloc(size); if (base != NULL) { ScopedPthreadMutexLocker locker(&g_hash_table->lock); @@ -342,11 +343,11 @@ extern "C" void leak_free(void* mem) { entry->allocations--; if (entry->allocations <= 0) { remove_entry(entry); - Malloc(free)(entry); + g_malloc_dispatch->free(entry); } // now free the memory! - Malloc(free)(header); + g_malloc_dispatch->free(header); } else { debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n", header->guard, header->entry); @@ -452,7 +453,7 @@ extern "C" size_t leak_malloc_usable_size(const void* mem) { return 0; } - size_t ret = Malloc(malloc_usable_size)(header); + size_t ret = g_malloc_dispatch->malloc_usable_size(header); if (ret != 0) { // The usable area starts at 'mem' and stops at 'header+ret'. return reinterpret_cast<uintptr_t>(header) + ret - reinterpret_cast<uintptr_t>(mem); @@ -462,7 +463,7 @@ extern "C" size_t leak_malloc_usable_size(const void* mem) { } extern "C" struct mallinfo leak_mallinfo() { - return Malloc(mallinfo)(); + return g_malloc_dispatch->mallinfo(); } extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) { @@ -476,7 +477,7 @@ extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) } extern "C" void* leak_pvalloc(size_t bytes) { - size_t pagesize = sysconf(_SC_PAGESIZE); + size_t pagesize = getpagesize(); size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow return NULL; @@ -485,5 +486,5 @@ extern "C" void* leak_pvalloc(size_t bytes) { } extern "C" void* leak_valloc(size_t size) { - return leak_memalign(sysconf(_SC_PAGESIZE), size); + return leak_memalign(getpagesize(), size); } diff --git a/libc/bionic/malloc_debug_qemu.cpp b/libc/bionic/malloc_debug_qemu.cpp index fd5161a7e..b3b604d86 100644 --- a/libc/bionic/malloc_debug_qemu.cpp +++ b/libc/bionic/malloc_debug_qemu.cpp @@ -336,6 +336,9 @@ static void dump_malloc_descriptor(char* str, // Static data // ============================================================================= +// The underlying malloc implementation to use to get memory. +static const MallocDebug* g_malloc_dispatch = NULL; + /* Emulator's magic page address. * This page (mapped on /dev/qemu_trace device) is used to fire up events * in the emulator. */ @@ -595,7 +598,9 @@ extern "C" void* qemu_instrumented_valloc(size_t); * Return: * 0 on success, or -1 on failure. */ -extern "C" bool malloc_debug_initialize(HashTable*) { +extern "C" bool malloc_debug_initialize(HashTable*, const MallocDebug* malloc_dispatch) { + g_malloc_dispatch = malloc_dispatch; + /* We will be using emulator's magic page to report memory allocation * activities. In essence, what magic page does, it translates writes to * the memory mapped spaces into writes to an I/O port that emulator @@ -693,7 +698,7 @@ extern "C" void* qemu_instrumented_malloc(size_t bytes) { errno = ENOMEM; return NULL; } - desc.ptr = Malloc(malloc)(size); + desc.ptr = g_malloc_dispatch->malloc(size); if (desc.ptr == NULL) { qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zu): malloc(%zu) failed.", malloc_pid, getpid(), bytes, size); @@ -704,7 +709,7 @@ extern "C" void* qemu_instrumented_malloc(size_t bytes) { if (notify_qemu_malloc(&desc)) { log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ", malloc_pid, getpid()); - Malloc(free)(desc.ptr); + g_malloc_dispatch->free(desc.ptr); errno = ENOMEM; return NULL; } else { @@ -726,7 +731,7 @@ extern "C" void qemu_instrumented_free(void* mem) { if (mem == NULL) { // Just let go NULL free - Malloc(free)(mem); + g_malloc_dispatch->free(mem); return; } @@ -757,7 +762,7 @@ extern "C" void qemu_instrumented_free(void* mem) { } else { log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ", malloc_pid, getpid(), mem); - Malloc(free)(desc.ptr); + g_malloc_dispatch->free(desc.ptr); } } @@ -816,7 +821,7 @@ extern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size) { total_elements++; desc.suffix_size += (elem_size - total_size); } - desc.ptr = Malloc(calloc)(total_elements, elem_size); + desc.ptr = g_malloc_dispatch->calloc(total_elements, elem_size); if (desc.ptr == NULL) { error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu(%zu), %zu) (prx=%u, sfx=%u) failed.", malloc_pid, getpid(), n_elements, total_elements, elem_size, @@ -827,7 +832,7 @@ extern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size) { if (notify_qemu_malloc(&desc)) { log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%zu(%zu), %zu): notify_malloc failed for ", malloc_pid, getpid(), n_elements, total_elements, elem_size); - Malloc(free)(desc.ptr); + g_malloc_dispatch->free(desc.ptr); errno = ENOMEM; return NULL; } else { @@ -905,7 +910,7 @@ extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) { errno = ENOMEM; return NULL; } - new_desc.ptr = Malloc(malloc)(new_size); + new_desc.ptr = g_malloc_dispatch->malloc(new_size); if (new_desc.ptr == NULL) { log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed on ", malloc_pid, getpid(), mem, bytes, new_size); @@ -924,7 +929,7 @@ extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) { log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) notify_malloc failed -> ", malloc_pid, getpid(), mem, bytes); log_mdesc(error, &cur_desc, " <- "); - Malloc(free)(new_desc.ptr); + g_malloc_dispatch->free(new_desc.ptr); errno = ENOMEM; return NULL; } @@ -940,11 +945,11 @@ extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) { /* Since we registered new decriptor with the emulator, we need * to unregister it before freeing newly allocated block. */ notify_qemu_free(mallocdesc_user_ptr(&new_desc)); - Malloc(free)(new_desc.ptr); + g_malloc_dispatch->free(new_desc.ptr); errno = ENOMEM; return NULL; } - Malloc(free)(cur_desc.ptr); + g_malloc_dispatch->free(cur_desc.ptr); log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) -> ", malloc_pid, getpid(), mem, bytes); @@ -985,7 +990,7 @@ extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) { return NULL; } - desc.ptr = Malloc(memalign)(desc.prefix_size, size); + desc.ptr = g_malloc_dispatch->memalign(desc.prefix_size, size); if (desc.ptr == NULL) { error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed.", malloc_pid, getpid(), alignment, bytes, size); @@ -994,7 +999,7 @@ extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) { if (notify_qemu_malloc(&desc)) { log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%zx, %zu): notify_malloc failed for ", malloc_pid, getpid(), alignment, bytes); - Malloc(free)(desc.ptr); + g_malloc_dispatch->free(desc.ptr); return NULL; } @@ -1032,7 +1037,7 @@ extern "C" size_t qemu_instrumented_malloc_usable_size(const void* mem) { } extern "C" struct mallinfo qemu_instrumented_mallinfo() { - return Malloc(mallinfo)(); + return g_malloc_dispatch->mallinfo(); } extern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, size_t size) { @@ -1048,7 +1053,7 @@ extern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, } extern "C" void* qemu_instrumented_pvalloc(size_t bytes) { - size_t pagesize = sysconf(_SC_PAGESIZE); + size_t pagesize = getpagesize(); size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow qemu_error_log("<libc_pid=%03u, pid=%03u> pvalloc(%zu): overflow (%zu).", @@ -1059,5 +1064,5 @@ extern "C" void* qemu_instrumented_pvalloc(size_t bytes) { } extern "C" void* qemu_instrumented_valloc(size_t size) { - return qemu_instrumented_memalign(sysconf(_SC_PAGESIZE), size); + return qemu_instrumented_memalign(getpagesize(), size); } diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 2ded22b0f..174e30807 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -41,23 +41,12 @@ #include "private/ErrnoRestorer.h" #include "private/ScopedPthreadMutexLocker.h" -// Used by gdb to track thread creation. See libthread_db. -#ifdef __i386__ -extern "C" __attribute__((noinline)) __attribute__((fastcall)) void _thread_created_hook(pid_t) {} -#else -extern "C" __attribute__((noinline)) void _thread_created_hook(pid_t) {} -#endif - // x86 uses segment descriptors rather than a direct pointer to TLS. #if __i386__ #include <asm/ldt.h> extern "C" __LIBC_HIDDEN__ void __init_user_desc(struct user_desc*, int, void*); #endif -static pthread_mutex_t g_pthread_stack_creation_lock = PTHREAD_MUTEX_INITIALIZER; - -static pthread_mutex_t g_debugger_notification_lock = PTHREAD_MUTEX_INITIALIZER; - extern "C" int __isthreaded; // This code is used both by each new pthread and the code that initializes the main thread. @@ -113,8 +102,6 @@ int __init_thread(pthread_internal_t* thread, bool add_to_thread_list) { } static void* __create_thread_stack(pthread_internal_t* thread) { - ScopedPthreadMutexLocker lock(&g_pthread_stack_creation_lock); - // Create a new private anonymous map. int prot = PROT_READ | PROT_WRITE; int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; @@ -258,12 +245,6 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, return init_errno; } - // Notify any debuggers about the new thread. - { - ScopedPthreadMutexLocker debugger_locker(&g_debugger_notification_lock); - _thread_created_hook(thread->tid); - } - // Publish the pthread_t and unlock the mutex to let the new thread start running. *thread_out = reinterpret_cast<pthread_t>(thread); pthread_mutex_unlock(&thread->startup_handshake_mutex); diff --git a/libc/bionic/strcoll_l.cpp b/libc/bionic/strcoll_l.cpp new file mode 100644 index 000000000..7d7c28bef --- /dev/null +++ b/libc/bionic/strcoll_l.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <string.h> + +int strcoll_l(const char *s1, const char *s2, locale_t) { + return strcoll(s1, s2); +} diff --git a/libc/bionic/strerror_r.cpp b/libc/bionic/strerror_r.cpp index 5f2d36214..1e57cc0b3 100644 --- a/libc/bionic/strerror_r.cpp +++ b/libc/bionic/strerror_r.cpp @@ -8,6 +8,7 @@ #include <string.h> #include "private/ErrnoRestorer.h" +#include "private/libc_logging.h" struct Pair { int code; @@ -49,9 +50,9 @@ int strerror_r(int error_number, char* buf, size_t buf_len) { const char* error_name = __strerror_lookup(error_number); if (error_name != NULL) { - length = snprintf(buf, buf_len, "%s", error_name); + length = strlcpy(buf, error_name, buf_len); } else { - length = snprintf(buf, buf_len, "Unknown error %d", error_number); + length = __libc_format_buffer(buf, buf_len, "Unknown error %d", error_number); } if (length >= buf_len) { errno_restorer.override(ERANGE); diff --git a/libc/bionic/strftime_l.cpp b/libc/bionic/strftime_l.cpp new file mode 100644 index 000000000..fb01da5f2 --- /dev/null +++ b/libc/bionic/strftime_l.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <time.h> + +size_t strftime_l(char *s, size_t max, const char *format, const struct tm *tm, + locale_t) { + return strftime(s, max, format, tm); +} diff --git a/libc/bionic/strtold_l.cpp b/libc/bionic/strtold_l.cpp new file mode 100644 index 000000000..4b230b94a --- /dev/null +++ b/libc/bionic/strtold_l.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdlib.h> + +long double strtold_l(const char *nptr, char **endptr, locale_t) { + return strtold(nptr, endptr); +} diff --git a/libc/bionic/strtoll_l.cpp b/libc/bionic/strtoll_l.cpp new file mode 100644 index 000000000..05fb76083 --- /dev/null +++ b/libc/bionic/strtoll_l.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdlib.h> + +long long strtoll_l(const char *nptr, char **endptr, size_t base, locale_t) { + return strtoll(nptr, endptr, base); +} diff --git a/libc/bionic/strtoull_l.cpp b/libc/bionic/strtoull_l.cpp new file mode 100644 index 000000000..ba0bc6ad4 --- /dev/null +++ b/libc/bionic/strtoull_l.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdlib.h> + +unsigned long long strtoull_l(const char *nptr, char **endptr, size_t base, + locale_t) { + return strtoull(nptr, endptr, base); +} diff --git a/libc/bionic/strxfrm_l.cpp b/libc/bionic/strxfrm_l.cpp new file mode 100644 index 000000000..afe3b965c --- /dev/null +++ b/libc/bionic/strxfrm_l.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <string.h> + +size_t strxfrm_l(char *dest, const char *src, size_t n, locale_t) { + return strxfrm(dest, src, n); +} diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp index 9b025df7c..0937e9c06 100644 --- a/libc/bionic/stubs.cpp +++ b/libc/bionic/stubs.cpp @@ -469,5 +469,6 @@ void endusershell() { // Portable code should use sysconf(_SC_PAGE_SIZE) directly instead. int getpagesize() { - return sysconf(_SC_PAGE_SIZE); + // We dont use sysconf(3) here because that drags in stdio, which makes static binaries fat. + return PAGE_SIZE; } diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp index acb27617a..ecb8b3391 100644 --- a/libc/bionic/wchar.cpp +++ b/libc/bionic/wchar.cpp @@ -219,3 +219,25 @@ size_t wcsnrtombs(char* dst, const wchar_t** src, size_t nwc, size_t len, mbstat size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps) { return wcsnrtombs(dst, src, SIZE_MAX, len, ps); } + +int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) { + return wcscoll(ws1, ws2); +} + +size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, locale_t) { + return wcsxfrm(dest, src, n); +} + +long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, size_t base, + locale_t) { + return wcstoll(nptr, endptr, base); +} + +unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr, + size_t base, locale_t) { + return wcstoull(nptr, endptr, base); +} + +long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, locale_t) { + return wcstold(nptr, endptr); +} diff --git a/libc/bionic/wctype.cpp b/libc/bionic/wctype.cpp index 673402d6b..f2d7861c2 100644 --- a/libc/bionic/wctype.cpp +++ b/libc/bionic/wctype.cpp @@ -30,6 +30,7 @@ #include <stdlib.h> #include <string.h> #include <wchar.h> +#include <wctype.h> // TODO: these only work for the ASCII range; rewrite to dlsym icu4c? http://b/14499654 @@ -46,6 +47,19 @@ int iswspace(wint_t wc) { return isspace(wc); } int iswupper(wint_t wc) { return isupper(wc); } int iswxdigit(wint_t wc) { return isxdigit(wc); } +int iswalnum_l(wint_t c, locale_t) { return iswalnum(c); } +int iswalpha_l(wint_t c, locale_t) { return iswalpha(c); } +int iswblank_l(wint_t c, locale_t) { return iswblank(c); } +int iswcntrl_l(wint_t c, locale_t) { return iswcntrl(c); } +int iswdigit_l(wint_t c, locale_t) { return iswdigit(c); } +int iswgraph_l(wint_t c, locale_t) { return iswgraph(c); } +int iswlower_l(wint_t c, locale_t) { return iswlower(c); } +int iswprint_l(wint_t c, locale_t) { return iswprint(c); } +int iswpunct_l(wint_t c, locale_t) { return iswpunct(c); } +int iswspace_l(wint_t c, locale_t) { return iswspace(c); } +int iswupper_l(wint_t c, locale_t) { return iswupper(c); } +int iswxdigit_l(wint_t c, locale_t) { return iswxdigit(c); } + int iswctype(wint_t wc, wctype_t char_class) { switch (char_class) { case WC_TYPE_ALNUM: return iswalnum(wc); @@ -64,9 +78,16 @@ int iswctype(wint_t wc, wctype_t char_class) { } } +int iswctype_l(wint_t wc, wctype_t char_class, locale_t) { + return iswctype(wc, char_class); +} + wint_t towlower(wint_t wc) { return tolower(wc); } wint_t towupper(wint_t wc) { return toupper(wc); } +int towupper_l(int c, locale_t) { return towupper(c); } +int towlower_l(int c, locale_t) { return towlower(c); } + wctype_t wctype(const char* property) { static const char* const properties[WC_TYPE_MAX] = { "<invalid>", @@ -81,6 +102,10 @@ wctype_t wctype(const char* property) { return static_cast<wctype_t>(0); } +wctype_t wctype_l(const char* property, locale_t) { + return wctype(property); +} + int wcwidth(wchar_t wc) { return (wc > 0); } |