auto import from //branches/cupcake_rel/...@141571

This commit is contained in:
The Android Open Source Project 2009-03-19 23:08:36 -07:00
parent 78bf5fc677
commit 7b31dd6680

View File

@ -37,7 +37,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <sys/stat.h> #include <sys/stat.h>
//#include <pthread.h> #include <pthread.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -110,15 +110,11 @@ unsigned bitmask[4096];
*/ */
extern void __attribute__((noinline)) rtld_db_dlactivity(void); extern void __attribute__((noinline)) rtld_db_dlactivity(void);
extern void sched_yield(void);
static struct r_debug _r_debug = {1, NULL, &rtld_db_dlactivity, static struct r_debug _r_debug = {1, NULL, &rtld_db_dlactivity,
RT_CONSISTENT, 0}; RT_CONSISTENT, 0};
static struct link_map *r_debug_tail = 0; static struct link_map *r_debug_tail = 0;
//static pthread_mutex_t _r_debug_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _r_debug_lock = PTHREAD_MUTEX_INITIALIZER;
static volatile int loader_lock = 0;
static void insert_soinfo_into_debug_map(soinfo * info) static void insert_soinfo_into_debug_map(soinfo * info)
{ {
@ -147,6 +143,17 @@ static void insert_soinfo_into_debug_map(soinfo * info)
r_debug_tail = map; r_debug_tail = map;
} }
static void remove_soinfo_from_debug_map(soinfo * info)
{
struct link_map * map = &(info->linkmap);
if (r_debug_tail == map)
r_debug_tail = map->l_prev;
if (map->l_prev) map->l_prev->l_next = map->l_next;
if (map->l_next) map->l_next->l_prev = map->l_prev;
}
void notify_gdb_of_load(soinfo * info) void notify_gdb_of_load(soinfo * info)
{ {
if (info->flags & FLAG_EXE) { if (info->flags & FLAG_EXE) {
@ -154,14 +161,7 @@ void notify_gdb_of_load(soinfo * info)
return; return;
} }
/* yes, this is a little gross, but it does avoid pthread_mutex_lock(&_r_debug_lock);
** pulling in pthread_*() and at the moment we don't
** dlopen() anything anyway
*/
while(__atomic_swap(1, &loader_lock) != 0) {
sched_yield();
usleep(5000);
}
_r_debug.r_state = RT_ADD; _r_debug.r_state = RT_ADD;
rtld_db_dlactivity(); rtld_db_dlactivity();
@ -171,7 +171,27 @@ void notify_gdb_of_load(soinfo * info)
_r_debug.r_state = RT_CONSISTENT; _r_debug.r_state = RT_CONSISTENT;
rtld_db_dlactivity(); rtld_db_dlactivity();
__atomic_swap(0, &loader_lock); pthread_mutex_unlock(&_r_debug_lock);
}
void notify_gdb_of_unload(soinfo * info)
{
if (info->flags & FLAG_EXE) {
// GDB already knows about the main executable
return;
}
pthread_mutex_lock(&_r_debug_lock);
_r_debug.r_state = RT_DELETE;
rtld_db_dlactivity();
remove_soinfo_from_debug_map(info);
_r_debug.r_state = RT_CONSISTENT;
rtld_db_dlactivity();
pthread_mutex_unlock(&_r_debug_lock);
} }
void notify_gdb_of_libraries() void notify_gdb_of_libraries()
@ -1066,6 +1086,7 @@ unsigned unload_library(soinfo *si)
pid, si->name, si->base); pid, si->name, si->base);
ba_free(si->ba_index); ba_free(si->ba_index);
} }
notify_gdb_of_unload(si);
free_info(si); free_info(si);
si->refcount = 0; si->refcount = 0;
} }
@ -1213,6 +1234,8 @@ static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
reloc, s->st_size, sym_addr, sym_name); reloc, s->st_size, sym_addr, sym_name);
memcpy((void*)reloc, (void*)sym_addr, s->st_size); memcpy((void*)reloc, (void*)sym_addr, s->st_size);
break; break;
case R_ARM_NONE:
break;
#endif /* ANDROID_ARM_LINKER */ #endif /* ANDROID_ARM_LINKER */
default: default: