diff options
32 files changed, 309 insertions, 61 deletions
diff --git a/libc/Android.mk b/libc/Android.mk index bafc118..9013e9a 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -329,6 +329,7 @@ libc_common_src_files += \ arch-x86/bionic/setjmp.S \ arch-x86/bionic/_setjmp.S \ arch-x86/bionic/vfork.S \ + arch-x86/bionic/syscall.S \ arch-x86/string/bzero.S \ arch-x86/string/memset.S \ arch-x86/string/memcmp.S \ diff --git a/libc/arch-x86/bionic/syscall.S b/libc/arch-x86/bionic/syscall.S new file mode 100644 index 0000000..71abe6b --- /dev/null +++ b/libc/arch-x86/bionic/syscall.S @@ -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 diff --git a/libc/bionic/malloc_leak.c b/libc/bionic/malloc_leak.c index 305f954..ad1d2b4 100644 --- a/libc/bionic/malloc_leak.c +++ b/libc/bionic/malloc_leak.c @@ -665,8 +665,9 @@ void* chk_realloc(void* mem, size_t bytes) } if (new_buffer) { - size_t size = (bytes < old_bytes)?(bytes):(old_bytes); - memcpy(new_buffer, mem, size); + if (bytes > old_bytes) + bytes = old_bytes; + memcpy(new_buffer, mem, bytes); chk_free(mem); } diff --git a/libc/bionic/pututline.c b/libc/bionic/pututline.c index 2449068..c8427f7 100644 --- a/libc/bionic/pututline.c +++ b/libc/bionic/pututline.c @@ -34,7 +34,7 @@ void pututline(struct utmp* utmp) { FILE* f; struct utmp u; - int i; + long i; if (!(f = fopen(_PATH_UTMP, "w+"))) return; diff --git a/libc/bionic/ssp.c b/libc/bionic/ssp.c index 20794f4..f83b2a4 100644 --- a/libc/bionic/ssp.c +++ b/libc/bionic/ssp.c @@ -76,9 +76,9 @@ void __stack_chk_fail(void) sigprocmask(SIG_BLOCK, &sigmask, NULL); /* 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) { - strlcpy(path, "unknown", sizeof(path)); + strlcpy(path, "<unknown>", sizeof(path)); } else { path[count] = '\0'; } diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h index 9582796..f84d1d1 100644 --- a/libc/include/dlfcn.h +++ b/libc/include/dlfcn.h @@ -32,10 +32,22 @@ __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 int dlclose(void* handle); extern const char* dlerror(void); extern void* dlsym(void* handle, const char* symbol); +extern int dladdr(void* addr, Dl_info *info); enum { RTLD_NOW = 0, diff --git a/libc/kernel/common/linux/a1026.h b/libc/kernel/common/linux/a1026.h new file mode 100644 index 0000000..2bf6190 --- /dev/null +++ b/libc/kernel/common/linux/a1026.h @@ -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 __LINUX_A1026_H +#define __LINUX_A1026_H + +#include <linux/ioctl.h> + +#define A1026_MAX_FW_SIZE (32*1024) +struct a1026img { + unsigned char *buf; + unsigned img_size; +}; + +enum A1026_PathID { + A1026_PATH_SUSPEND, + A1026_PATH_INCALL_RECEIVER, + A1026_PATH_INCALL_HEADSET, + A1026_PATH_INCALL_SPEAKER, + A1026_PATH_INCALL_BT, + A1026_PATH_VR_NO_NS_RECEIVER, + A1026_PATH_VR_NO_NS_HEADSET, + A1026_PATH_VR_NO_NS_SPEAKER, + A1026_PATH_VR_NO_NS_BT, + A1026_PATH_VR_NS_RECEIVER, + A1026_PATH_VR_NS_HEADSET, + A1026_PATH_VR_NS_SPEAKER, + A1026_PATH_VR_NS_BT, + A1026_PATH_RECORD_RECEIVER, + A1026_PATH_RECORD_HEADSET, + A1026_PATH_RECORD_SPEAKER, + A1026_PATH_RECORD_BT, + A1026_PATH_CAMCORDER, + A1026_PATH_INCALL_TTY +}; + +enum A1026_NS_states { + A1026_NS_STATE_AUTO, + A1026_NS_STATE_OFF, + A1026_NS_STATE_CT, + A1026_NS_STATE_FT, + A1026_NS_NUM_STATES +}; + +#define A1026_IOCTL_MAGIC 'u' + +#define A1026_BOOTUP_INIT _IOW(A1026_IOCTL_MAGIC, 0x01, struct a1026img *) +#define A1026_SET_CONFIG _IOW(A1026_IOCTL_MAGIC, 0x02, enum A1026_PathID) +#define A1026_SET_NS_STATE _IOW(A1026_IOCTL_MAGIC, 0x03, enum A1026_NS_states) + +#define A1026_SET_MIC_ONOFF _IOW(A1026_IOCTL_MAGIC, 0x50, unsigned) +#define A1026_SET_MICSEL_ONOFF _IOW(A1026_IOCTL_MAGIC, 0x51, unsigned) +#define A1026_READ_DATA _IOR(A1026_IOCTL_MAGIC, 0x52, unsigned) +#define A1026_WRITE_MSG _IOW(A1026_IOCTL_MAGIC, 0x53, unsigned) +#define A1026_SYNC_CMD _IO(A1026_IOCTL_MAGIC, 0x54) +#define A1026_SET_CMD_FILE _IOW(A1026_IOCTL_MAGIC, 0x55, unsigned) + +#endif + diff --git a/libc/kernel/common/linux/msm_kgsl.h b/libc/kernel/common/linux/msm_kgsl.h index d717e57..740ba60 100644 --- a/libc/kernel/common/linux/msm_kgsl.h +++ b/libc/kernel/common/linux/msm_kgsl.h @@ -139,6 +139,8 @@ struct kgsl_drawctxt_destroy { struct kgsl_sharedmem_from_pmem { int pmem_fd; unsigned int gpuaddr; + unsigned int len; + unsigned int offset; }; #define IOCTL_KGSL_SHAREDMEM_FROM_PMEM _IOWR(KGSL_IOC_TYPE, 0x20, struct kgsl_sharedmem_from_pmem) @@ -188,5 +190,12 @@ struct kgsl_sharedmem_from_vmalloc { #define IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE _IOW(KGSL_IOC_TYPE, 0x24, struct kgsl_sharedmem_free) +struct kgsl_drawctxt_set_bin_base_offset { + unsigned int drawctxt_id; + unsigned int offset; +}; + +#define IOCTL_KGSL_DRAWCTXT_SET_BIN_BASE_OFFSET _IOW(KGSL_IOC_TYPE, 0x25, struct kgsl_drawctxt_set_bin_base_offset) + #endif diff --git a/libc/kernel/common/linux/tpa2018d1.h b/libc/kernel/common/linux/tpa2018d1.h new file mode 100644 index 0000000..4ae31fc --- /dev/null +++ b/libc/kernel/common/linux/tpa2018d1.h @@ -0,0 +1,33 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 _LINUX_TPA2018D1_H +#define _LINUX_TPA2018D1_H + +#include <linux/ioctl.h> + +enum tpa2018d1_mode { + TPA2018_MODE_OFF, + TPA2018_MODE_PLAYBACK, + TPA2018_MODE_RINGTONE, + TPA2018_MODE_VOICE_CALL, + TPA2018_NUM_MODES, +}; + +#define TPA2018_IOCTL_MAGIC 'a' +#define TPA2018_SET_CONFIG _IOW(TPA2018_IOCTL_MAGIC, 1, unsigned) +#define TPA2018_READ_CONFIG _IOR(TPA2018_IOCTL_MAGIC, 2, unsigned) +#define TPA2018_SET_PARAM _IOW(TPA2018_IOCTL_MAGIC, 3, unsigned) +#define TPA2018_SET_MODE _IOW(TPA2018_IOCTL_MAGIC, 4, unsigned) + +#endif + + diff --git a/libc/string/strcasecmp.c b/libc/string/strcasecmp.c index 12f3a09..2be0913 100644 --- a/libc/string/strcasecmp.c +++ b/libc/string/strcasecmp.c @@ -98,8 +98,8 @@ strncasecmp(const char *s1, const char *s2, size_t n) if (cm[*us1] != cm[*us2++]) return (cm[*us1] - cm[*--us2]); if (*us1++ == '\0') - break; + break; } while (--n != 0); - } + } return (0); } diff --git a/libc/string/strchr.c b/libc/string/strchr.c index e33694c..31ba4e2 100644 --- a/libc/string/strchr.c +++ b/libc/string/strchr.c @@ -38,6 +38,6 @@ strchr(const char *p, int ch) return((char *)p); if (!*p) return((char *)NULL); - } + } /* NOTREACHED */ } diff --git a/libc/string/strcoll.c b/libc/string/strcoll.c index 365cad5..e3b1ec3 100755 --- a/libc/string/strcoll.c +++ b/libc/string/strcoll.c @@ -36,5 +36,5 @@ int strcoll(const char *s1, const char *s2) { - return strcmp (s1, s2); + return strcmp(s1, s2); } diff --git a/libc/string/strlcat.c b/libc/string/strlcat.c index ad2215b..ceab094 100644 --- a/libc/string/strlcat.c +++ b/libc/string/strlcat.c @@ -46,9 +46,9 @@ strlcat(char *dst, const char *src, size_t siz) if (n != 1) { *d++ = *s; n--; - } + } s++; - } + } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ diff --git a/libc/string/strlcpy.c b/libc/string/strlcpy.c index 38277eb..d32b659 100644 --- a/libc/string/strlcpy.c +++ b/libc/string/strlcpy.c @@ -37,7 +37,7 @@ strlcpy(char *dst, const char *src, size_t siz) if ((*d++ = *s++) == '\0') break; } - } + } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { diff --git a/libc/string/strncat.c b/libc/string/strncat.c index 1cb9405..c4df4f2 100644 --- a/libc/string/strncat.c +++ b/libc/string/strncat.c @@ -52,6 +52,6 @@ strncat(char *dst, const char *src, size_t n) d++; } while (--n != 0); *d = 0; - } + } return (dst); } diff --git a/libc/string/strncmp.c b/libc/string/strncmp.c index 9da41ab..1768808 100644 --- a/libc/string/strncmp.c +++ b/libc/string/strncmp.c @@ -38,14 +38,13 @@ int strncmp(const char *s1, const char *s2, size_t n) { - if (n == 0) return (0); do { if (*s1 != *s2++) return (*(unsigned char *)s1 - *(unsigned char *)--s2); if (*s1++ == 0) - break; + break; } while (--n != 0); return (0); } diff --git a/libc/string/strncpy.c b/libc/string/strncpy.c index b91091b..4426cbe 100644 --- a/libc/string/strncpy.c +++ b/libc/string/strncpy.c @@ -54,8 +54,8 @@ strncpy(char *dst, const char *src, size_t n) /* NUL pad the remaining n-1 bytes */ while (--n != 0) *d++ = 0; - break; - } + break; + } } while (--n != 0); } return (dst); diff --git a/libc/string/strpbrk.c b/libc/string/strpbrk.c index 6ba3796..cd3b71c 100644 --- a/libc/string/strpbrk.c +++ b/libc/string/strpbrk.c @@ -38,7 +38,7 @@ strpbrk(const char *s1, const char *s2) { const char *scanp; int c, sc; - + while ((c = *s1++) != 0) { for (scanp = s2; (sc = *scanp++) != 0;) if (sc == c) diff --git a/libc/string/strrchr.c b/libc/string/strrchr.c index 2800781..4918f82 100644 --- a/libc/string/strrchr.c +++ b/libc/string/strrchr.c @@ -34,12 +34,12 @@ char * strrchr(const char *p, int ch) { char *save; - + for (save = NULL;; ++p) { if (*p == ch) save = (char *)p; if (!*p) return(save); - } + } /* NOTREACHED */ } diff --git a/libc/string/strsep.c b/libc/string/strsep.c index bcca681..c44bc5b 100644 --- a/libc/string/strsep.c +++ b/libc/string/strsep.c @@ -34,7 +34,7 @@ /* * 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. * delim need not remain constant from call to call. diff --git a/libc/string/strstr.c b/libc/string/strstr.c index debe96c..95a865b 100644 --- a/libc/string/strstr.c +++ b/libc/string/strstr.c @@ -51,6 +51,6 @@ strstr(const char *s, const char *find) } while (sc != c); } while (strncmp(s, find, len) != 0); s--; - } + } return ((char *)s); } diff --git a/libc/string/strxfrm.c b/libc/string/strxfrm.c index f1843b5..3c4d707 100755 --- a/libc/string/strxfrm.c +++ b/libc/string/strxfrm.c @@ -29,7 +29,7 @@ /* * 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 * the C locale. * diff --git a/libc/unistd/pread.c b/libc/unistd/pread.c index d2f71f7..b55623e 100644 --- a/libc/unistd/pread.c +++ b/libc/unistd/pread.c @@ -25,10 +25,10 @@ #include <sys/types.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) { - return __pread64(fd, buf, nbytes, offset, 0); + return __pread64(fd, buf, nbytes, offset); } diff --git a/libc/unistd/pwrite.c b/libc/unistd/pwrite.c index 5adf40a..ea080d2 100644 --- a/libc/unistd/pwrite.c +++ b/libc/unistd/pwrite.c @@ -28,10 +28,10 @@ #include <sys/types.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) { - return __pwrite64(fd, buf, nbytes, offset, 0); + return __pwrite64(fd, buf, nbytes, offset); } diff --git a/libc/zoneinfo/zoneinfo.dat b/libc/zoneinfo/zoneinfo.dat Binary files differindex e5bf25a..c9f0b6f 100644 --- a/libc/zoneinfo/zoneinfo.dat +++ b/libc/zoneinfo/zoneinfo.dat diff --git a/libc/zoneinfo/zoneinfo.idx b/libc/zoneinfo/zoneinfo.idx Binary files differindex 78a3650..cb560db 100644 --- a/libc/zoneinfo/zoneinfo.idx +++ b/libc/zoneinfo/zoneinfo.idx diff --git a/libc/zoneinfo/zoneinfo.version b/libc/zoneinfo/zoneinfo.version index 289c5d1..57a3708 100644 --- a/libc/zoneinfo/zoneinfo.version +++ b/libc/zoneinfo/zoneinfo.version @@ -1 +1 @@ -2007h +2009s diff --git a/libdl/libdl.c b/libdl/libdl.c index 7971942..b36af16 100644 --- a/libdl/libdl.c +++ b/libdl/libdl.c @@ -14,12 +14,14 @@ * limitations under the License. */ +#include <dlfcn.h> /* These are stubs for functions that are actually defined * in the dynamic linker (dlfcn.c), and hijacked at runtime. */ 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; } +int dladdr(void *addr, Dl_info *info) { return 0; } int dlclose(void *handle) { return 0; } #ifdef __arm__ diff --git a/libstdc++/src/new.cpp b/libstdc++/src/new.cpp index 8189159..a9c92d4 100644 --- a/libstdc++/src/new.cpp +++ b/libstdc++/src/new.cpp @@ -23,16 +23,12 @@ void* operator new[](std::size_t size) void operator delete(void* ptr) { - if (ptr) { - free(ptr); - } + free(ptr); } void operator delete[](void* ptr) { - if (ptr) { - free(ptr); - } + free(ptr); } 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&) { - if (ptr) { - free(ptr); - } + free(ptr); } void operator delete[](void* ptr, const std::nothrow_t&) { - if (ptr) { - free(ptr); - } + free(ptr); } diff --git a/linker/dlfcn.c b/linker/dlfcn.c index 039926c..dcadce5 100644 --- a/linker/dlfcn.c +++ b/linker/dlfcn.c @@ -117,6 +117,37 @@ err: 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) { pthread_mutex_lock(&dl_lock); @@ -126,22 +157,22 @@ int dlclose(void *handle) } #if defined(ANDROID_ARM_LINKER) -// 0000000 00011111 111112 22222222 233333333334444444444 -// 0123456 78901234 567890 12345678 901234567890123456789 +// 0000000 00011111 111112 22222222 2333333 333344444444445555555 +// 0123456 78901234 567890 12345678 9012345 678901234567890123456 #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) -// 0000000 00011111 111112 22222222 2333333333344444 -// 0123456 78901234 567890 12345678 9012345678901234 +// 0000000 00011111 111112 22222222 2333333 3333444444444455 +// 0123456 78901234 567890 12345678 9012345 6789012345678901 #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) -// 0000000 00011111 111112 22222222 2333333333344444 -// 0123456 78901234 567890 12345678 9012345678901234 +// 0000000 00011111 111112 22222222 2333333 3333444444444455 +// 0123456 78901234 567890 12345678 9012345 6789012345678901 #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) */ #error Unsupported architecture. Only ARM and x86 are presently supported. @@ -175,20 +206,25 @@ static Elf32_Sym libdl_symtab[] = { st_info: STB_GLOBAL << 4, st_shndx: 1, }, -#ifdef ANDROID_ARM_LINKER { 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_info: STB_GLOBAL << 4, st_shndx: 1, }, #elif defined(ANDROID_X86_LINKER) - { st_name: 29, + { st_name: 36, st_value: (Elf32_Addr) &dl_iterate_phdr, st_info: STB_GLOBAL << 4, st_shndx: 1, }, #elif defined(ANDROID_SH_LINKER) - { st_name: 29, + { st_name: 36, st_value: (Elf32_Addr) &dl_iterate_phdr, st_info: STB_GLOBAL << 4, st_shndx: 1, @@ -216,7 +252,7 @@ static Elf32_Sym libdl_symtab[] = { * stubbing them out in libdl. */ 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 = { name: "libdl.so", @@ -226,7 +262,7 @@ soinfo libdl_info = { symtab: libdl_symtab, nbucket: 1, - nchain: 6, + nchain: 7, bucket: libdl_buckets, chain: libdl_chains, }; diff --git a/linker/linker.c b/linker/linker.c index 9779290..f5294d9 100644 --- a/linker/linker.c +++ b/linker/linker.c @@ -538,6 +538,40 @@ Elf32_Sym *lookup(const char *name, soinfo **found) return 0; } +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 static void dump(soinfo *si) { @@ -1295,6 +1329,13 @@ static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count) reloc, sym_addr, sym_name); *((unsigned*)reloc) += sym_addr; break; + case R_ARM_REL32: + COUNT_RELOC(RELOC_RELATIVE); + MARK(rel->r_offset); + TRACE_TYPE(RELO, "%5d RELO REL32 %08x <- %08x - %08x %s\n", pid, + reloc, sym_addr, rel->r_offset, sym_name); + *((unsigned*)reloc) += sym_addr - rel->r_offset; + break; #elif defined(ANDROID_X86_LINKER) case R_386_JUMP_SLOT: COUNT_RELOC(RELOC_ABSOLUTE); diff --git a/linker/linker.h b/linker/linker.h index 2e51338..8cd56b0 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -172,6 +172,13 @@ extern soinfo libdl_info; #define R_ARM_JUMP_SLOT 22 #define R_ARM_RELATIVE 23 +/* According to the AAPCS specification, we only + * need the above relocations. However, in practice, + * the following ones turn up from time to time. + */ +#define R_ARM_ABS32 2 +#define R_ARM_REL32 3 + #elif defined(ANDROID_X86_LINKER) #define R_386_32 1 @@ -214,16 +221,12 @@ extern soinfo libdl_info; #define DT_PREINIT_ARRAYSZ 33 #endif -/* in theory we only need the above relative relocations, - but in practice the following one turns up from time - to time. fushigi na. -*/ -#define R_ARM_ABS32 2 - soinfo *find_library(const char *name); unsigned unload_library(soinfo *si); Elf32_Sym *lookup_in_library(soinfo *si, const char *name); 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); #ifdef ANDROID_ARM_LINKER |