From 3a9c5d66dc8d41272f51482b713717af7049697e Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 10 Feb 2014 13:31:13 -0800 Subject: [PATCH] Fix . Also move some of the stuff that should be in out of the private "linker.h", to make it clearer that these are public API known to gdb that we can't change. Bug: 12554197 Change-Id: I830e1260d3d8b833ed99bc1518f1c6b6102be8af --- libc/include/link.h | 32 +++++++++++++++++++++++++++++--- linker/linker.cpp | 34 +++++++++++++++++----------------- linker/linker.h | 27 +-------------------------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/libc/include/link.h b/libc/include/link.h index 341fbf197..cb8e139ac 100644 --- a/libc/include/link.h +++ b/libc/include/link.h @@ -33,7 +33,11 @@ __BEGIN_DECLS -#define ElfW(type) Elf_##type +#if __LP64__ +#define ElfW(type) Elf64_ ## type +#else +#define ElfW(type) Elf32_ ## type +#endif struct dl_phdr_info { ElfW(Addr) dlpi_addr; @@ -42,13 +46,35 @@ struct dl_phdr_info { ElfW(Half) dlpi_phnum; }; -int dl_iterate_phdr(int (*cb)(struct dl_phdr_info*, size_t, void*), void*); +int dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*); #ifdef __arm__ typedef long unsigned int* _Unwind_Ptr; -_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount); +_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*); #endif +/* Used by the dynamic linker to communicate with the debugger. */ +struct link_map { + ElfW(Addr) l_addr; + char* l_name; + ElfW(Dyn)* l_ld; + struct link_map* l_next; + struct link_map* l_prev; +}; + +/* Used by the dynamic linker to communicate with the debugger. */ +struct r_debug { + int32_t r_version; + struct link_map* r_map; + ElfW(Addr) r_brk; + enum { + RT_CONSISTENT, + RT_ADD, + RT_DELETE + } r_state; + ElfW(Addr) r_ldbase; +}; + __END_DECLS #endif /* _LINK_H_ */ diff --git a/linker/linker.cpp b/linker/linker.cpp index 9bc9afe7f..2058050a6 100755 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -187,17 +187,17 @@ size_t linker_get_error_buffer_size() { */ extern "C" void __attribute__((noinline)) __attribute__((visibility("default"))) rtld_db_dlactivity(); -static r_debug _r_debug = {1, NULL, &rtld_db_dlactivity, RT_CONSISTENT, 0}; -static link_map_t* r_debug_tail = 0; +static r_debug _r_debug = {1, NULL, reinterpret_cast(&rtld_db_dlactivity), r_debug::RT_CONSISTENT, 0}; +static link_map* r_debug_tail = 0; static pthread_mutex_t gDebugMutex = PTHREAD_MUTEX_INITIALIZER; -static void insert_soinfo_into_debug_map(soinfo * info) { +static void insert_soinfo_into_debug_map(soinfo* info) { // Copy the necessary fields into the debug structure. - link_map_t* map = &(info->link_map); + link_map* map = &(info->link_map_head); map->l_addr = info->load_bias; map->l_name = (char*) info->name; - map->l_ld = (uintptr_t)info->dynamic; + map->l_ld = info->dynamic; /* Stick the new library at the end of the list. * gdb tends to care more about libc than it does @@ -217,7 +217,7 @@ static void insert_soinfo_into_debug_map(soinfo * info) { } static void remove_soinfo_from_debug_map(soinfo* info) { - link_map_t* map = &(info->link_map); + link_map* map = &(info->link_map_head); if (r_debug_tail == map) { r_debug_tail = map->l_prev; @@ -239,12 +239,12 @@ static void notify_gdb_of_load(soinfo* info) { ScopedPthreadMutexLocker locker(&gDebugMutex); - _r_debug.r_state = RT_ADD; + _r_debug.r_state = r_debug::RT_ADD; rtld_db_dlactivity(); insert_soinfo_into_debug_map(info); - _r_debug.r_state = RT_CONSISTENT; + _r_debug.r_state = r_debug::RT_CONSISTENT; rtld_db_dlactivity(); } @@ -256,20 +256,20 @@ static void notify_gdb_of_unload(soinfo* info) { ScopedPthreadMutexLocker locker(&gDebugMutex); - _r_debug.r_state = RT_DELETE; + _r_debug.r_state = r_debug::RT_DELETE; rtld_db_dlactivity(); remove_soinfo_from_debug_map(info); - _r_debug.r_state = RT_CONSISTENT; + _r_debug.r_state = r_debug::RT_CONSISTENT; rtld_db_dlactivity(); } void notify_gdb_of_libraries() { - _r_debug.r_state = RT_ADD; - rtld_db_dlactivity(); - _r_debug.r_state = RT_CONSISTENT; - rtld_db_dlactivity(); + _r_debug.r_state = r_debug::RT_ADD; + rtld_db_dlactivity(); + _r_debug.r_state = r_debug::RT_CONSISTENT; + rtld_db_dlactivity(); } static bool ensure_free_list_non_empty() { @@ -439,8 +439,8 @@ dl_iterate_phdr(int (*cb)(dl_phdr_info *info, size_t size, void *data), int rv = 0; for (soinfo* si = solist; si != NULL; si = si->next) { dl_phdr_info dl_info; - dl_info.dlpi_addr = si->link_map.l_addr; - dl_info.dlpi_name = si->link_map.l_name; + dl_info.dlpi_addr = si->link_map_head.l_addr; + dl_info.dlpi_name = si->link_map_head.l_name; dl_info.dlpi_phdr = si->phdr; dl_info.dlpi_phnum = si->phnum; rv = cb(&dl_info, sizeof(dl_phdr_info), data); @@ -2038,7 +2038,7 @@ static Elf_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf_Add /* bootstrap the link map, the main exe always needs to be first */ si->flags |= FLAG_EXE; - link_map_t* map = &(si->link_map); + link_map* map = &(si->link_map_head); map->l_addr = 0; map->l_name = args.argv[0]; diff --git a/linker/linker.h b/linker/linker.h index 972050f3f..654ee5f2b 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -61,31 +61,6 @@ // itself at the start of a page. #define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1)) -// Magic shared structures that GDB knows about. - -struct link_map_t { - uintptr_t l_addr; - char* l_name; - uintptr_t l_ld; - link_map_t* l_next; - link_map_t* l_prev; -}; - -// Values for r_debug->state -enum { - RT_CONSISTENT, - RT_ADD, - RT_DELETE -}; - -struct r_debug { - int32_t r_version; - link_map_t* r_map; - void (*r_brk)(void); - int32_t r_state; - uintptr_t r_ldbase; -}; - #define FLAG_LINKED 0x00000001 #define FLAG_EXE 0x00000004 // The main executable #define FLAG_LINKER 0x00000010 // The linker itself @@ -172,7 +147,7 @@ struct soinfo { #endif size_t ref_count; - link_map_t link_map; + link_map link_map_head; bool constructors_called;