diff options
-rw-r--r-- | trunk/src/rtld/ChangeLog | 11 | ||||
-rw-r--r-- | trunk/src/rtld/dl-load.c | 60 | ||||
-rw-r--r-- | trunk/src/rtld/dl-lookupX.h | 4 | ||||
-rw-r--r-- | trunk/src/rtld/dl-version.c | 2 | ||||
-rw-r--r-- | trunk/src/rtld/rtld.c | 11 | ||||
-rw-r--r-- | trunk/src/rtld/rtld.h | 8 |
6 files changed, 80 insertions, 16 deletions
diff --git a/trunk/src/rtld/ChangeLog b/trunk/src/rtld/ChangeLog index ae7a5a7..ae208d7 100644 --- a/trunk/src/rtld/ChangeLog +++ b/trunk/src/rtld/ChangeLog @@ -6,9 +6,18 @@ new extern_protected_data function. rename reloc_typeclass to elf_machine_type_class add machine_no_rela, machine_no_rel funcs + Update debug msg + Fix missing dso_list->map = NULL * rtld/dl-tls.c: (rtld_determine_tlsoffsets) add NIOS2 definition - * rtld/dl-lookup.c + * rtld/dl-lookup.c: Add EXTERN_PROTECTED_DATA support * rtld/dl-lookupX.h: Add EXTERN_PROTECTED_DATA support + update debug msgs + * rtld/dl-load.c: (create_map_object_from_dso_ent) Add ld.so like debug + When an executable sets a load address use it + Update the load address calculation, prevents visual overlaps + * rtld/dl-version.c: update debug msgs + * rtld/rtld.h: define _dl_debug_printf to act like ld.so debug + define RTLD_DEBUG_PID to set the debug prefix * glibc changes directly affecting the implementation: diff --git a/trunk/src/rtld/dl-load.c b/trunk/src/rtld/dl-load.c index f73f17f..5dc913e 100644 --- a/trunk/src/rtld/dl-load.c +++ b/trunk/src/rtld/dl-load.c @@ -80,6 +80,7 @@ add_name_to_object (struct link_map *l, const char *name) const char *rtld_progname; static Elf64_Addr load_addr = 0xdead0000; +static Elf64_Addr dynamic_addr = 0xfeed0000; /* mimic behavior of _dl_map_object_from_fd(...) Note: this is not a copy of the function! */ @@ -104,8 +105,9 @@ create_map_object_from_dso_ent (struct dso_list *cur_dso_ent) /* Print debug message. */ - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) - printf("\tfile=%s; generating link map\n", name); + if ((l_type == lt_library && !is_ldso_soname(soname)) && + __glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf("file=%s [0]; generating link map\n", soname); l = _dl_new_object (realname, name, l_type); @@ -207,14 +209,58 @@ create_map_object_from_dso_ent (struct dso_list *cur_dso_ent) } } - /* Set up the symbol hash table. */ - _dl_setup_hash (l); - - l->l_map_start = load_addr; - load_addr += 0x1000; + if (dso->base) { + l->l_map_start = dso->base; + + /* We need to ensure that we don't have two DSOs loading at the same place! */ + struct dso_list * dso_list_ptr; + for (dso_list_ptr = cur_dso_ent->prev; dso_list_ptr; dso_list_ptr = dso_list_ptr->prev) + { + /* This looks for fairly obvious overlaps... */ + if ((dso_list_ptr->dso->base <= dso->base && dso->base <= dso_list_ptr->dso->end) || \ + (dso->base <= dso_list_ptr->dso->base && dso_list_ptr->dso->base <= dso->end)) + { + l->l_map_start = (Elf64_Addr)NULL; + break; + } + } + } + + if (l->l_map_start == (Elf64_Addr)NULL) + { + l->l_map_start = load_addr; + load_addr += ( ((dso->end - dso->base) + (0x1000 - 1)) & (~(0x1000-1)) ); + } l->sym_base = dso->info[DT_SYMTAB] - dso->base; + if ((l_type == lt_library && !is_ldso_soname(soname)) + && (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))) { + _dl_debug_printf ("\ + dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n", + (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), + (unsigned long int) dynamic_addr, + (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), + (unsigned long int) l->l_map_start, + (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), + (dso->end - dso->base)); + _dl_debug_printf ("\ + entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n", + (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), + (unsigned long int) l->l_map_start + dso->ehdr.e_entry, + (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), + (unsigned long int) l->l_map_start + dso->ehdr.e_ehsize, + (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), + dso->ehdr.e_phnum); + _dl_debug_printf ("\n"); + + /* Only used for debugging output */ + dynamic_addr += ( ((dso->end - dso->base) + (0x1000 - 1)) & (~(0x1000-1)) ); + } + + /* Set up the symbol hash table. */ + _dl_setup_hash (l); + for (i = 0; i < dso->ehdr.e_phnum; ++i) if (dso->phdr[i].p_type == PT_TLS) { diff --git a/trunk/src/rtld/dl-lookupX.h b/trunk/src/rtld/dl-lookupX.h index 3f8472a..dc6d4bf 100644 --- a/trunk/src/rtld/dl-lookupX.h +++ b/trunk/src/rtld/dl-lookupX.h @@ -784,9 +784,9 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, 0UL, protected ? "protected" : "normal", undef_name); if (version) - _dl_debug_printf (" [%s]\n", version->name); + printf (" [%s]\n", version->name); else - _dl_debug_printf ("\n"); + printf ("\n"); } #if 1 if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) diff --git a/trunk/src/rtld/dl-version.c b/trunk/src/rtld/dl-version.c index 759495c..042a70f 100644 --- a/trunk/src/rtld/dl-version.c +++ b/trunk/src/rtld/dl-version.c @@ -77,7 +77,7 @@ match_symbol (const char *name, Elf64_Word hash, const char *string, /* Display information about what we are doing while debugging. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS)) _dl_debug_printf ("\ -checking for version `%s' in file %s required by file %s\n", +checking for version `%s' in file %s [0] required by file %s [0]\n", string, DSO_FILENAME (map->l_name), name); diff --git a/trunk/src/rtld/rtld.c b/trunk/src/rtld/rtld.c index 90ca4df..82ba4b2 100644 --- a/trunk/src/rtld/rtld.c +++ b/trunk/src/rtld/rtld.c @@ -699,6 +699,7 @@ load_dsos (DSO *dso, int host_paths) dso_list = malloc (sizeof (struct dso_list)); dso_list->dso = dso; + dso_list->map = NULL; dso_list->next = NULL; dso_list->prev = NULL; dso_list->needed = NULL; @@ -784,7 +785,7 @@ load_dsos (DSO *dso, int host_paths) if (new_dso_ent == NULL) { if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)) - printf ("\tfile=%s [0]; needed by %s [0]\n", + _dl_debug_printf ("file=%s [0]; needed by %s [0]\n", soname, cur_dso->filename); int machine; @@ -804,6 +805,7 @@ load_dsos (DSO *dso, int host_paths) dso_list_tail = dso_list_tail->next; dso_list_tail->next = NULL; dso_list_tail->dso = NULL; + dso_list_tail->map = NULL; dso_list_tail->needed = NULL; dso_list_tail->name = soname; dso_list_tail->loader = NULL; @@ -834,6 +836,7 @@ load_dsos (DSO *dso, int host_paths) dso_list_tail = dso_list_tail->next; dso_list_tail->next = NULL; dso_list_tail->dso = new_dso; + dso_list_tail->map = NULL; dso_list_tail->needed = NULL; dso_list_tail->loader = cur_dso_ent; dso_list_tail->canon_filename = new_canon_name; @@ -1099,7 +1102,7 @@ build_local_scope (struct dso_list *ent, int max) static struct argp argp = { options, parse_opt, "[FILES]", argp_doc }; -struct link_map *requested_map; +struct link_map *requested_map = NULL; static void process_one_dso (DSO *dso, int host_paths); @@ -1353,7 +1356,7 @@ process_one_dso (DSO *dso, int host_paths) filename ? filename : rtld_progname ?: "<main program>", (uint64_t) l->l_map_start, - (uint64_t) (l->l_map_start - cur_dso_ent->dso->base)); + (uint64_t) (l->l_map_start == cur_dso_ent->dso->base ? 0 : l->l_map_start)); else printf ("\t%s => %s (0x%08"PRIx32", 0x%08"PRIx32")", cur_dso_ent->name ? cur_dso_ent->name @@ -1361,7 +1364,7 @@ process_one_dso (DSO *dso, int host_paths) filename ? filename : rtld_progname ?: "<main program>", (uint32_t) l->l_map_start, - (uint32_t) (l->l_map_start - cur_dso_ent->dso->base)); + (uint32_t) (l->l_map_start == cur_dso_ent->dso->base ? 0 : l->l_map_start)); if (l->l_tls_modid) if (size_pointer == 16) diff --git a/trunk/src/rtld/rtld.h b/trunk/src/rtld/rtld.h index eced76f..c7b5d91 100644 --- a/trunk/src/rtld/rtld.h +++ b/trunk/src/rtld/rtld.h @@ -176,7 +176,13 @@ extern unsigned int _dl_debug_mask; extern unsigned int _dl_dynamic_weak; extern const char *rtld_progname; -#define _dl_debug_printf printf + +/* This is an optional value before the ':' when debuging is enabled. */ +/* Typically glibc sets this to a number of spaces and the pid of the process*/ +#ifndef RTLD_DEBUG_PID +# define RTLD_DEBUG_PID " " +#endif +#define _dl_debug_printf(...) printf( RTLD_DEBUG_PID ":\t" __VA_ARGS__) #define __rtld_lock_lock_recursive(NAME) #define __rtld_lock_unlock_recursive(NAME) |