Update.
authorUlrich Drepper <drepper@redhat.com>
Fri, 16 Mar 2001 07:40:05 +0000 (07:40 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 16 Mar 2001 07:40:05 +0000 (07:40 +0000)
2001-03-12  Jakub Jelinek  <jakub@redhat.com>

* csu/Makefile (abi-tag.h): Define OS and version separately, allow
version to be overriden from config.h.
* csu/abi-note.S: Use OS and version separately, include config.h.
* elf/dl-load.c (_dl_osversion): New.
(_dl_map_object_from_fd): Kill some warnings.
(open_verify): Check .note.ABI-tag of the library if present.
* elf/Makefile (CPPFLAGS-dl-load.c): Add -I$(csu-objpfx).
* elf/cache.c (struct cache_entry): Add osversion.
(print_entry): Print osversion.
(print_cache): Pass osversion to it.
(compare): Sort according to osversion.
(save_cache): Set osversion.
(add_to_cache): Add osversion argument.
* sysdeps/generic/ldconfig.h (add_to_cache, process_file,
process_elf_file): Add osversion argument.
* elf/readlib.c (process_file): Likewise.
* sysdeps/generic/readelflib.c (process_elf_file): Likewise.
* sysdeps/unix/sysv/linux/ia64/readelflib.c (process_elf_file,
process_elf32_file, process_elf64_file): Likewise.
* sysdeps/unix/sysv/linux/i386/readelflib.c (process_elf_file,
process_elf32_file, process_elf64_file): Likewise.
* sysdeps/unix/sysv/linux/sparc/readelflib.c (process_elf_file,
process_elf32_file, process_elf64_file): Likewise.
* elf/ldconfig.c (manual_link): Pass it.
(search_dir): Issue diagnostic if two libs with the same soname in
the same directory have different .note.ABI-tag.  Record osversion in
dlib_entry and use it from there.
(struct lib_entry): Remove.
(struct dlib_entry): Add osversion.
* sysdeps/generic/dl-cache.c (_dl_load_cache_lookup): Check
osversion.
* sysdeps/generic/dl-cache.h (struct file_entry_new): Replace __unused
field with osversion.
* sysdeps/generic/ldsodefs.h (_dl_osversion): Declare.
* sysdeps/unix/sysv/linux/init-first.c: Include ldsodefs.h.
* sysdeps/unix/sysv/linux/dl-osinfo.h (DL_SYSDEP_OSCHECK): Save kernel
version in _dl_osversion.
* sysdeps/unix/sysv/linux/configure.in: Define __ABI_TAG_VERSION.
* Makerules (build-shlib-helper, build-module-helper): New.
(build-shlib, build-module-helper): Make sure .note.ABI-tag comes
early.
* config.h.in (__ABI_TAG_VERSION): Add.
* elf/dl-minimal.c (__strtoul_internal): Set endptr on return.
* sysdeps/unix/sysv/linux/i386/dl-librecon.h (EXTRA_LD_ENVVARS):
Handle LD_ASSUME_KERNEL.
* sysdeps/unix/sysv/linux/dl-librecon.h: New.

26 files changed:
ChangeLog
Makerules
config.h.in
csu/Makefile
csu/abi-note.S
elf/Makefile
elf/cache.c
elf/dl-load.c
elf/dl-minimal.c
elf/ldconfig.c
elf/readlib.c
posix/fnmatch_loop.c
sysdeps/generic/dl-cache.c
sysdeps/generic/dl-cache.h
sysdeps/generic/ldconfig.h
sysdeps/generic/ldsodefs.h
sysdeps/generic/readelflib.c
sysdeps/unix/sysv/linux/configure
sysdeps/unix/sysv/linux/configure.in
sysdeps/unix/sysv/linux/dl-librecon.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/dl-osinfo.h
sysdeps/unix/sysv/linux/i386/dl-librecon.h
sysdeps/unix/sysv/linux/i386/readelflib.c
sysdeps/unix/sysv/linux/ia64/readelflib.c
sysdeps/unix/sysv/linux/init-first.c
sysdeps/unix/sysv/linux/sparc/readelflib.c

index 5045392..817a5b2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+2001-03-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * csu/Makefile (abi-tag.h): Define OS and version separately, allow
+       version to be overriden from config.h.
+       * csu/abi-note.S: Use OS and version separately, include config.h.
+       * elf/dl-load.c (_dl_osversion): New.
+       (_dl_map_object_from_fd): Kill some warnings.
+       (open_verify): Check .note.ABI-tag of the library if present.
+       * elf/Makefile (CPPFLAGS-dl-load.c): Add -I$(csu-objpfx).
+       * elf/cache.c (struct cache_entry): Add osversion.
+       (print_entry): Print osversion.
+       (print_cache): Pass osversion to it.
+       (compare): Sort according to osversion.
+       (save_cache): Set osversion.
+       (add_to_cache): Add osversion argument.
+       * sysdeps/generic/ldconfig.h (add_to_cache, process_file,
+       process_elf_file): Add osversion argument.
+       * elf/readlib.c (process_file): Likewise.
+       * sysdeps/generic/readelflib.c (process_elf_file): Likewise.
+       * sysdeps/unix/sysv/linux/ia64/readelflib.c (process_elf_file,
+       process_elf32_file, process_elf64_file): Likewise.
+       * sysdeps/unix/sysv/linux/i386/readelflib.c (process_elf_file,
+       process_elf32_file, process_elf64_file): Likewise.
+       * sysdeps/unix/sysv/linux/sparc/readelflib.c (process_elf_file,
+       process_elf32_file, process_elf64_file): Likewise.
+       * elf/ldconfig.c (manual_link): Pass it.
+       (search_dir): Issue diagnostic if two libs with the same soname in
+       the same directory have different .note.ABI-tag.  Record osversion in
+       dlib_entry and use it from there.
+       (struct lib_entry): Remove.
+       (struct dlib_entry): Add osversion.
+       * sysdeps/generic/dl-cache.c (_dl_load_cache_lookup): Check
+       osversion.
+       * sysdeps/generic/dl-cache.h (struct file_entry_new): Replace __unused
+       field with osversion.
+       * sysdeps/generic/ldsodefs.h (_dl_osversion): Declare.
+       * sysdeps/unix/sysv/linux/init-first.c: Include ldsodefs.h.
+       * sysdeps/unix/sysv/linux/dl-osinfo.h (DL_SYSDEP_OSCHECK): Save kernel
+       version in _dl_osversion.
+       * sysdeps/unix/sysv/linux/configure.in: Define __ABI_TAG_VERSION.
+       * Makerules (build-shlib-helper, build-module-helper): New.
+       (build-shlib, build-module-helper): Make sure .note.ABI-tag comes
+       early.
+       * config.h.in (__ABI_TAG_VERSION): Add.
+       * elf/dl-minimal.c (__strtoul_internal): Set endptr on return.
+       * sysdeps/unix/sysv/linux/i386/dl-librecon.h (EXTRA_LD_ENVVARS):
+       Handle LD_ASSUME_KERNEL.
+       * sysdeps/unix/sysv/linux/dl-librecon.h: New.
+
 2001-03-15  Ulrich Drepper  <drepper@redhat.com>
 
        * timezone/antarctica: Update from tzdata2001a.
index 5f938dd..78089e6 100644 (file)
--- a/Makerules
+++ b/Makerules
@@ -413,29 +413,75 @@ endif
 lib%.so: lib%_pic.a $(+preinit) $(+postinit) $(+interp)
        $(build-shlib)
 
-define build-shlib
-$(LINK.o) -shared -Wl,-O1 -o $@ $(sysdep-LDFLAGS) $(config-LDFLAGS)  \
+define build-shlib-helper
+$(LINK.o) -shared -Wl,-O1 $(sysdep-LDFLAGS) $(config-LDFLAGS) \
          $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
          $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
          -Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
          $(LDFLAGS.so) $(LDFLAGS-$(@F:lib%.so=%).so) \
-         -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
-         -Wl,--whole-archive \
+         -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)
+endef
+
+ifeq (yes,$(elf))
+# binutils only position loadable notes into the first page for binaries,
+# not for shared objects
+define build-shlib
+$(build-shlib-helper) \
+         -o $@.new $(csu-objpfx)/abi-note.o -Wl,--verbose \
+         $(LDLIBS-$(@F:lib%.so=%).so) 2>&1 | \
+         sed -e '/^=========/,/^=========/!d;/^=========/d' \
+             -e 's/^.*\.hash[  ]*:.*$$/  .note.ABI-tag : { *(.note.ABI-tag) } &/' \
+         > $@.lds; \
+         rm -f $@.new; \
+         $(build-shlib-helper) -o $@ -T $@.lds \
+         -Wl,--whole-archive $(csu-objpfx)/abi-note.o \
+         $(filter-out $(map-file) $(+preinit) $(+postinit),$^) \
+         $(no-whole-archive) $(LDLIBS-$(@F:lib%.so=%).so); \
+         rm -f $@.lds
+endef
+else
+define build-shlib
+$(build-shlib-helper) \
+         -o $@ -Wl,--whole-archive \
          $(filter-out $(map-file) $(+preinit) $(+postinit),$^) \
          $(no-whole-archive) $(LDLIBS-$(@F:lib%.so=%).so)
 endef
+endif
+
+define build-module-helper
+$(LINK.o) -shared $(sysdep-LDFLAGS) $(config-LDFLAGS) \
+         -B$(csu-objpfx) $(load-map-file) \
+         $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \
+         -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)
+endef
 
 # This macro is similar to build-shlib but it does not define a soname
 # and it does not depend on the destination name to start with `lib'.
+ifeq (yes,$(elf))
+# binutils only position loadable notes into the first page for binaries,
+# not for shared objects
 define build-module
-$(LINK.o) -shared -o $@ $(sysdep-LDFLAGS) $(config-LDFLAGS)  \
-         -B$(csu-objpfx) $(load-map-file) \
-         $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \
-         -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
-         -Wl,--whole-archive \
+$(build-module-helper) \
+         -o $@.new $(csu-objpfx)/abi-note.o -Wl,--verbose \
+         $(LDLIBS-$(@F:lib%.so=%).so) 2>&1 | \
+         sed -e '/^=========/,/^=========/!d;/^=========/d' \
+             -e 's/^.*\.hash[  ]*:.*$$/  .note.ABI-tag : { *(.note.ABI-tag) } &/' \
+         > $@.lds; \
+         rm -f $@.new; \
+         $(build-module-helper) -o $@ -T $@.lds \
+         -Wl,--whole-archive $(csu-objpfx)/abi-note.o \
+         $(filter-out $(map-file) $(+preinit) $(+postinit),$^) \
+         $(no-whole-archive) $(LDLIBS-$(@F:lib%.so=%).so); \
+         rm -f $@.lds
+endef
+else
+define build-module
+$(build-module-helper) \
+         -o $@ -Wl,--whole-archive \
          $(filter-out $(map-file) $(+preinit) $(+postinit),$^) \
          $(no-whole-archive) $(LDLIBS-$(@F:%.so=%).so)
 endef
+endif
 
 # Don't try to use -lc when making libc.so itself.
 # Also omits crti.o and crtn.o, which we do not want
index b6223d7..14e1550 100644 (file)
@@ -93,6 +93,9 @@
 /* Linux specific: minimum supported kernel version.  */
 #undef __LINUX_KERNEL_VERSION
 
+/* Override abi-tags ABI version if necessary.  */
+#undef  __ABI_TAG_VERSION
+
 /* An extension in gcc 2.96 and up allows the subtraction of two
    local labels.  */
 #undef HAVE_SUBTRACT_LOCAL_LABELS
index ad59404..838e141 100644 (file)
@@ -168,12 +168,17 @@ $(objpfx)abi-tag.h: $(..)abi-tags
        $(make-target-directory)
        rm -f $@.new
        sed -e 's/#.*$$//' -e '/^[      ]*$$/d' $< | \
-       while read conf tag; do \
+       while read conf tagos tagver; do \
          test `expr '$(config-machine)-$(config-vendor)-$(config-os)' \
                     : "$$conf"` != 0 || continue; \
-         echo "$$tag" | \
-         sed -e 's/[^0-9xXa-fA-F]/ /g' -e 's/ *$$//' \
-             -e 's/ /,/g' -e 's/^ */#define ABI_TAG /' > $@.new; \
+         ( echo "$$tagos" | \
+           sed -e 's/[^0-9xXa-fA-F     ]//' \
+               -e 's/^/#define __ABI_TAG_OS /'; \
+           echo "#ifndef __ABI_TAG_VERSION"; \
+           echo "$$tagver" | \
+           sed -e 's/[^0-9xXa-fA-F]/ /g' -e 's/ *$$//' \
+             -e 's/ /,/g' -e 's/^/# define __ABI_TAG_VERSION /'; \
+           echo "#endif" ) > $@.new; \
        done
        if test -r $@.new; then mv -f $@.new $@; \
        else echo >&2 'This configuration not matched in $<'; exit 1; fi
index 6050883..3ad3a47 100644 (file)
@@ -1,5 +1,5 @@
 /* Special .init and .fini section support.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it
@@ -54,6 +54,7 @@ offset        length  contents
    identify the earliest release of that OS that supports this ABI.
    See abi-tags (top level) for details. */
 
+#include <config.h>
 #include <abi-tag.h>           /* OS-specific ABI tag value */
        
 /* The linker (GNU ld 2.8 and later) recognizes an allocated section whose
@@ -67,5 +68,6 @@ offset        length  contents
        .long  1                /* note type */
 0:     .asciz "GNU"            /* vendor name */
 1:     .align 4                
-2:     .long ABI_TAG           /* note data: the ABI tag */
+2:     .long __ABI_TAG_OS      /* note data: the ABI tag */
+       .long __ABI_TAG_VERSION
 3:     .align 4                /* pad out section */
index a4f0a10..dff36c9 100644 (file)
@@ -188,7 +188,7 @@ $(objpfx)trusted-dirs.st: Makefile $(..)Makeconfig
        | $(AWK) -f gen-trusted-dirs.awk > ${@:st=T};
        $(move-if-change) ${@:st=T} ${@:st=h}
        touch $@
-CPPFLAGS-dl-load.c = -I$(objpfx).
+CPPFLAGS-dl-load.c = -I$(objpfx). -I$(csu-objpfx).
 
 ifeq (yes,$(build-shared))
 $(inst_slibdir)/$(rtld-version-installed-name): $(objpfx)ld.so $(+force)
index 378ce8f..19237bb 100644 (file)
@@ -39,6 +39,7 @@ struct cache_entry
   char *lib;                   /* Library name.  */
   char *path;                  /* Path to find library.  */
   int flags;                   /* Flags to indicate kind of library.  */
+  unsigned int osversion;      /* Required OS version.  */
   uint64_t hwcap;              /* Important hardware capabilities.  */
   int bits_hwcap;              /* Number of bits set in hwcap.  */
   struct cache_entry *next;    /* Next entry in list.  */
@@ -52,7 +53,8 @@ static const char *flag_descr[] =
 
 /* Print a single entry.  */
 static void
-print_entry (const char *lib, int flag, uint64_t hwcap, const char *key)
+print_entry (const char *lib, int flag, unsigned int osversion,
+            uint64_t hwcap, const char *key)
 {
   printf ("\t%s (", lib);
   switch (flag & FLAG_TYPE_MASK)
@@ -61,7 +63,7 @@ print_entry (const char *lib, int flag, uint64_t hwcap, const char *key)
     case FLAG_ELF:
     case FLAG_ELF_LIBC5:
     case FLAG_ELF_LIBC6:
-      fputs (flag_descr [flag & FLAG_TYPE_MASK], stdout);
+      fputs (flag_descr[flag & FLAG_TYPE_MASK], stdout);
       break;
     default:
       fputs ("unknown", stdout);
@@ -85,6 +87,23 @@ print_entry (const char *lib, int flag, uint64_t hwcap, const char *key)
     }
   if (hwcap != 0)
     printf (", hwcap: 0x%" PRIx64, hwcap);
+  if (osversion != 0)
+    {
+      static const char *const abi_tag_os[] =
+      {
+       [0] = "Linux",
+       [1] = "Hurd",
+       [2] = "Solaris",
+       [3] = "Unknown OS"
+      };
+      unsigned int os = osversion >> 24;
+
+      printf (", OS ABI: %s %d.%d.%d",
+             abi_tag_os[os > 3 ? 3 : os],
+             (osversion >> 16) & 0xff,
+             (osversion >> 8) & 0xff,
+             osversion & 0xff);
+    }
   printf (") => %s\n", key);
 }
 
@@ -139,7 +158,8 @@ print_cache (const char *cache_name)
   else
     {
       size_t offset = ALIGN_CACHE (sizeof (struct cache_file)
-                                  + cache->nlibs * sizeof (struct file_entry));
+                                  + (cache->nlibs
+                                     * sizeof (struct file_entry)));
       /* This is where the strings start.  */
       cache_data = (const char *) &cache->libs[cache->nlibs];
 
@@ -150,9 +170,10 @@ print_cache (const char *cache_name)
 
          cache_new = (struct cache_file_new *) ((void *)cache + offset);
 
-         if (!memcmp (cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1)
-             && !memcmp (cache_new->version, CACHE_VERSION,
-                         sizeof CACHE_VERSION - 1))
+         if (memcmp (cache_new->magic, CACHEMAGIC_NEW,
+                     sizeof CACHEMAGIC_NEW - 1) == 0
+             && memcmp (cache_new->version, CACHE_VERSION,
+                        sizeof CACHE_VERSION - 1) == 0)
            {
              cache_data = (const char *) cache_new;
              format = 1;
@@ -167,17 +188,19 @@ print_cache (const char *cache_name)
       /* Print everything.  */
       for (i = 0; i < cache->nlibs; i++)
        print_entry (cache_data + cache->libs[i].key,
-                    cache->libs[i].flags, 0,
+                    cache->libs[i].flags, 0, 0,
                     cache_data + cache->libs[i].value);
     }
   else if (format == 1)
     {
-      printf (_("%d libs found in cache `%s'\n"), cache_new->nlibs, cache_name);
+      printf (_("%d libs found in cache `%s'\n"),
+             cache_new->nlibs, cache_name);
 
       /* Print everything.  */
       for (i = 0; i < cache_new->nlibs; i++)
        print_entry (cache_data + cache_new->libs[i].key,
                     cache_new->libs[i].flags,
+                    cache_new->libs[i].osversion,
                     cache_new->libs[i].hwcap,
                     cache_data + cache_new->libs[i].value);
     }
@@ -217,6 +240,10 @@ int compare (const struct cache_entry *e1, const struct cache_entry *e2)
        return 1;
       else if (e2->hwcap < e1->hwcap)
        return -1;
+      if (e2->osversion > e1->osversion)
+       return 1;
+      if (e2->osversion < e1->osversion)
+       return -1;
     }
   return res;
 }
@@ -280,12 +307,15 @@ save_cache (const char *cache_name)
       /* And the list of all entries in the new format.  */
       file_entries_new_size = sizeof (struct cache_file_new)
        + cache_entry_count * sizeof (struct file_entry_new);
-      file_entries_new = (struct cache_file_new *) xmalloc (file_entries_new_size);
+      file_entries_new =
+       (struct cache_file_new *) xmalloc (file_entries_new_size);
 
       /* Fill in the header.  */
       memset (file_entries_new, 0, sizeof (struct cache_file_new));
-      memcpy (file_entries_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1);
-      memcpy (file_entries_new->version, CACHE_VERSION, sizeof CACHE_VERSION - 1);
+      memcpy (file_entries_new->magic, CACHEMAGIC_NEW,
+             sizeof CACHEMAGIC_NEW - 1);
+      memcpy (file_entries_new->version, CACHE_VERSION,
+             sizeof CACHE_VERSION - 1);
 
       file_entries_new->nlibs = cache_entry_count;
       file_entries_new->len_strings = total_strlen;
@@ -319,9 +349,9 @@ save_cache (const char *cache_name)
             always begins at the beginning of the the new cache
             struct.  */
          file_entries_new->libs[idx_new].flags = entry->flags;
+         file_entries_new->libs[idx_new].osversion = entry->osversion;
          file_entries_new->libs[idx_new].hwcap = entry->hwcap;
          file_entries_new->libs[idx_new].key = str_offset;
-         file_entries_new->libs[idx_new].__unused = 0;
        }
       len = strlen (entry->lib);
       str = stpcpy (str, entry->lib);
@@ -363,7 +393,8 @@ save_cache (const char *cache_name)
   /* Write contents.  */
   if (opt_format != 2)
     {
-      if (write (fd, file_entries, file_entries_size) != (ssize_t)file_entries_size)
+      if (write (fd, file_entries, file_entries_size)
+         != (ssize_t)file_entries_size)
        error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
     }
   if (opt_format != 0)
@@ -371,7 +402,7 @@ save_cache (const char *cache_name)
       /* Align cache.  */
       if (opt_format != 2)
        {
-         char zero [pad];
+         char zero[pad];
          if (write (fd, zero, pad) != (ssize_t)pad)
            error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
        }
@@ -414,7 +445,7 @@ save_cache (const char *cache_name)
 /* Add one library to the cache.  */
 void
 add_to_cache (const char *path, const char *lib, int flags,
-             uint64_t hwcap)
+             unsigned int osversion, uint64_t hwcap)
 {
   struct cache_entry *new_entry, *ptr, *prev;
   char *full_path;
@@ -430,6 +461,7 @@ add_to_cache (const char *path, const char *lib, int flags,
   new_entry->lib = xstrdup (lib);
   new_entry->path = full_path;
   new_entry->flags = flags;
+  new_entry->osversion = osversion;
   new_entry->hwcap = hwcap;
   new_entry->bits_hwcap = 0;
 
index 6e4c972..0a5603f 100644 (file)
@@ -30,6 +30,8 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include "dynamic-link.h"
+#include <abi-tag.h>
+#include <dl-osinfo.h>
 
 #include <dl-dst.h>
 
@@ -111,6 +113,8 @@ struct filebuf
 
 size_t _dl_pagesize;
 
+unsigned int _dl_osversion;
+
 int _dl_clktck;
 
 extern const char *_dl_platform;
@@ -1061,12 +1065,12 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0))
     _dl_debug_printf ("  dynamic: 0x%0*lx  base: 0x%0*lx   size: 0x%0*Zx\n"
                      "    entry: 0x%0*lx  phdr: 0x%0*lx  phnum:   %*u\n\n",
-                     sizeof (void *) * 2, (unsigned long int) l->l_ld,
-                     sizeof (void *) * 2, (unsigned long int) l->l_addr,
-                     sizeof (void *) * 2, maplength,
-                     sizeof (void *) * 2, (unsigned long int) l->l_entry,
-                     sizeof (void *) * 2, (unsigned long int) l->l_phdr,
-                     sizeof (void *) * 2, l->l_phnum);
+                     (int) sizeof (void *) * 2, (unsigned long int) l->l_ld,
+                     (int) sizeof (void *) * 2, (unsigned long int) l->l_addr,
+                     (int) sizeof (void *) * 2, maplength,
+                     (int) sizeof (void *) * 2, (unsigned long int) l->l_entry,
+                     (int) sizeof (void *) * 2, (unsigned long int) l->l_phdr,
+                     (int) sizeof (void *) * 2, l->l_phnum);
 
   elf_get_dynamic_info (l);
 
@@ -1213,6 +1217,10 @@ open_verify (const char *name, struct filebuf *fbp)
     [EI_OSABI] = ELFOSABI_SYSV,
     [EI_ABIVERSION] = 0
   };
+  static const struct {
+    ElfW(Word) vendorlen, datalen, type;
+    char vendor [4];
+  } expected_note = { 4, 16, 1, "GNU" };
   int fd;
 
   /* Open the file.  We always open files read-only.  */
@@ -1220,6 +1228,10 @@ open_verify (const char *name, struct filebuf *fbp)
   if (fd != -1)
     {
       ElfW(Ehdr) *ehdr;
+      ElfW(Phdr) *phdr, *ph;
+      ElfW(Word) *abi_note, abi_note_buf[8];
+      unsigned int osversion;
+      size_t maplength;
 
       /* We successfully openened the file.  Now verify it is a file
         we can use.  */
@@ -1287,12 +1299,7 @@ open_verify (const char *name, struct filebuf *fbp)
        lose (0, fd, name, NULL, NULL,
              N_("ELF file version does not match current one"));
       if (! __builtin_expect (elf_machine_matches_host (ehdr), 1))
-       {
-       close_and_out:
-         __close (fd);
-         __set_errno (ENOENT);
-         fd = -1;
-       }
+       goto close_and_out;
       else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr)))
               != sizeof (ElfW(Phdr)))
        lose (0, fd, name, NULL, NULL,
@@ -1301,6 +1308,50 @@ open_verify (const char *name, struct filebuf *fbp)
               && __builtin_expect (ehdr->e_type, ET_EXEC) != ET_EXEC)
        lose (0, fd, name, NULL, NULL,
              N_("only ET_DYN and ET_EXEC can be loaded"));
+
+      maplength = ehdr->e_phnum * sizeof (ElfW(Phdr));
+      if (ehdr->e_phoff + maplength <= fbp->len)
+       phdr = (void *) (fbp->buf + ehdr->e_phoff);
+      else
+       {
+         phdr = alloca (maplength);
+         __lseek (fd, SEEK_SET, ehdr->e_phoff);
+         if (__libc_read (fd, (void *) phdr, maplength) != maplength)
+           lose (errno, fd, name, NULL, NULL, N_("cannot read file data"));
+       }
+
+      /* Check .note.ABI-tag if present.  */
+      for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ++ph)
+       if (ph->p_type == PT_NOTE && ph->p_filesz == 32 && ph->p_align >= 4)
+         {
+           if (ph->p_offset + 32 <= fbp->len)
+             abi_note = (void *) (fbp->buf + ph->p_offset);
+           else
+             {
+               __lseek (fd, SEEK_SET, ph->p_offset);
+               if (__libc_read (fd, (void *) abi_note_buf, 32) != 32)
+                 lose (errno, fd, name, NULL, NULL,
+                       N_("cannot read file data"));
+               abi_note = abi_note_buf;
+             }
+
+           if (memcmp (abi_note, &expected_note, sizeof (expected_note)))
+             continue;
+
+           osversion = (abi_note [5] & 0xff) * 65536
+                       + (abi_note [6] & 0xff) * 256
+                       + (abi_note [7] & 0xff);
+           if (abi_note [4] != __ABI_TAG_OS
+               || (_dl_osversion && _dl_osversion < osversion))
+             {
+             close_and_out:
+               __close (fd);
+               __set_errno (ENOENT);
+               fd = -1;
+             }
+
+           break;
+         }
     }
 
   return fd;
index 5184c11..8922edc 100644 (file)
@@ -252,6 +252,8 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
          || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10))
        {
          errno = ERANGE;
+         if (endptr != NULL)
+           *endptr = (char *) nptr;
          return ULONG_MAX;
        }
       result *= base;
@@ -259,5 +261,7 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
       ++nptr;
     }
 
+  if (endptr != NULL)
+    *endptr = (char *) nptr;
   return result * sign;
 }
index 4c00bce..d3c5355 100644 (file)
 
 #define PACKAGE _libc_intl_domainname
 
-struct lib_entry
-  {
-    int flags;
-    uint64_t hwcap;
-    char *lib;
-    char *path;
-  };
-
 static const struct
 {
   const char *name;
   int flag;
-} lib_types [] =
+} lib_types[] =
 {
   {"libc4", FLAG_LIBC4},
   {"libc5", FLAG_ELF_LIBC5},
@@ -316,7 +308,7 @@ add_dir (const char *line)
       *equal_sign = '\0';
       ++equal_sign;
       entry->flag = FLAG_ANY;
-      for (i = 0; i < sizeof (lib_types) / sizeof (lib_types [0]); ++i)
+      for (i = 0; i < sizeof (lib_types) / sizeof (lib_types[0]); ++i)
        if (strcmp (equal_sign, lib_types[i].name) == 0)
          {
            entry->flag = lib_types[i].flag;
@@ -334,7 +326,7 @@ add_dir (const char *line)
   i = strlen (entry->path) - 1;
   while (entry->path[i] == '/' && i > 0)
     {
-      entry->path [i] = '\0';
+      entry->path[i] = '\0';
       --i;
     }
 
@@ -460,6 +452,7 @@ manual_link (char *library)
   char *soname;
   struct stat64 stat_buf;
   int flag;
+  unsigned int osversion;
 
   /* Prepare arguments for create_links call.  Split library name in
      directory and filename first.  Since path is allocated, we've got
@@ -524,7 +517,8 @@ manual_link (char *library)
       free (path);
       return;
     }
-  if (process_file (real_library, library, libname, &flag, &soname, 0))
+  if (process_file (real_library, library, libname, &flag, &osversion,
+                   &soname, 0))
     {
       error (0, 0, _("No link created since soname could not be found for %s"),
             library);
@@ -568,6 +562,7 @@ struct dlib_entry
   char *soname;
   int flag;
   int is_link;
+  unsigned int osversion;
   struct dlib_entry *next;
 };
 
@@ -585,6 +580,7 @@ search_dir (const struct dir_entry *entry)
   struct stat64 stat_buf;
   int is_link;
   uint64_t hwcap = path_hwcap (entry->path);
+  unsigned int osversion;
 
   file_name_len = PATH_MAX;
   file_name = alloca (file_name_len);
@@ -700,7 +696,7 @@ search_dir (const struct dir_entry *entry)
        real_name = real_file_name;
 
       if (process_file (real_name, file_name, direntry->d_name, &flag,
-                       &soname, is_link))
+                       &osversion, &soname, is_link))
        {
          if (real_name != real_file_name)
            free (real_name);
@@ -762,6 +758,11 @@ search_dir (const struct dir_entry *entry)
                        error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
                               dlib_ptr->name, direntry->d_name, entry->path);
                    }
+                 /* OS version should be the same - sanity check.  */
+                 if (dlib_ptr->osversion != osversion)
+                   error (0, 0, _("libraries %s and %s in directory %s have same\n"
+                                  "soname but different minimal supported OS version."),
+                          dlib_ptr->name, direntry->d_name, entry->path);
                  free (dlib_ptr->name);
                  dlib_ptr->name = xstrdup (direntry->d_name);
                  dlib_ptr->is_link = is_link;
@@ -778,6 +779,7 @@ search_dir (const struct dir_entry *entry)
          dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
          dlib_ptr->name = xstrdup (direntry->d_name);
          dlib_ptr->flag = flag;
+         dlib_ptr->osversion = osversion;
          dlib_ptr->soname = soname;
          dlib_ptr->is_link = is_link;
          /* Add at head of list.  */
@@ -797,7 +799,8 @@ search_dir (const struct dir_entry *entry)
        create_links (dir_name, entry->path, dlib_ptr->name,
                      dlib_ptr->soname);
       if (opt_build_cache)
-       add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag, hwcap);
+       add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag,
+                     dlib_ptr->osversion, hwcap);
     }
 
   /* Free all resources.  */
@@ -909,7 +912,7 @@ main (int argc, char **argv)
     {
       int i;
       for (i = remaining; i < argc; ++i)
-       add_dir (argv [i]);
+       add_dir (argv[i]);
     }
 
   if (opt_chroot)
@@ -990,7 +993,7 @@ main (int argc, char **argv)
       int i;
 
       for (i = remaining; i < argc; ++i)
-       manual_link (argv [i]);
+       manual_link (argv[i]);
 
       exit (0);
     }
index 746c78f..2886c5d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
                  Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -48,18 +48,18 @@ struct known_names
   int flag;
 };
 
-static struct known_names interpreters [] =
+static struct known_names interpreters[] =
 {
-  {"/lib/" LD_SO, FLAG_ELF_LIBC6},
+  { "/lib/" LD_SO, FLAG_ELF_LIBC6 },
 #ifdef SYSDEP_KNOWN_INTERPRETER_NAMES
   SYSDEP_KNOWN_INTERPRETER_NAMES
 #endif
 };
 
-static struct known_names known_libs [] =
+static struct known_names known_libs[] =
 {
-  {LIBC_SO, FLAG_ELF_LIBC6},
-  {LIBM_SO, FLAG_ELF_LIBC6},
+  { LIBC_SO, FLAG_ELF_LIBC6 },
+  { LIBM_SO, FLAG_ELF_LIBC6 },
 #ifdef SYSDEP_KNOWN_LIBRARY_NAMES
   SYSDEP_KNOWN_LIBRARY_NAMES
 #endif
@@ -70,13 +70,13 @@ static struct known_names known_libs [] =
 /* Returns 0 if everything is ok, != 0 in case of error.  */
 int
 process_file (const char *real_file_name, const char *file_name,
-             const char *lib, int *flag, char **soname, int is_link)
+             const char *lib, int *flag, unsigned int *osversion,
+             char **soname, int is_link)
 {
   FILE *file;
   struct stat64 statbuf;
   void *file_contents;
   int ret;
-
   ElfW(Ehdr) *elf_header;
   struct exec *aout_header;
 
@@ -142,10 +142,7 @@ process_file (const char *real_file_name, const char *file_name,
     }
 
   elf_header = (ElfW(Ehdr) *) file_contents;
-  if (elf_header->e_ident [EI_MAG0] != ELFMAG0
-      || elf_header->e_ident [EI_MAG1] != ELFMAG1
-      || elf_header->e_ident [EI_MAG2] != ELFMAG2
-      || elf_header->e_ident [EI_MAG3] != ELFMAG3)
+  if (memcmp (elf_header->e_ident, ELFMAG, SELFMAG) != 0)
     {
       /* The file is neither ELF nor aout.  Check if it's a linker script,
         like libc.so - otherwise complain.  */
@@ -161,8 +158,8 @@ process_file (const char *real_file_name, const char *file_name,
       goto done;
     }
 
-  if (process_elf_file (file_name, lib, flag, soname, file_contents,
-                       statbuf.st_size))
+  if (process_elf_file (file_name, lib, flag, osversion, soname,
+                       file_contents, statbuf.st_size))
     ret = 1;
 
  done:
index 9400734..20ae0e3 100644 (file)
@@ -1182,5 +1182,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
 #undef MEMPCPY
 #undef MEMCHR
 #undef STRCOLL
+#undef STRLEN
+#undef STRCAT
 #undef L
 #undef BTOWC
index 5e16f28..65135d4 100644 (file)
@@ -228,6 +228,8 @@ _dl_load_cache_lookup (const char *name)
 
       /* Only accept hwcap if it's for the right platform.  */
 #define HWCAP_CHECK                                                           \
+      if (_dl_osversion        && cache_new->libs[middle].osversion > _dl_osversion)  \
+       continue;                                                              \
       if (_DL_PLATFORMS_COUNT && platform != -1                                       \
          && (cache_new->libs[middle].hwcap & _DL_HWCAP_PLATFORM) != 0         \
          && (cache_new->libs[middle].hwcap & _DL_HWCAP_PLATFORM) != platform) \
index 2d02dcf..7938fc0 100644 (file)
@@ -76,7 +76,7 @@ struct file_entry_new
 {
   int32_t flags;               /* This is 1 for an ELF library.  */
   uint32_t key, value;         /* String table indices.  */
-  uint32_t __unused;           /* Align next field always on 8 byte boundary.  */
+  uint32_t osversion;          /* Required OS version.  */
   uint64_t hwcap;              /* Hwcap entry.  */
 };
 
index aaad06d..0575f48 100644 (file)
@@ -39,17 +39,17 @@ extern void init_cache (void);
 extern void save_cache (const char *cache_name);
 
 extern void add_to_cache (const char *path, const char *lib, int flags,
-                         uint64_t hwcap);
+                         unsigned int osversion, uint64_t hwcap);
 
 /* Declared in readlib.c.  */
 extern int process_file (const char *real_file_name, const char *file_name,
-                        const char *lib, int *flag, char **soname,
-                        int is_link);
+                        const char *lib, int *flag, unsigned int *osversion,
+                        char **soname, int is_link);
 
 /* Declared in readelflib.c.  */
 extern int process_elf_file (const char *file_name, const char *lib, int *flag,
-                            char **soname, void *file_contents,
-                            size_t file_length);
+                            unsigned int *osversion, char **soname,
+                            void *file_contents, size_t file_length);
 
 /* Declared in chroot_canon.c.  */
 extern char *chroot_canon (const char *chroot, const char *name);
index 0575eaf..bcdcf7d 100644 (file)
@@ -173,6 +173,9 @@ extern char **_dl_argv;
 /* Cached value of `getpagesize ()'.  */
 extern size_t _dl_pagesize;
 
+/* OS version.  */
+extern unsigned int _dl_osversion;
+
 /* File descriptor referring to the zero-fill device.  */
 extern int _dl_zerofd;
 
index 2797c28..5354526 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
                  Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -41,7 +41,8 @@ do                                                            \
 /* Returns 0 if everything is ok, != 0 in case of error.  */
 int
 process_elf_file (const char *file_name, const char *lib, int *flag,
-                 char **soname, void *file_contents, size_t file_length)
+                 unsigned int *osversion, char **soname, void *file_contents,
+                 size_t file_length)
 {
   int i;
   unsigned int j;
@@ -56,6 +57,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
   char *dynamic_strings;  
 
   elf_header = (ElfW(Ehdr) *) file_contents;
+  *osversion = 0;
 
   if (elf_header->e_ident [EI_CLASS] != ElfW (CLASS))
     {
@@ -110,6 +112,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
          dynamic_addr = segment->p_offset;
          dynamic_size = segment->p_filesz;
          break;
+
        case PT_INTERP:
          program_interpreter = (char *) (file_contents + segment->p_offset);
          check_ptr (program_interpreter);
@@ -123,6 +126,21 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
                break;
              }
          break;
+
+       case PT_NOTE:
+         if (!*osversion && segment->p_filesz == 32 && segment->p_align >= 4)
+           {
+             ElfW(Word) *abi_note = (ElfW(Word) *) (file_contents
+                                                    + segment->p_offset);
+             if (abi_note [0] == 4 && abi_note [1] == 16 && abi_note [2] == 1
+                 && memcmp (abi_note + 3, "GNU", 4) == 0)
+               *osversion = (abi_note [4] << 24) |
+                            ((abi_note [5] & 0xff) << 16) |
+                            ((abi_note [6] & 0xff) << 8) |
+                            (abi_note [7] & 0xff);
+           }
+         break;
+
        default:
          break;
        }
index e6d4a7d..fc5297d 100644 (file)
@@ -87,6 +87,7 @@ if test -n "$minimum_kernel"; then
   echo $ac_n "checking for kernel header at least $minimum_kernel""... $ac_c" 1>&6
 echo "configure:89: checking for kernel header at least $minimum_kernel" >&5
   decnum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/(\1 * 65536 + \2 * 256 + \3)/'`;
+  abinum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1,\2,\3/'`;
   cat > conftest.$ac_ext <<EOF
 #line 92 "configure"
 #include "confdefs.h"
@@ -111,6 +112,10 @@ rm -f conftest*
 #define __LINUX_KERNEL_VERSION $decnum
 EOF
 
+    cat >> confdefs.h <<EOF
+#define __ABI_TAG_VERSION $abinum
+EOF
+
   else
     { echo "configure: error: *** The available kernel headers are older than the requested
 *** compatible kernel version" 1>&2; exit 1; }
index 7d538e8..afe7982 100644 (file)
@@ -74,6 +74,7 @@ if test -n "$minimum_kernel"; then
   AC_MSG_CHECKING(for kernel header at least $minimum_kernel)
 changequote(,)dnl
   decnum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/(\1 * 65536 + \2 * 256 + \3)/'`;
+  abinum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1,\2,\3/'`;
 changequote([,])dnl
   AC_EGREP_CPP([eat flaming death], [#include <linux/version.h>
 #if LINUX_VERSION_CODE < $decnum
@@ -82,6 +83,7 @@ eat flaming death
   AC_MSG_RESULT($libc_minimum_kernel)
   if test "$libc_minimum_kernel" = ok; then
     AC_DEFINE_UNQUOTED(__LINUX_KERNEL_VERSION, $decnum)
+    AC_DEFINE_UNQUOTED(__ABI_TAG_VERSION, $abinum)
   else
     AC_MSG_ERROR([*** The available kernel headers are older than the requested
 *** compatible kernel version])
diff --git a/sysdeps/unix/sysv/linux/dl-librecon.h b/sysdeps/unix/sysv/linux/dl-librecon.h
new file mode 100644 (file)
index 0000000..843e874
--- /dev/null
@@ -0,0 +1,49 @@
+/* Optional code to distinguish library flavours.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _DL_LIBRECON_H
+#define _DL_LIBRECON_H 1
+
+/* Recognizing extra environment variables.  */
+#define EXTRA_LD_ENVVARS \
+  case 13:                                                                   \
+    if (memcmp (&envline[3], "ASSUME_KERNEL", 13) == 0)                              \
+      {                                                                              \
+       unsigned long int i, j, osversion = 0;                                \
+       char *p = &envline[17], *q;                                           \
+                                                                             \
+       for (i = 0; i < 3; i++, p = q + 1)                                    \
+         {                                                                   \
+           j = __strtoul_internal (p, &q, 0, 0);                             \
+           if (j >= 255 || p == q || (i < 2 && *q && *q != '.'))             \
+             {                                                               \
+               osversion = 0;                                                \
+               break;                                                        \
+             }                                                               \
+           osversion |= j << (16 - 8 * i);                                   \
+           if (!*q)                                                          \
+             break;                                                          \
+         }                                                                   \
+       if (osversion)                                                        \
+         _dl_osversion = osversion;                                          \
+       break;                                                                \
+      }
+
+#endif /* dl-librecon.h */
index a56f8e6..e9bacf4 100644 (file)
@@ -102,5 +102,7 @@ dl_fatal (const char *str)
        if (version < __LINUX_KERNEL_VERSION)                                 \
          /* Not sufficent.  */                                               \
          FATAL ("FATAL: kernel too old\n");                                  \
+                                                                             \
+       _dl_osversion = version;                                              \
       }                                                                              \
   } while (0)
index 7d486c5..26311b3 100644 (file)
 
 /* Recognizing extra environment variables.  */
 #define EXTRA_LD_ENVVARS \
+  case 13:                                                                   \
+    if (memcmp (&envline[3], "ASSUME_KERNEL", 13) == 0)                              \
+      {                                                                              \
+       unsigned long int i, j, osversion = 0;                                \
+       char *p = &envline[17], *q;                                           \
+                                                                             \
+       for (i = 0; i < 3; i++, p = q + 1)                                    \
+         {                                                                   \
+           j = __strtoul_internal (p, &q, 0, 0);                             \
+           if (j >= 255 || p == q || (i < 2 && *q && *q != '.'))             \
+             {                                                               \
+               osversion = 0;                                                \
+               break;                                                        \
+             }                                                               \
+           osversion |= j << (16 - 8 * i);                                   \
+           if (!*q)                                                          \
+             break;                                                          \
+         }                                                                   \
+       if (osversion)                                                        \
+         _dl_osversion = osversion;                                          \
+       break;                                                                \
+      }                                                                              \
+                                                                             \
   case 15:                                                                   \
     if (memcmp (&envline[3], "LIBRARY_VERSION", 15) == 0)                    \
       {                                                                              \
index f8868bb..cc219d2 100644 (file)
 
 
 int process_elf32_file (const char *file_name, const char *lib, int *flag,
-                       char **soname, void *file_contents,
-                       size_t file_length);
+                       unsigned int *osversion, char **soname,
+                       void *file_contents, size_t file_length);
 int process_elf64_file (const char *file_name, const char *lib, int *flag,
-                       char **soname, void *file_contents,
-                       size_t file_length);
+                       unsigned int *osversion, char **soname,
+                       void *file_contents, size_t file_length);
 
 /* Returns 0 if everything is ok, != 0 in case of error.  */
 int
 process_elf_file (const char *file_name, const char *lib, int *flag,
-                 char **soname, void *file_contents, size_t file_length)
+                 unsigned int *osversion, char **soname, void *file_contents,
+                 size_t file_length)
 {
   ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
   int ret;
 
   if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
-    return process_elf32_file (file_name, lib, flag, soname, file_contents,
-                              file_length);
+    return process_elf32_file (file_name, lib, flag, osversion, soname,
+                              file_contents, file_length);
   else
     {
       switch (elf_header->e_machine)
@@ -50,8 +51,8 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
          return 1;
        }
 
-      ret = process_elf64_file (file_name, lib, flag, soname, file_contents,
-                               file_length);
+      ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+                               file_contents, file_length);
       /* IA64/X86-64 64bit libraries are always libc.so.6+.  */
       if (!ret)
        switch (elf_header->e_machine)
index 29a402b..efc699f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
 
 
 int process_elf32_file (const char *file_name, const char *lib, int *flag,
-                       char **soname, void *file_contents, size_t file_length);
+                       unsigned int *osversion, char **soname,
+                       void *file_contents, size_t file_length);
 int process_elf64_file (const char *file_name, const char *lib, int *flag,
-                       char **soname, void *file_contents, size_t file_length);
+                       unsigned int *osversion, char **soname,
+                       void *file_contents, size_t file_length);
 
 /* Returns 0 if everything is ok, != 0 in case of error.  */
 int
 process_elf_file (const char *file_name, const char *lib, int *flag,
-                 char **soname, void *file_contents, size_t file_length)
+                 unsigned int *osversion, char **soname,
+                 void *file_contents, size_t file_length)
 {
   ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
   int ret;
 
   if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
-    return process_elf32_file (file_name, lib, flag, soname, file_contents,
-                               file_length);
+    return process_elf32_file (file_name, lib, flag, osversion, soname,
+                              file_contents, file_length);
   else
     {
-      ret = process_elf64_file (file_name, lib, flag, soname, file_contents,
-                                file_length);
+      ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+                               file_contents, file_length);
       /* Intel 64bit libraries are always libc.so.6+.  */
       if (!ret)
        *flag = FLAG_IA64_LIB64|FLAG_ELF_LIBC6;
index 512a696..017878a 100644 (file)
@@ -29,6 +29,7 @@
 #include <libc-internal.h>
 
 #ifndef SHARED
+# include <ldsodefs.h>
 # include "dl-osinfo.h"
 #endif
 
index f500627..f8d383e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
                  Jakub Jelinek <jakub@redhat.com>, 1999.
 
 
 int process_elf32_file (const char *file_name, const char *lib, int *flag,
-                       char **soname, void *file_contents,
-                       size_t file_length);
+                       unsigned int *osversion, char **soname,
+                       void *file_contents, size_t file_length);
 int process_elf64_file (const char *file_name, const char *lib, int *flag,
-                       char **soname, void *file_contents,
-                       size_t file_length);
+                       unsigned int *osversion, char **soname,
+                       void *file_contents, size_t file_length);
 
 /* Returns 0 if everything is ok, != 0 in case of error.  */
 int
 process_elf_file (const char *file_name, const char *lib, int *flag,
-                 char **soname, void *file_contents, size_t file_length)
+                 unsigned int *osversion, char **soname, void *file_contents,
+                 size_t file_length)
 {
   ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
   int ret;
 
   if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
-    return process_elf32_file (file_name, lib, flag, soname, file_contents,
-                              file_length);
+    return process_elf32_file (file_name, lib, flag, osversion, soname,
+                              file_contents, file_length);
   else
     {
-      ret = process_elf64_file (file_name, lib, flag, soname, file_contents,
-                               file_length);
+      ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+                               file_contents, file_length);
       /* Sparc 64bit libraries are always libc.so.6+.  */
       if (!ret)
        *flag = FLAG_SPARC_LIB64|FLAG_ELF_LIBC6;