Only in glibc-2.3: autom4te.cache Only in glibc-2.3/csu: core Only in glibc-2.3/elf: core diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/elf/dl-close.c glibc-2.3/elf/dl-close.c --- glibc-pristine/elf/dl-close.c 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/elf/dl-close.c 2005-10-19 21:48:52.000000000 +0100 @@ -506,6 +506,9 @@ /* Remove the searchlists. */ free (imap->l_initfini); + /* Remove the dtneeded list */ + free (imap->l_dtneeded.r_list); + /* Remove the scope array if we allocated it. */ if (imap->l_scope != imap->l_scope_mem) free (imap->l_scope); Only in glibc-2.3/elf: dl-close.c~ diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/elf/dl-deps.c glibc-2.3/elf/dl-deps.c --- glibc-pristine/elf/dl-deps.c 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/elf/dl-deps.c 2005-11-18 12:50:38.000000000 +0000 @@ -39,6 +39,9 @@ #define FILTERTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ + DT_EXTRATAGIDX (DT_FILTER)) +#ifndef VERSYMIDX +# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) +#endif /* When loading auxiliary objects we must ignore errors. It's ok if an object is missing. */ @@ -139,6 +142,65 @@ __result; }) +static void +setup_direct (struct link_map *map, struct r_scope_elem *scope) +{ + if (map->l_info[VERSYMIDX(DT_DIRECT)] && map->l_info[DT_NEEDED]) + { + const ElfW(Dyn) *d; + unsigned int i; + const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); + + if (GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) + _dl_debug_printf ("** direct linkage section in '%s' **\n", + map->l_name ? map->l_name : ""); + + map->l_dtneeded.r_nlist = 1; + for (d = map->l_ld; d->d_tag != DT_NULL; ++d) + { + if (__builtin_expect (d->d_tag, DT_NEEDED) == DT_NEEDED) + map->l_dtneeded.r_nlist++; + } + + map->l_dtneeded.r_list = (struct link_map **) + malloc (map->l_dtneeded.r_nlist * sizeof (struct link_map *)); + + map->l_dtneeded.r_list[0] = map; + for (i = 1, d = map->l_ld; d->d_tag != DT_NULL; ++d) + { + const char *name; + unsigned int j; + + if (d->d_tag != DT_NEEDED) + continue; + + name = expand_dst (map, strtab + d->d_un.d_val, 0); + if (GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) + _dl_debug_printf (" direct index %u object '%s'\n", i, name); + for (j = 0; j < scope->r_nlist; j++) + { + if (scope->r_list[j] && + _dl_name_match_p (name, scope->r_list[j])) + { + map->l_dtneeded.r_list[i] = scope->r_list[j]; + break; + } + } + if (!map->l_dtneeded.r_list[i]) + _dl_debug_printf (" impossible error - can't find '%s'\n", name); + i++; + } + } + else + { + if (GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) + _dl_debug_printf ("no direct linkage section in '%s'\n", + map->l_name ? map->l_name : ""); + map->l_dtneeded.r_nlist = 0; + map->l_dtneeded.r_list = NULL; + } +} + void internal_function _dl_map_object_deps (struct link_map *map, @@ -555,6 +617,16 @@ } } + if (__builtin_expect (GLRO(dl_direct), 0)) + { + /* Setup direct linkage dtneeded table */ + for (i = 0; i < nlist; ++i) + setup_direct (map->l_searchlist.r_list[i], &map->l_searchlist); + } + else + if (GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) + _dl_debug_printf (" no dl_direct set %u\n", GLRO(dl_direct)); + /* Maybe we can remove some relocation dependencies now. */ assert (map->l_searchlist.r_list[0] == map); for (i = 0; i < map->l_reldepsact; ++i) Only in glibc-2.3/elf: dl-deps.c~ Only in glibc-2.3/elf: dl-load.c~ diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/elf/dl-lookup.c glibc-2.3/elf/dl-lookup.c --- glibc-pristine/elf/dl-lookup.c 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/elf/dl-lookup.c 2005-11-23 11:23:47.000000000 +0000 @@ -32,6 +32,10 @@ #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) +#ifndef VERSYMIDX +# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) +#endif + /* We need this string more than once. */ static const char undefined_msg[] = "undefined symbol: "; @@ -209,6 +213,7 @@ const unsigned long int hash = _dl_elf_hash (undef_name); struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope = symbol_scope; + size_t i = 0; bump_num_relocations (); @@ -216,7 +221,81 @@ up a versioned symbol. */ assert (version == NULL || flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY); - size_t i = 0; + if (__builtin_expect (undef_map != NULL, 1) && + __builtin_expect (undef_map->l_dtneeded.r_nlist != NULL, 0) && + __builtin_expect (*ref != NULL, 1)) + { + unsigned int idx, noffset; + const ElfW(Sym) *symtab; + ElfW(Addr) direct; + + /* We need a dynsym index ... */ + symtab = (const void *) D_PTR (undef_map, l_info[DT_SYMTAB]); + direct = D_PTR (undef_map, l_info[VERSYMIDX(DT_DIRECT)]); + + idx = *ref - symtab; + if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) + _dl_debug_printf ("dynamic symbol index %u from '%s' for %s base direct 0x%x start 0x%x\n", idx, + undef_map->l_name ? undef_map->l_name : "", + undef_name ? undef_name : "", + (int) direct, (int) undef_map->l_map_start); + direct += idx * 2; + if (direct >= undef_map->l_map_end || direct <= undef_map->l_map_start) + _dl_debug_printf ("broken: off end of map 0x%x\n", (int) direct); + else + { + noffset = *(uint16_t *)direct; + if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) + _dl_debug_printf ("dynamic symbol offset %u from 0x%x\n", noffset, (int) direct); + if (noffset & DT_DIRECT_VAGUE) + { + if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) + _dl_debug_printf ("vague symbol\n"); + goto normal_lookup; + } + + noffset &= DT_DIRECT_MASK; + + if (__builtin_expect (noffset < undef_map->l_dtneeded.r_nlist, 1)) + { + int res; + struct r_scope_elem direct_elem; + + /* FIXME - requires LD_PRELOAD support ... */ + direct_elem.r_list = undef_map->l_dtneeded.r_list + noffset; + direct_elem.r_nlist = 1; + + if (direct_elem.r_list[0] == skip_map) + goto normal_lookup; /* FIXME - correct ? */ + + res = do_lookup_x (undef_name, hash, *ref, ¤t_value, &direct_elem, + 0, version, flags, skip_map, type_class); + if (res > 0) + { + if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) + _dl_debug_printf ("direct lookup ...\n"); + goto match; + } + else + _dl_debug_printf ("Error in lookup %u - missing (?) - fallback " + "to deps & then global ? ...\n", res); + } + else if (noffset == DT_DIRECT_UNKNOWN) + { + if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) + _dl_debug_printf ("unknown/undefined symbol '%s'\n", + undef_name ? undef_name : ""); + } + else + { + _dl_debug_printf ("Error: foo symbol '%s' 0 < %u < %u\n", + undef_name ? undef_name : "", + noffset, undef_map->l_dtneeded.r_nlist); + } + } + } + normal_lookup: + if (__builtin_expect (skip_map != NULL, 0)) { /* Search the relevant loaded objects for a definition. */ @@ -258,7 +337,7 @@ return 0; } } - + match: if (__builtin_expect (current_value.s == NULL, 0)) { if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) Only in glibc-2.3/elf: dl-lookup.c~ Only in glibc-pristine/elf: dl-lookup.c.orig diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/elf/dl-support.c glibc-2.3/elf/dl-support.c --- glibc-pristine/elf/dl-support.c 2005-11-17 17:40:21.000000000 +0000 +++ glibc-2.3/elf/dl-support.c 2005-11-17 17:28:30.000000000 +0000 @@ -41,6 +41,7 @@ int _dl_debug_mask; int _dl_lazy; +int _dl_direct; int _dl_mlock_pages; int _dl_madvise; ElfW(Addr) _dl_use_load_bias = -2; @@ -242,6 +243,8 @@ _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; + _dl_direct = *(getenv ("LD_BIND_DIRECT") ?: "") == '\0'; + _dl_madvise = *(getenv ("LD_NOMADVISE") ?: "") == '\0'; _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; Only in glibc-2.3/elf: dl-support.c~ diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/elf/dynamic-link.h glibc-2.3/elf/dynamic-link.h --- glibc-pristine/elf/dynamic-link.h 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/elf/dynamic-link.h 2005-10-19 21:01:06.000000000 +0100 @@ -94,6 +94,7 @@ ADJUST_DYN_INFO (DT_PLTGOT); ADJUST_DYN_INFO (DT_STRTAB); ADJUST_DYN_INFO (DT_SYMTAB); + ADJUST_DYN_INFO (VERSYMIDX(DT_DIRECT)); # if ! ELF_MACHINE_NO_RELA ADJUST_DYN_INFO (DT_RELA); # endif Only in glibc-2.3/elf: dynamic-link.h~ diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/elf/elf.h glibc-2.3/elf/elf.h --- glibc-pristine/elf/elf.h 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/elf/elf.h 2005-11-23 11:18:29.000000000 +0000 @@ -714,6 +714,7 @@ /* The versioning entry types. The next are defined as part of the GNU extension. */ #define DT_VERSYM 0x6ffffff0 +#define DT_DIRECT 0x6ffffff1 /* FIXME - how are these allocated ? */ #define DT_RELACOUNT 0x6ffffff9 #define DT_RELCOUNT 0x6ffffffa @@ -743,6 +744,11 @@ #define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ #define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ +/* Constants for the DT_DIRECT entries. */ +#define DT_DIRECT_VAGUE (1<<15) +#define DT_DIRECT_MASK 0x3ff +#define DT_DIRECT_UNKNOWN DT_DIRECT_MASK + /* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry in the dynamic section. */ #define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ Only in glibc-2.3/elf: elf.h~ diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/elf/rtld.c glibc-2.3/elf/rtld.c --- glibc-pristine/elf/rtld.c 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/elf/rtld.c 2005-11-18 12:51:38.000000000 +0000 @@ -123,6 +123,7 @@ ._dl_correct_cache_id = _DL_CACHE_DEFAULT_ID, ._dl_hwcap_mask = HWCAP_IMPORTANT, ._dl_lazy = 1, + ._dl_direct = 0, ._dl_fpu_control = _FPU_DEFAULT, ._dl_madvise = 1, @@ -2056,11 +2057,13 @@ DL_DEBUG_SYMBOLS | DL_DEBUG_IMPCALLS }, { LEN_AND_STR ("bindings"), "display information about symbol binding", DL_DEBUG_BINDINGS | DL_DEBUG_IMPCALLS }, + { LEN_AND_STR ("direct"), "display information about direct binding", + DL_DEBUG_DIRECT | DL_DEBUG_IMPCALLS }, { LEN_AND_STR ("versions"), "display version dependencies", DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS }, { LEN_AND_STR ("all"), "all previous options combined", DL_DEBUG_LIBS | DL_DEBUG_RELOC | DL_DEBUG_FILES | DL_DEBUG_SYMBOLS - | DL_DEBUG_BINDINGS | DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS }, + | DL_DEBUG_BINDINGS | DL_DEBUG_DIRECT | DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS }, { LEN_AND_STR ("statistics"), "display relocation statistics", DL_DEBUG_STATISTICS }, { LEN_AND_STR ("unused"), "determined unused DSOs", @@ -2230,6 +2233,8 @@ if (!INTUSE(__libc_enable_secure) && memcmp (envline, "ORIGIN_PATH", 11) == 0) GLRO(dl_origin_path) = &envline[12]; + if (memcmp (envline, "BIND_DIRECT", 11) == 0) + GLRO(dl_direct) = envline[12] != '\0'; break; case 12: Only in glibc-2.3/elf: rtld.c~ diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/include/link.h glibc-2.3/include/link.h --- glibc-pristine/include/link.h 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/include/link.h 2005-10-19 21:13:12.000000000 +0100 @@ -299,6 +299,10 @@ done. */ ElfW(Addr) l_relro_addr; size_t l_relro_size; + + /* Array of DT_NEEDED dependencies in order for use in + direct linkage - l_dtneeded[0] entry is self */ + struct r_scope_elem l_dtneeded; }; struct dl_phdr_info diff -u -r -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' glibc-pristine/sysdeps/generic/ldsodefs.h glibc-2.3/sysdeps/generic/ldsodefs.h --- glibc-pristine/sysdeps/generic/ldsodefs.h 2005-11-17 17:48:13.000000000 +0000 +++ glibc-2.3/sysdeps/generic/ldsodefs.h 2005-11-17 17:27:28.000000000 +0000 @@ -388,6 +388,7 @@ /* These two are used only internally. */ #define DL_DEBUG_HELP (1 << 9) #define DL_DEBUG_PRELINK (1 << 10) +#define DL_DEBUG_DIRECT (1 << 11) /* Cached value of `getpagesize ()'. */ EXTERN size_t _dl_pagesize; @@ -413,6 +414,9 @@ /* Do we do lazy relocations? */ EXTERN int _dl_lazy; + /* Do we do direct relocations? */ + EXTERN int _dl_direct; + /* Should we advise kernel about memory usage? */ EXTERN int _dl_madvise;