merge from donut
This commit is contained in:
commit
61e844f48e
@ -39,23 +39,6 @@
|
|||||||
#include <bionic_tls.h>
|
#include <bionic_tls.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
extern void _init(void);
|
|
||||||
extern void _fini(void);
|
|
||||||
|
|
||||||
static void call_array(void(**list)())
|
|
||||||
{
|
|
||||||
// First element is -1, list is null-terminated
|
|
||||||
while (*++list) {
|
|
||||||
(*list)();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __bionic_do_global_dtors(structors_array_t const * const p)
|
|
||||||
{
|
|
||||||
call_array(p->fini_array);
|
|
||||||
//_fini();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern unsigned __get_sp(void);
|
extern unsigned __get_sp(void);
|
||||||
extern pid_t gettid(void);
|
extern pid_t gettid(void);
|
||||||
|
|
||||||
@ -69,23 +52,19 @@ unsigned int __page_shift = PAGE_SHIFT;
|
|||||||
|
|
||||||
int __system_properties_init(void);
|
int __system_properties_init(void);
|
||||||
|
|
||||||
void __libc_init_common(uintptr_t *elfdata,
|
void __libc_init_common(uintptr_t *elfdata)
|
||||||
void (*onexit)(void),
|
|
||||||
int (*slingshot)(int, char**, char**),
|
|
||||||
structors_array_t const * const structors,
|
|
||||||
void (*pre_ctor_hook)())
|
|
||||||
{
|
{
|
||||||
pthread_internal_t thread;
|
int argc = *elfdata;
|
||||||
pthread_attr_t thread_attr;
|
char** argv = (char**)(elfdata + 1);
|
||||||
void *tls_area[BIONIC_TLS_SLOTS];
|
char** envp = argv + argc + 1;
|
||||||
int argc;
|
|
||||||
char **argv, **envp, **envend;
|
|
||||||
struct auxentry *auxentry;
|
|
||||||
unsigned int page_size = 0, page_shift = 0;
|
|
||||||
|
|
||||||
/* The main thread's stack has empirically shown to be 84k */
|
pthread_attr_t thread_attr;
|
||||||
|
static pthread_internal_t thread;
|
||||||
|
static void* tls_area[BIONIC_TLS_SLOTS];
|
||||||
|
|
||||||
|
/* setup pthread runtime and maint thread descriptor */
|
||||||
unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
|
unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
|
||||||
unsigned stacksize = 128 * 1024; //84 * 1024;
|
unsigned stacksize = 128 * 1024;
|
||||||
unsigned stackbottom = stacktop - stacksize;
|
unsigned stackbottom = stacktop - stacksize;
|
||||||
|
|
||||||
pthread_attr_init(&thread_attr);
|
pthread_attr_init(&thread_attr);
|
||||||
@ -93,30 +72,15 @@ void __libc_init_common(uintptr_t *elfdata,
|
|||||||
_init_thread(&thread, gettid(), &thread_attr, (void*)stackbottom);
|
_init_thread(&thread, gettid(), &thread_attr, (void*)stackbottom);
|
||||||
__init_tls(tls_area, &thread);
|
__init_tls(tls_area, &thread);
|
||||||
|
|
||||||
argc = (int) *elfdata++;
|
/* clear errno - requires TLS area */
|
||||||
argv = (char**) elfdata;
|
|
||||||
envp = argv+(argc+1);
|
|
||||||
environ = envp;
|
|
||||||
|
|
||||||
__progname = argv[0] ? argv[0] : "<unknown>";
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
|
/* set program name */
|
||||||
|
__progname = argv[0] ? argv[0] : "<unknown>";
|
||||||
|
|
||||||
|
/* setup environment pointer */
|
||||||
|
environ = envp;
|
||||||
|
|
||||||
|
/* setup system properties - requires environment */
|
||||||
__system_properties_init();
|
__system_properties_init();
|
||||||
|
|
||||||
if (pre_ctor_hook) pre_ctor_hook();
|
|
||||||
|
|
||||||
// XXX: we should execute the .fini_array upon exit
|
|
||||||
|
|
||||||
// pre-init array.
|
|
||||||
// XXX: I'm not sure what's the different with the init array.
|
|
||||||
call_array(structors->preinit_array);
|
|
||||||
|
|
||||||
// for compatibility with non-eabi binary, call the .ctors section
|
|
||||||
call_array(structors->ctors_array);
|
|
||||||
|
|
||||||
// call static constructors
|
|
||||||
call_array(structors->init_array);
|
|
||||||
|
|
||||||
exit(slingshot(argc, argv, envp));
|
|
||||||
}
|
}
|
||||||
|
@ -38,10 +38,6 @@ typedef struct
|
|||||||
void (**ctors_array)(void);
|
void (**ctors_array)(void);
|
||||||
} structors_array_t;
|
} structors_array_t;
|
||||||
|
|
||||||
extern __noreturn void __libc_init_common(uintptr_t *elfdata,
|
extern void __libc_init_common(uintptr_t *elfdata);
|
||||||
void (*onexit)(void),
|
|
||||||
int (*slingshot)(int, char**, char**),
|
|
||||||
structors_array_t const * const structors,
|
|
||||||
void (*pre_ctor_hook)());
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,41 +26,81 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* libc_init_static.c
|
* libc_init_dynamic.c
|
||||||
*
|
*
|
||||||
* This function takes the raw data block set up by the ELF loader
|
* This source files provides two important functions for dynamic
|
||||||
* in the kernel and parses it. It is invoked by crt0.S which makes
|
* executables:
|
||||||
* any necessary adjustments and passes calls this function using
|
|
||||||
* the standard C calling convention.
|
|
||||||
*
|
*
|
||||||
* The arguments are:
|
* - a C runtime initializer (__libc_preinit), which is called by
|
||||||
* uintptr_t *elfdata -- The ELF loader data block; usually from the stack.
|
* the dynamic linker when libc.so is loaded. This happens before
|
||||||
* Basically a pointer to argc.
|
* any other initializer (e.g. static C++ constructors in other
|
||||||
* void (*onexit)(void) -- Function to install into onexit
|
* shared libraries the program depends on).
|
||||||
|
*
|
||||||
|
* - a program launch function (__libc_init), which is called after
|
||||||
|
* all dynamic linking has been performed. Technically, it is called
|
||||||
|
* from arch-$ARCH/bionic/crtbegin_dynamic.S which is itself called
|
||||||
|
* by the dynamic linker after all libraries have been loaded and
|
||||||
|
* initialized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Several Linux ABIs don't pass the onexit pointer, and the ones that
|
|
||||||
* do never use it. Therefore, unless USE_ONEXIT is defined, we just
|
|
||||||
* ignore the onexit pointer.
|
|
||||||
*/
|
|
||||||
/* #define USE_ONEXIT */
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include "pthread_internal.h"
|
|
||||||
#include "atexit.h"
|
#include "atexit.h"
|
||||||
#include "libc_init_common.h"
|
#include "libc_init_common.h"
|
||||||
|
#include <bionic_tls.h>
|
||||||
|
|
||||||
extern void malloc_debug_init();
|
extern void malloc_debug_init();
|
||||||
|
|
||||||
|
/* We flag the __libc_preinit function as a constructor to ensure
|
||||||
|
* that its address is listed in libc.so's .init_array section.
|
||||||
|
* This ensures that the function is called by the dynamic linker
|
||||||
|
* as soon as the shared library is loaded.
|
||||||
|
*/
|
||||||
|
void __attribute__((constructor)) __libc_prenit(void);
|
||||||
|
|
||||||
|
void __libc_prenit(void)
|
||||||
|
{
|
||||||
|
/* Read the ELF data pointer form a special slot of the
|
||||||
|
* TLS area, then call __libc_init_common with it.
|
||||||
|
*
|
||||||
|
* Note that:
|
||||||
|
* - we clear the slot so no other initializer sees its value.
|
||||||
|
* - __libc_init_common() will change the TLS area so the old one
|
||||||
|
* won't be accessible anyway.
|
||||||
|
*/
|
||||||
|
void** tls_area = (void**)__get_tls();
|
||||||
|
unsigned* elfdata = tls_area[TLS_SLOT_BIONIC_PREINIT];
|
||||||
|
|
||||||
|
tls_area[TLS_SLOT_BIONIC_PREINIT] = NULL;
|
||||||
|
|
||||||
|
__libc_init_common(elfdata);
|
||||||
|
|
||||||
|
#ifdef MALLOC_LEAK_CHECK
|
||||||
|
/* setup malloc leak checker, requires system properties */
|
||||||
|
extern void malloc_debug_init(void);
|
||||||
|
malloc_debug_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
__noreturn void __libc_init(uintptr_t *elfdata,
|
__noreturn void __libc_init(uintptr_t *elfdata,
|
||||||
void (*onexit)(void),
|
void (*onexit)(void),
|
||||||
int (*slingshot)(int, char**, char**),
|
int (*slingshot)(int, char**, char**),
|
||||||
structors_array_t const * const structors)
|
structors_array_t const * const structors)
|
||||||
{
|
{
|
||||||
__libc_init_common(elfdata, onexit, slingshot, structors, malloc_debug_init);
|
/* When we reach this point, all initializers have been already
|
||||||
|
* run by the dynamic linker, so ignore 'structors'.
|
||||||
|
*/
|
||||||
|
int argc = (int)*elfdata;
|
||||||
|
char** argv = (char**)(elfdata + 1);
|
||||||
|
char** envp = argv + argc + 1;
|
||||||
|
|
||||||
|
/* Several Linux ABIs don't pass the onexit pointer, and the ones that
|
||||||
|
* do never use it. Therefore, we ignore it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exit(slingshot(argc, argv, envp));
|
||||||
}
|
}
|
||||||
|
@ -28,24 +28,15 @@
|
|||||||
/*
|
/*
|
||||||
* libc_init_static.c
|
* libc_init_static.c
|
||||||
*
|
*
|
||||||
* This function takes the raw data block set up by the ELF loader
|
* The program startup function __libc_init() defined here is
|
||||||
* in the kernel and parses it. It is invoked by crt0.S which makes
|
* used for static executables only (i.e. those that don't depend
|
||||||
* any necessary adjustments and passes calls this function using
|
* on shared libraries). It is called from arch-$ARCH/bionic/crtbegin_static.S
|
||||||
* the standard C calling convention.
|
* which is directly invoked by the kernel when the program is launched.
|
||||||
*
|
*
|
||||||
* The arguments are:
|
* The 'structors' parameter contains pointers to various initializer
|
||||||
* uintptr_t *elfdata -- The ELF loader data block; usually from the stack.
|
* arrays that must be run before the program's 'main' routine is launched.
|
||||||
* Basically a pointer to argc.
|
|
||||||
* void (*onexit)(void) -- Function to install into onexit
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Several Linux ABIs don't pass the onexit pointer, and the ones that
|
|
||||||
* do never use it. Therefore, unless USE_ONEXIT is defined, we just
|
|
||||||
* ignore the onexit pointer.
|
|
||||||
*/
|
|
||||||
/* #define USE_ONEXIT */
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -58,19 +49,47 @@
|
|||||||
#include <bionic_tls.h>
|
#include <bionic_tls.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
static void call_array(void(**list)())
|
||||||
|
{
|
||||||
|
// First element is -1, list is null-terminated
|
||||||
|
while (*++list) {
|
||||||
|
(*list)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__noreturn void __libc_init(uintptr_t *elfdata,
|
__noreturn void __libc_init(uintptr_t *elfdata,
|
||||||
void (*onexit)(void),
|
void (*onexit)(void),
|
||||||
int (*slingshot)(int, char**, char**),
|
int (*slingshot)(int, char**, char**),
|
||||||
structors_array_t const * const structors)
|
structors_array_t const * const structors)
|
||||||
{
|
{
|
||||||
/*
|
int argc;
|
||||||
* To enable malloc checks for statically linked programs, add
|
char **argv, **envp;
|
||||||
* "WITH_MALLOC_CHECK_LIBC_A := true" in device/buildspec.mk
|
|
||||||
*/
|
/* Initialize the C runtime environment */
|
||||||
|
__libc_init_common(elfdata);
|
||||||
|
|
||||||
#ifdef MALLOC_LEAK_CHECK
|
#ifdef MALLOC_LEAK_CHECK
|
||||||
extern void malloc_debug_init();
|
/* setup malloc leak checker, requires system properties */
|
||||||
__libc_init_common(elfdata, onexit, slingshot, structors, malloc_debug_init);
|
extern void malloc_debug_init(void);
|
||||||
#else
|
malloc_debug_init();
|
||||||
__libc_init_common(elfdata, onexit, slingshot, structors, NULL);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Several Linux ABIs don't pass the onexit pointer, and the ones that
|
||||||
|
* do never use it. Therefore, we ignore it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* pre-init array. */
|
||||||
|
call_array(structors->preinit_array);
|
||||||
|
|
||||||
|
/* .ctors section initializers, for non-arm-eabi ABIs */
|
||||||
|
call_array(structors->ctors_array);
|
||||||
|
|
||||||
|
// call static constructors
|
||||||
|
call_array(structors->init_array);
|
||||||
|
|
||||||
|
argc = (int) *elfdata;
|
||||||
|
argv = (char**)(elfdata + 1);
|
||||||
|
envp = argv + argc + 1;
|
||||||
|
|
||||||
|
exit(slingshot(argc, argv, envp));
|
||||||
}
|
}
|
||||||
|
@ -126,8 +126,8 @@ static int __android_log_write(int prio, const char *tag, const char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int __android_log_vprint(int prio, const char *tag, const char *fmt,
|
int __libc_android_log_vprint(int prio, const char *tag, const char *fmt,
|
||||||
va_list ap)
|
va_list ap)
|
||||||
{
|
{
|
||||||
char buf[LOG_BUF_SIZE];
|
char buf[LOG_BUF_SIZE];
|
||||||
|
|
||||||
|
@ -91,7 +91,14 @@ static pthread_mutex_t gAllocationsMutex = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
static HashTable gHashTable;
|
static HashTable gHashTable;
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// output fucntions
|
// log functions
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
#define debug_log(format, ...) \
|
||||||
|
__libc_android_log_print(ANDROID_LOG_DEBUG, "malloc_leak", (format), ##__VA_ARGS__ )
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// output functions
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
static int hash_entry_compare(const void* arg1, const void* arg2)
|
static int hash_entry_compare(const void* arg1, const void* arg2)
|
||||||
@ -257,12 +264,6 @@ struct AllocationEntry {
|
|||||||
uint32_t guard;
|
uint32_t guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// log funtions
|
|
||||||
// =============================================================================
|
|
||||||
|
|
||||||
#define debug_log(format, ...) \
|
|
||||||
__libc_android_log_print(ANDROID_LOG_DEBUG, "malloc_leak", (format), ##__VA_ARGS__ )
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Hash Table functions
|
// Hash Table functions
|
||||||
@ -515,8 +516,8 @@ static void dump_stack_trace()
|
|||||||
|
|
||||||
tmp[0] = 0; // Need to initialize tmp[0] for the first strcat
|
tmp[0] = 0; // Need to initialize tmp[0] for the first strcat
|
||||||
for (i=0 ; i<c; i++) {
|
for (i=0 ; i<c; i++) {
|
||||||
sprintf(buf, "%2d: %08x\n", i, addrs[i]);
|
snprintf(buf, sizeof buf, "%2d: %08x\n", i, addrs[i]);
|
||||||
strcat(tmp, buf);
|
strlcat(tmp, buf, sizeof tmp);
|
||||||
}
|
}
|
||||||
__libc_android_log_print(ANDROID_LOG_ERROR, "libc", "call stack:\n%s", tmp);
|
__libc_android_log_print(ANDROID_LOG_ERROR, "libc", "call stack:\n%s", tmp);
|
||||||
}
|
}
|
||||||
@ -526,69 +527,90 @@ static int is_valid_malloc_pointer(void* addr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void assert_log_message(const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&gAllocationsMutex);
|
||||||
|
gMallocDispatch = &gMallocEngineTable[INDEX_NORMAL];
|
||||||
|
va_start(args, format);
|
||||||
|
__libc_android_log_vprint(ANDROID_LOG_ERROR, "libc",
|
||||||
|
format, args);
|
||||||
|
va_end(args);
|
||||||
|
dump_stack_trace();
|
||||||
|
if (gTrapOnError) {
|
||||||
|
__builtin_trap();
|
||||||
|
}
|
||||||
|
gMallocDispatch = &gMallocEngineTable[INDEX_MALLOC_CHECK];
|
||||||
|
pthread_mutex_unlock(&gAllocationsMutex);
|
||||||
|
}
|
||||||
|
|
||||||
static void assert_valid_malloc_pointer(void* mem)
|
static void assert_valid_malloc_pointer(void* mem)
|
||||||
{
|
{
|
||||||
if (mem && !is_valid_malloc_pointer(mem)) {
|
if (mem && !is_valid_malloc_pointer(mem)) {
|
||||||
pthread_mutex_lock(&gAllocationsMutex);
|
assert_log_message(
|
||||||
gMallocDispatch = &gMallocEngineTable[INDEX_NORMAL];
|
"*** MALLOC CHECK: buffer %p, is not a valid "
|
||||||
__libc_android_log_print(ANDROID_LOG_ERROR, "libc",
|
"malloc pointer (are you mixing up new/delete "
|
||||||
"*** MALLOC CHECK: buffer %p, is not a valid "
|
"and malloc/free?)", mem);
|
||||||
"malloc pointer (are you mixing up new/delete "
|
|
||||||
"and malloc/free?)", mem);
|
|
||||||
dump_stack_trace();
|
|
||||||
if (gTrapOnError) {
|
|
||||||
__builtin_trap();
|
|
||||||
}
|
|
||||||
gMallocDispatch = &gMallocEngineTable[INDEX_MALLOC_CHECK];
|
|
||||||
pthread_mutex_unlock(&gAllocationsMutex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chk_out_of_bounds_check__locked(void* buffer, size_t size)
|
/* Check that a given address corresponds to a guarded block,
|
||||||
|
* and returns its original allocation size in '*allocated'.
|
||||||
|
* 'func' is the capitalized name of the caller function.
|
||||||
|
* Returns 0 on success, or -1 on failure.
|
||||||
|
* NOTE: Does not return if gTrapOnError is set.
|
||||||
|
*/
|
||||||
|
static int chk_mem_check(void* mem,
|
||||||
|
size_t* allocated,
|
||||||
|
const char* func)
|
||||||
{
|
{
|
||||||
int i;
|
char* buffer;
|
||||||
char* buf = (char*)buffer - CHK_SENTINEL_HEAD_SIZE;
|
size_t offset, bytes;
|
||||||
|
int i;
|
||||||
|
char* buf;
|
||||||
|
|
||||||
|
/* first check the bytes in the sentinel header */
|
||||||
|
buf = (char*)mem - CHK_SENTINEL_HEAD_SIZE;
|
||||||
for (i=0 ; i<CHK_SENTINEL_HEAD_SIZE ; i++) {
|
for (i=0 ; i<CHK_SENTINEL_HEAD_SIZE ; i++) {
|
||||||
if (buf[i] != CHK_SENTINEL_VALUE) {
|
if (buf[i] != CHK_SENTINEL_VALUE) {
|
||||||
gMallocDispatch = &gMallocEngineTable[INDEX_NORMAL];
|
assert_log_message(
|
||||||
__libc_android_log_print(ANDROID_LOG_ERROR, "libc",
|
"*** %s CHECK: buffer %p "
|
||||||
"*** MALLOC CHECK: buffer %p, size=%lu, "
|
"corrupted %d bytes before allocation",
|
||||||
"corrupted %d bytes before allocation",
|
func, mem, CHK_SENTINEL_HEAD_SIZE-i);
|
||||||
buffer, size, CHK_SENTINEL_HEAD_SIZE-i);
|
return -1;
|
||||||
dump_stack_trace();
|
|
||||||
if (gTrapOnError) {
|
|
||||||
__builtin_trap();
|
|
||||||
}
|
|
||||||
gMallocDispatch = &gMallocEngineTable[INDEX_MALLOC_CHECK];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf = (char*)buffer + size;
|
|
||||||
|
/* then the ones in the sentinel trailer */
|
||||||
|
buffer = (char*)mem - CHK_SENTINEL_HEAD_SIZE;
|
||||||
|
offset = dlmalloc_usable_size(buffer) - sizeof(size_t);
|
||||||
|
bytes = *(size_t *)(buffer + offset);
|
||||||
|
|
||||||
|
buf = (char*)mem + bytes;
|
||||||
for (i=CHK_SENTINEL_TAIL_SIZE-1 ; i>=0 ; i--) {
|
for (i=CHK_SENTINEL_TAIL_SIZE-1 ; i>=0 ; i--) {
|
||||||
if (buf[i] != CHK_SENTINEL_VALUE) {
|
if (buf[i] != CHK_SENTINEL_VALUE) {
|
||||||
gMallocDispatch = &gMallocEngineTable[INDEX_NORMAL];
|
assert_log_message(
|
||||||
__libc_android_log_print(ANDROID_LOG_ERROR, "libc",
|
"*** %s CHECK: buffer %p, size=%lu, "
|
||||||
"*** MALLOC CHECK: buffer %p, size=%lu, "
|
"corrupted %d bytes after allocation",
|
||||||
"corrupted %d bytes after allocation",
|
func, buffer, bytes, i+1);
|
||||||
buffer, size, i+1);
|
return -1;
|
||||||
dump_stack_trace();
|
|
||||||
if (gTrapOnError) {
|
|
||||||
__builtin_trap();
|
|
||||||
}
|
|
||||||
gMallocDispatch = &gMallocEngineTable[INDEX_MALLOC_CHECK];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*allocated = bytes;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* chk_malloc(size_t bytes)
|
void* chk_malloc(size_t bytes)
|
||||||
{
|
{
|
||||||
char* buffer = (char*)dlmalloc(bytes + CHK_OVERHEAD_SIZE);
|
char* buffer = (char*)dlmalloc(bytes + CHK_OVERHEAD_SIZE);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
pthread_mutex_lock(&gAllocationsMutex);
|
memset(buffer, CHK_SENTINEL_VALUE, bytes + CHK_OVERHEAD_SIZE);
|
||||||
memset(buffer, CHK_SENTINEL_VALUE, bytes + CHK_OVERHEAD_SIZE);
|
size_t offset = dlmalloc_usable_size(buffer) - sizeof(size_t);
|
||||||
size_t offset = dlmalloc_usable_size(buffer) - sizeof(size_t);
|
*(size_t *)(buffer + offset) = bytes;
|
||||||
*(size_t *)(buffer + offset) = bytes;
|
buffer += CHK_SENTINEL_HEAD_SIZE;
|
||||||
buffer += CHK_SENTINEL_HEAD_SIZE;
|
|
||||||
pthread_mutex_unlock(&gAllocationsMutex);
|
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@ -597,14 +619,14 @@ void chk_free(void* mem)
|
|||||||
{
|
{
|
||||||
assert_valid_malloc_pointer(mem);
|
assert_valid_malloc_pointer(mem);
|
||||||
if (mem) {
|
if (mem) {
|
||||||
pthread_mutex_lock(&gAllocationsMutex);
|
size_t size;
|
||||||
char* buffer = (char*)mem - CHK_SENTINEL_HEAD_SIZE;
|
char* buffer;
|
||||||
size_t offset = dlmalloc_usable_size(buffer) - sizeof(size_t);
|
|
||||||
size_t bytes = *(size_t *)(buffer + offset);
|
if (chk_mem_check(mem, &size, "FREE") == 0) {
|
||||||
chk_out_of_bounds_check__locked(mem, bytes);
|
buffer = (char*)mem - CHK_SENTINEL_HEAD_SIZE;
|
||||||
pthread_mutex_unlock(&gAllocationsMutex);
|
memset(buffer, CHK_FILL_FREE, size + CHK_OVERHEAD_SIZE);
|
||||||
memset(buffer, CHK_FILL_FREE, bytes);
|
dlfree(buffer);
|
||||||
dlfree(buffer);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,19 +650,20 @@ void* chk_calloc(size_t n_elements, size_t elem_size)
|
|||||||
|
|
||||||
void* chk_realloc(void* mem, size_t bytes)
|
void* chk_realloc(void* mem, size_t bytes)
|
||||||
{
|
{
|
||||||
|
char* buffer;
|
||||||
|
int ret;
|
||||||
|
size_t old_bytes = 0;
|
||||||
|
|
||||||
assert_valid_malloc_pointer(mem);
|
assert_valid_malloc_pointer(mem);
|
||||||
|
|
||||||
|
if (mem != NULL && chk_mem_check(mem, &old_bytes, "REALLOC") < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
char* new_buffer = chk_malloc(bytes);
|
char* new_buffer = chk_malloc(bytes);
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
return new_buffer;
|
return new_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&gAllocationsMutex);
|
|
||||||
char* buffer = (char*)mem - CHK_SENTINEL_HEAD_SIZE;
|
|
||||||
size_t offset = dlmalloc_usable_size(buffer) - sizeof(size_t);
|
|
||||||
size_t old_bytes = *(size_t *)(buffer + offset);
|
|
||||||
chk_out_of_bounds_check__locked(mem, old_bytes);
|
|
||||||
pthread_mutex_unlock(&gAllocationsMutex);
|
|
||||||
|
|
||||||
if (new_buffer) {
|
if (new_buffer) {
|
||||||
size_t size = (bytes < old_bytes)?(bytes):(old_bytes);
|
size_t size = (bytes < old_bytes)?(bytes):(old_bytes);
|
||||||
memcpy(new_buffer, mem, size);
|
memcpy(new_buffer, mem, size);
|
||||||
|
67
libc/kernel/common/linux/uinput.h
Normal file
67
libc/kernel/common/linux/uinput.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
****************************************************************************
|
||||||
|
***
|
||||||
|
*** This header was automatically generated from a Linux kernel header
|
||||||
|
*** of the same name, to make information necessary for userspace to
|
||||||
|
*** call into the kernel available to libc. It contains only constants,
|
||||||
|
*** structures, and macros generated from the original header, and thus,
|
||||||
|
*** contains no copyrightable information.
|
||||||
|
***
|
||||||
|
****************************************************************************
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __UINPUT_H_
|
||||||
|
#define __UINPUT_H_
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#define UINPUT_VERSION 3
|
||||||
|
|
||||||
|
struct uinput_ff_upload {
|
||||||
|
int request_id;
|
||||||
|
int retval;
|
||||||
|
struct ff_effect effect;
|
||||||
|
struct ff_effect old;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct uinput_ff_erase {
|
||||||
|
int request_id;
|
||||||
|
int retval;
|
||||||
|
int effect_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UINPUT_IOCTL_BASE 'U'
|
||||||
|
#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
|
||||||
|
#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
|
||||||
|
|
||||||
|
#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
|
||||||
|
#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
|
||||||
|
#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
|
||||||
|
#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
|
||||||
|
#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
|
||||||
|
#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
|
||||||
|
#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
|
||||||
|
#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
|
||||||
|
#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
|
||||||
|
#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
|
||||||
|
|
||||||
|
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
|
||||||
|
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
|
||||||
|
#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
|
||||||
|
#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
|
||||||
|
|
||||||
|
#define EV_UINPUT 0x0101
|
||||||
|
#define UI_FF_UPLOAD 1
|
||||||
|
#define UI_FF_ERASE 2
|
||||||
|
|
||||||
|
#define UINPUT_MAX_NAME_SIZE 80
|
||||||
|
struct uinput_user_dev {
|
||||||
|
char name[UINPUT_MAX_NAME_SIZE];
|
||||||
|
struct input_id id;
|
||||||
|
int ff_effects_max;
|
||||||
|
int absmax[ABS_MAX + 1];
|
||||||
|
int absmin[ABS_MAX + 1];
|
||||||
|
int absfuzz[ABS_MAX + 1];
|
||||||
|
int absflat[ABS_MAX + 1];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
@ -60,6 +60,13 @@ __BEGIN_DECLS
|
|||||||
#define TLS_SLOT_OPENGL_API 3
|
#define TLS_SLOT_OPENGL_API 3
|
||||||
#define TLS_SLOT_OPENGL 4
|
#define TLS_SLOT_OPENGL 4
|
||||||
|
|
||||||
|
/* this slot is only used to pass information from the dynamic linker to
|
||||||
|
* libc.so when the C library is loaded in to memory. The C runtime init
|
||||||
|
* function will then clear it. Since its use is extremely temporary,
|
||||||
|
* we reuse an existing location.
|
||||||
|
*/
|
||||||
|
#define TLS_SLOT_BIONIC_PREINIT (TLS_SLOT_ERRNO+1)
|
||||||
|
|
||||||
/* small technical note: it is not possible to call pthread_setspecific
|
/* small technical note: it is not possible to call pthread_setspecific
|
||||||
* on keys that are <= TLS_SLOT_MAX_WELL_KNOWN, which is why it is set to
|
* on keys that are <= TLS_SLOT_MAX_WELL_KNOWN, which is why it is set to
|
||||||
* TLS_SLOT_ERRNO.
|
* TLS_SLOT_ERRNO.
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#ifndef _ANDROID_BIONIC_LOGD_H
|
#ifndef _ANDROID_BIONIC_LOGD_H
|
||||||
#define _ANDROID_BIONIC_LOGD_H
|
#define _ANDROID_BIONIC_LOGD_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ANDROID_LOG_UNKNOWN = 0,
|
ANDROID_LOG_UNKNOWN = 0,
|
||||||
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
|
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
|
||||||
@ -43,5 +45,6 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int __libc_android_log_print(int prio, const char *tag, const char *fmt, ...);
|
int __libc_android_log_print(int prio, const char *tag, const char *fmt, ...);
|
||||||
|
int __libc_android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap);
|
||||||
|
|
||||||
#endif /* _ANDROID_BIONIC_LOGD_H */
|
#endif /* _ANDROID_BIONIC_LOGD_H */
|
||||||
|
40
libstdc++/include/cerrno
Normal file
40
libstdc++/include/cerrno
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BIONIC_LIBSTDCPP_INCLUDE_CERRNO__
|
||||||
|
#define BIONIC_LIBSTDCPP_INCLUDE_CERRNO__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C++ Library wrapper around the C errno.h header file.
|
||||||
|
*/
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
// errno is a macro, so we can't define std::errno
|
||||||
|
|
||||||
|
#endif // BIONIC_LIBSTDCPP_INCLUDE_CERRNO__
|
39
libstdc++/include/cfloat
Normal file
39
libstdc++/include/cfloat
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BIONIC_LIBSTDCPP_INCLUDE_CFLOAT__
|
||||||
|
#define BIONIC_LIBSTDCPP_INCLUDE_CFLOAT__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C++ Library wrapper around the C float.h header file.
|
||||||
|
*/
|
||||||
|
#include <sys/limits.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#endif // BIONIC_LIBSTDCPP_INCLUDE_CFLOAT__
|
@ -85,6 +85,11 @@ using ::srand;
|
|||||||
using ::random;
|
using ::random;
|
||||||
using ::srandom;
|
using ::srandom;
|
||||||
|
|
||||||
|
using ::malloc;
|
||||||
|
using ::free;
|
||||||
|
using ::calloc;
|
||||||
|
using ::realloc;
|
||||||
|
|
||||||
using ::unlockpt;
|
using ::unlockpt;
|
||||||
using ::ptsname;
|
using ::ptsname;
|
||||||
using ::ptsname_r;
|
using ::ptsname_r;
|
||||||
|
@ -76,11 +76,6 @@
|
|||||||
* headers provide versions that are negative...
|
* headers provide versions that are negative...
|
||||||
* - allocate space for soinfo structs dynamically instead of
|
* - allocate space for soinfo structs dynamically instead of
|
||||||
* having a hard limit (64)
|
* having a hard limit (64)
|
||||||
*
|
|
||||||
* features to add someday:
|
|
||||||
*
|
|
||||||
* - dlopen() and friends
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -1744,6 +1739,11 @@ unsigned __linker_init(unsigned **elfdata)
|
|||||||
struct link_map * map;
|
struct link_map * map;
|
||||||
char *ldpath_env = NULL;
|
char *ldpath_env = NULL;
|
||||||
|
|
||||||
|
/* Setup a temporary TLS area that is used to get a working
|
||||||
|
* errno for system calls.
|
||||||
|
*/
|
||||||
|
__set_tls(__tls_area);
|
||||||
|
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
|
|
||||||
#if TIMING
|
#if TIMING
|
||||||
@ -1751,8 +1751,15 @@ unsigned __linker_init(unsigned **elfdata)
|
|||||||
gettimeofday(&t0, 0);
|
gettimeofday(&t0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__set_tls(__tls_area);
|
/* NOTE: we store the elfdata pointer on a special location
|
||||||
((unsigned *)__get_tls())[TLS_SLOT_THREAD_ID] = gettid();
|
* of the temporary TLS area in order to pass it to
|
||||||
|
* the C Library's runtime initializer.
|
||||||
|
*
|
||||||
|
* The initializer must clear the slot and reset the TLS
|
||||||
|
* to point to a different location to ensure that no other
|
||||||
|
* shared library constructor can access it.
|
||||||
|
*/
|
||||||
|
__tls_area[TLS_SLOT_BIONIC_PREINIT] = elfdata;
|
||||||
|
|
||||||
debugger_init();
|
debugger_init();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user