merge from open-source master

Change-Id: I70266ee8c520b216773f267e46c8273d2334c31d
This commit is contained in:
The Android Open Source Project 2010-03-22 15:55:09 -07:00
commit 377d4c979d
27 changed files with 189 additions and 59 deletions

View file

@ -343,6 +343,7 @@ libc_common_src_files += \
arch-x86/bionic/setjmp.S \ arch-x86/bionic/setjmp.S \
arch-x86/bionic/_setjmp.S \ arch-x86/bionic/_setjmp.S \
arch-x86/bionic/vfork.S \ arch-x86/bionic/vfork.S \
arch-x86/bionic/syscall.S \
arch-x86/string/bzero.S \ arch-x86/string/bzero.S \
arch-x86/string/memset.S \ arch-x86/string/memset.S \
arch-x86/string/memcmp.S \ arch-x86/string/memcmp.S \

View file

@ -0,0 +1,52 @@
/*
* Generic syscall call.
* Upon entry
* %eax: system call number
* %ebx: arg0 to system call
* %ecx: arg..
* %edx: arg..
* %esi: arg..
* %edi: arg..
* We push these (to save them) load them up with the
* values from the calling frame (not all will actually be valid)
* and make the syscall.
*/
#include <sys/linux-syscalls.h>
.text
.type syscall, @function
.globl syscall
.align 4
syscall:
push %eax
push %ebx
push %ecx
push %edx
push %esi
push %edi
mov 28(%esp),%eax
mov 32(%esp),%ebx
mov 36(%esp),%ecx
mov 40(%esp),%edx
mov 44(%esp),%esi
mov 48(%esp),%edi
int $0x80
cmpl $-129, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno
addl $4, %esp
orl $-1, %eax
1:
pop %edi
pop %esi
pop %edx
pop %ecx
pop %ebx
pop %eax
ret

View file

@ -430,8 +430,9 @@ void* chk_realloc(void* mem, size_t bytes)
} }
if (new_buffer) { if (new_buffer) {
size_t size = (bytes < old_bytes)?(bytes):(old_bytes); if (bytes > old_bytes)
memcpy(new_buffer, mem, size); bytes = old_bytes;
memcpy(new_buffer, mem, bytes);
chk_free(mem); chk_free(mem);
} }

View file

@ -601,13 +601,12 @@ int pthread_join(pthread_t thid, void ** ret_val)
for (thread = gThreadList; thread != NULL; thread = thread->next) for (thread = gThreadList; thread != NULL; thread = thread->next)
if (thread == (pthread_internal_t*)thid) if (thread == (pthread_internal_t*)thid)
break; goto FoundIt;
if (!thread) { pthread_mutex_unlock(&gThreadListLock);
pthread_mutex_unlock(&gThreadListLock); return ESRCH;
return ESRCH;
}
FoundIt:
if (thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) { if (thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) {
pthread_mutex_unlock(&gThreadListLock); pthread_mutex_unlock(&gThreadListLock);
return EINVAL; return EINVAL;

View file

@ -34,7 +34,7 @@ void pututline(struct utmp* utmp)
{ {
FILE* f; FILE* f;
struct utmp u; struct utmp u;
int i; long i;
if (!(f = fopen(_PATH_UTMP, "w+"))) if (!(f = fopen(_PATH_UTMP, "w+")))
return; return;

View file

@ -76,9 +76,9 @@ void __stack_chk_fail(void)
sigprocmask(SIG_BLOCK, &sigmask, NULL); sigprocmask(SIG_BLOCK, &sigmask, NULL);
/* Use /proc/self/exe link to obtain the program name for logging /* Use /proc/self/exe link to obtain the program name for logging
* purposes. If it's not available, we set it to "unknown" */ * purposes. If it's not available, we set it to "<unknown>" */
if ((count = readlink("/proc/self/exe", path, sizeof(path) - 1)) == -1) { if ((count = readlink("/proc/self/exe", path, sizeof(path) - 1)) == -1) {
strlcpy(path, "unknown", sizeof(path)); strlcpy(path, "<unknown>", sizeof(path));
} else { } else {
path[count] = '\0'; path[count] = '\0';
} }

View file

@ -32,10 +32,22 @@
__BEGIN_DECLS __BEGIN_DECLS
typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Address at which shared object
is loaded */
const char *dli_sname; /* Name of nearest symbol with address
lower than addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;
extern void* dlopen(const char* filename, int flag); extern void* dlopen(const char* filename, int flag);
extern int dlclose(void* handle); extern int dlclose(void* handle);
extern const char* dlerror(void); extern const char* dlerror(void);
extern void* dlsym(void* handle, const char* symbol); extern void* dlsym(void* handle, const char* symbol);
extern int dladdr(void* addr, Dl_info *info);
enum { enum {
RTLD_NOW = 0, RTLD_NOW = 0,

View file

@ -98,8 +98,8 @@ strncasecmp(const char *s1, const char *s2, size_t n)
if (cm[*us1] != cm[*us2++]) if (cm[*us1] != cm[*us2++])
return (cm[*us1] - cm[*--us2]); return (cm[*us1] - cm[*--us2]);
if (*us1++ == '\0') if (*us1++ == '\0')
break; break;
} while (--n != 0); } while (--n != 0);
} }
return (0); return (0);
} }

View file

@ -38,6 +38,6 @@ strchr(const char *p, int ch)
return((char *)p); return((char *)p);
if (!*p) if (!*p)
return((char *)NULL); return((char *)NULL);
} }
/* NOTREACHED */ /* NOTREACHED */
} }

View file

@ -36,5 +36,5 @@
int int
strcoll(const char *s1, const char *s2) strcoll(const char *s1, const char *s2)
{ {
return strcmp (s1, s2); return strcmp(s1, s2);
} }

View file

@ -46,9 +46,9 @@ strlcat(char *dst, const char *src, size_t siz)
if (n != 1) { if (n != 1) {
*d++ = *s; *d++ = *s;
n--; n--;
} }
s++; s++;
} }
*d = '\0'; *d = '\0';
return(dlen + (s - src)); /* count does not include NUL */ return(dlen + (s - src)); /* count does not include NUL */

View file

@ -37,7 +37,7 @@ strlcpy(char *dst, const char *src, size_t siz)
if ((*d++ = *s++) == '\0') if ((*d++ = *s++) == '\0')
break; break;
} }
} }
/* Not enough room in dst, add NUL and traverse rest of src */ /* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) { if (n == 0) {

View file

@ -52,6 +52,6 @@ strncat(char *dst, const char *src, size_t n)
d++; d++;
} while (--n != 0); } while (--n != 0);
*d = 0; *d = 0;
} }
return (dst); return (dst);
} }

View file

@ -38,14 +38,13 @@
int int
strncmp(const char *s1, const char *s2, size_t n) strncmp(const char *s1, const char *s2, size_t n)
{ {
if (n == 0) if (n == 0)
return (0); return (0);
do { do {
if (*s1 != *s2++) if (*s1 != *s2++)
return (*(unsigned char *)s1 - *(unsigned char *)--s2); return (*(unsigned char *)s1 - *(unsigned char *)--s2);
if (*s1++ == 0) if (*s1++ == 0)
break; break;
} while (--n != 0); } while (--n != 0);
return (0); return (0);
} }

View file

@ -54,8 +54,8 @@ strncpy(char *dst, const char *src, size_t n)
/* NUL pad the remaining n-1 bytes */ /* NUL pad the remaining n-1 bytes */
while (--n != 0) while (--n != 0)
*d++ = 0; *d++ = 0;
break; break;
} }
} while (--n != 0); } while (--n != 0);
} }
return (dst); return (dst);

View file

@ -38,7 +38,7 @@ strpbrk(const char *s1, const char *s2)
{ {
const char *scanp; const char *scanp;
int c, sc; int c, sc;
while ((c = *s1++) != 0) { while ((c = *s1++) != 0) {
for (scanp = s2; (sc = *scanp++) != 0;) for (scanp = s2; (sc = *scanp++) != 0;)
if (sc == c) if (sc == c)

View file

@ -34,12 +34,12 @@ char *
strrchr(const char *p, int ch) strrchr(const char *p, int ch)
{ {
char *save; char *save;
for (save = NULL;; ++p) { for (save = NULL;; ++p) {
if (*p == ch) if (*p == ch)
save = (char *)p; save = (char *)p;
if (!*p) if (!*p)
return(save); return(save);
} }
/* NOTREACHED */ /* NOTREACHED */
} }

View file

@ -34,7 +34,7 @@
/* /*
* Get next token from string *stringp, where tokens are possibly-empty * Get next token from string *stringp, where tokens are possibly-empty
* strings separated by characters from delim. * strings separated by characters from delim.
* *
* Writes NULs into the string at *stringp to end tokens. * Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call. * delim need not remain constant from call to call.

View file

@ -51,6 +51,6 @@ strstr(const char *s, const char *find)
} while (sc != c); } while (sc != c);
} while (strncmp(s, find, len) != 0); } while (strncmp(s, find, len) != 0);
s--; s--;
} }
return ((char *)s); return ((char *)s);
} }

View file

@ -29,7 +29,7 @@
/* /*
* Transform string s2 to string s1 using the current locale so that * Transform string s2 to string s1 using the current locale so that
* strcmp of transformed strings yields the same result as strcoll. * strcmp of transformed strings yields the same result as strcoll.
* Since Bionic really does not support locales, we assume we always use * Since Bionic really does not support locales, we assume we always use
* the C locale. * the C locale.
* *

View file

@ -25,10 +25,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
extern int __pread64(int fd, void *buf, size_t nbytes, off_t lo, off_t hi); extern int __pread64(int fd, void *buf, size_t nbytes, loff_t offset);
ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset) ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset)
{ {
return __pread64(fd, buf, nbytes, offset, 0); return __pread64(fd, buf, nbytes, offset);
} }

View file

@ -28,10 +28,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
extern int __pwrite64(int fd, void *buf, size_t nbytes, off_t lo, off_t hi); extern int __pwrite64(int fd, void *buf, size_t nbytes, loff_t offset);
ssize_t pwrite(int fd, void *buf, size_t nbytes, off_t offset) ssize_t pwrite(int fd, void *buf, size_t nbytes, off_t offset)
{ {
return __pwrite64(fd, buf, nbytes, offset, 0); return __pwrite64(fd, buf, nbytes, offset);
} }

View file

@ -14,12 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
#include <dlfcn.h>
/* These are stubs for functions that are actually defined /* These are stubs for functions that are actually defined
* in the dynamic linker (dlfcn.c), and hijacked at runtime. * in the dynamic linker (dlfcn.c), and hijacked at runtime.
*/ */
void *dlopen(const char *filename, int flag) { return 0; } void *dlopen(const char *filename, int flag) { return 0; }
char *dlerror(void) { return 0; } const char *dlerror(void) { return 0; }
void *dlsym(void *handle, const char *symbol) { return 0; } void *dlsym(void *handle, const char *symbol) { return 0; }
int dladdr(void *addr, Dl_info *info) { return 0; }
int dlclose(void *handle) { return 0; } int dlclose(void *handle) { return 0; }
#ifdef __arm__ #ifdef __arm__

View file

@ -23,16 +23,12 @@ void* operator new[](std::size_t size)
void operator delete(void* ptr) void operator delete(void* ptr)
{ {
if (ptr) { free(ptr);
free(ptr);
}
} }
void operator delete[](void* ptr) void operator delete[](void* ptr)
{ {
if (ptr) { free(ptr);
free(ptr);
}
} }
void* operator new(std::size_t size, const std::nothrow_t&) void* operator new(std::size_t size, const std::nothrow_t&)
@ -47,16 +43,12 @@ void* operator new[](std::size_t size, const std::nothrow_t&)
void operator delete(void* ptr, const std::nothrow_t&) void operator delete(void* ptr, const std::nothrow_t&)
{ {
if (ptr) { free(ptr);
free(ptr);
}
} }
void operator delete[](void* ptr, const std::nothrow_t&) void operator delete[](void* ptr, const std::nothrow_t&)
{ {
if (ptr) { free(ptr);
free(ptr);
}
} }

View file

@ -118,6 +118,37 @@ err:
return 0; return 0;
} }
int dladdr(void *addr, Dl_info *info)
{
int ret = 0;
pthread_mutex_lock(&dl_lock);
/* Determine if this address can be found in any library currently mapped */
soinfo *si = find_containing_library(addr);
if(si) {
memset(info, 0, sizeof(Dl_info));
info->dli_fname = si->name;
info->dli_fbase = (void*)si->base;
/* Determine if any symbol in the library contains the specified address */
Elf32_Sym *sym = find_containing_symbol(addr, si);
if(sym != NULL) {
info->dli_sname = si->strtab + sym->st_name;
info->dli_saddr = (void*)(si->base + sym->st_value);
}
ret = 1;
}
pthread_mutex_unlock(&dl_lock);
return ret;
}
int dlclose(void *handle) int dlclose(void *handle)
{ {
pthread_mutex_lock(&dl_lock); pthread_mutex_lock(&dl_lock);
@ -127,22 +158,22 @@ int dlclose(void *handle)
} }
#if defined(ANDROID_ARM_LINKER) #if defined(ANDROID_ARM_LINKER)
// 0000000 00011111 111112 22222222 233333333334444444444 // 0000000 00011111 111112 22222222 2333333 333344444444445555555
// 0123456 78901234 567890 12345678 901234567890123456789 // 0123456 78901234 567890 12345678 9012345 678901234567890123456
#define ANDROID_LIBDL_STRTAB \ #define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dl_unwind_find_exidx\0" "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_unwind_find_exidx\0"
#elif defined(ANDROID_X86_LINKER) #elif defined(ANDROID_X86_LINKER)
// 0000000 00011111 111112 22222222 2333333333344444 // 0000000 00011111 111112 22222222 2333333 3333444444444455
// 0123456 78901234 567890 12345678 9012345678901234 // 0123456 78901234 567890 12345678 9012345 6789012345678901
#define ANDROID_LIBDL_STRTAB \ #define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dl_iterate_phdr\0" "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0"
#elif defined(ANDROID_SH_LINKER) #elif defined(ANDROID_SH_LINKER)
// 0000000 00011111 111112 22222222 2333333333344444 // 0000000 00011111 111112 22222222 2333333 3333444444444455
// 0123456 78901234 567890 12345678 9012345678901234 // 0123456 78901234 567890 12345678 9012345 6789012345678901
#define ANDROID_LIBDL_STRTAB \ #define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dl_iterate_phdr\0" "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0"
#else /* !defined(ANDROID_ARM_LINKER) && !defined(ANDROID_X86_LINKER) */ #else /* !defined(ANDROID_ARM_LINKER) && !defined(ANDROID_X86_LINKER) */
#error Unsupported architecture. Only ARM and x86 are presently supported. #error Unsupported architecture. Only ARM and x86 are presently supported.
@ -176,20 +207,25 @@ static Elf32_Sym libdl_symtab[] = {
st_info: STB_GLOBAL << 4, st_info: STB_GLOBAL << 4,
st_shndx: 1, st_shndx: 1,
}, },
#ifdef ANDROID_ARM_LINKER
{ st_name: 29, { st_name: 29,
st_value: (Elf32_Addr) &dladdr,
st_info: STB_GLOBAL << 4,
st_shndx: 1,
},
#ifdef ANDROID_ARM_LINKER
{ st_name: 36,
st_value: (Elf32_Addr) &dl_unwind_find_exidx, st_value: (Elf32_Addr) &dl_unwind_find_exidx,
st_info: STB_GLOBAL << 4, st_info: STB_GLOBAL << 4,
st_shndx: 1, st_shndx: 1,
}, },
#elif defined(ANDROID_X86_LINKER) #elif defined(ANDROID_X86_LINKER)
{ st_name: 29, { st_name: 36,
st_value: (Elf32_Addr) &dl_iterate_phdr, st_value: (Elf32_Addr) &dl_iterate_phdr,
st_info: STB_GLOBAL << 4, st_info: STB_GLOBAL << 4,
st_shndx: 1, st_shndx: 1,
}, },
#elif defined(ANDROID_SH_LINKER) #elif defined(ANDROID_SH_LINKER)
{ st_name: 29, { st_name: 36,
st_value: (Elf32_Addr) &dl_iterate_phdr, st_value: (Elf32_Addr) &dl_iterate_phdr,
st_info: STB_GLOBAL << 4, st_info: STB_GLOBAL << 4,
st_shndx: 1, st_shndx: 1,
@ -217,7 +253,7 @@ static Elf32_Sym libdl_symtab[] = {
* stubbing them out in libdl. * stubbing them out in libdl.
*/ */
static unsigned libdl_buckets[1] = { 1 }; static unsigned libdl_buckets[1] = { 1 };
static unsigned libdl_chains[6] = { 0, 2, 3, 4, 5, 0 }; static unsigned libdl_chains[7] = { 0, 2, 3, 4, 5, 6, 0 };
soinfo libdl_info = { soinfo libdl_info = {
name: "libdl.so", name: "libdl.so",
@ -227,7 +263,7 @@ soinfo libdl_info = {
symtab: libdl_symtab, symtab: libdl_symtab,
nbucket: 1, nbucket: 1,
nchain: 6, nchain: 7,
bucket: libdl_buckets, bucket: libdl_buckets,
chain: libdl_chains, chain: libdl_chains,
}; };

View file

@ -535,6 +535,40 @@ Elf32_Sym *lookup(const char *name, soinfo **found)
return NULL; return NULL;
} }
soinfo *find_containing_library(void *addr)
{
soinfo *si;
for(si = solist; si != NULL; si = si->next)
{
if((unsigned)addr >= si->base && (unsigned)addr - si->base < si->size) {
return si;
}
}
return NULL;
}
Elf32_Sym *find_containing_symbol(void *addr, soinfo *si)
{
unsigned int i;
unsigned soaddr = (unsigned)addr - si->base;
/* Search the library's symbol table for any defined symbol which
* contains this address */
for(i=0; i<si->nchain; i++) {
Elf32_Sym *sym = &si->symtab[i];
if(sym->st_shndx != SHN_UNDEF &&
soaddr >= sym->st_value &&
soaddr < sym->st_value + sym->st_size) {
return sym;
}
}
return NULL;
}
#if 0 #if 0
static void dump(soinfo *si) static void dump(soinfo *si)
{ {

View file

@ -225,6 +225,8 @@ soinfo *find_library(const char *name);
unsigned unload_library(soinfo *si); unsigned unload_library(soinfo *si);
Elf32_Sym *lookup_in_library(soinfo *si, const char *name); Elf32_Sym *lookup_in_library(soinfo *si, const char *name);
Elf32_Sym *lookup(const char *name, soinfo **found); Elf32_Sym *lookup(const char *name, soinfo **found);
soinfo *find_containing_library(void *addr);
Elf32_Sym *find_containing_symbol(void *addr, soinfo *si);
const char *linker_get_error(void); const char *linker_get_error(void);
#ifdef ANDROID_ARM_LINKER #ifdef ANDROID_ARM_LINKER