merge from open-source master
Change-Id: I70266ee8c520b216773f267e46c8273d2334c31d
This commit is contained in:
commit
377d4c979d
27 changed files with 189 additions and 59 deletions
|
@ -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 \
|
||||||
|
|
52
libc/arch-x86/bionic/syscall.S
Normal file
52
libc/arch-x86/bionic/syscall.S
Normal 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
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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';
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue