[BZ #2980] cvs/fedora-glibc-20060802T1650
authorUlrich Drepper <drepper@redhat.com>
Wed, 2 Aug 2006 16:45:53 +0000 (16:45 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 2 Aug 2006 16:45:53 +0000 (16:45 +0000)
2006-06-23  Joseph Myers  <joseph@codesourcery.com>
[BZ #2980]
* posix/Makefile (CFLAGS-waitid.c): Add
-fasynchronous-unwind-tables.

2006-08-02  Ulrich Drepper  <drepper@redhat.com>

* elf/dl-addr.c (_dl_addr): If GNU-style hash tables are present,
walk them instead of the symbol table.

ChangeLog
elf/dl-addr.c
nptl/sysdeps/unix/sysv/linux/smp.h
posix/Makefile

index a4bb3e8..6d8eea5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-06-23  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #2980]
+       * posix/Makefile (CFLAGS-waitid.c): Add
+       -fasynchronous-unwind-tables.
+
+2006-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-addr.c (_dl_addr): If GNU-style hash tables are present,
+       walk them instead of the symbol table.
+
 2006-08-01  Ulrich Drepper  <drepper@redhat.com>
 
        * nscd/initgrcache.c (addinitgroupsX): Judge successful lookups by
index ced8978..535977c 100644 (file)
@@ -74,28 +74,62 @@ _dl_addr (const void *address, Dl_info *info,
 
       ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
 
-      const ElfW(Sym) *symtabend;
-      if (match->l_info[DT_HASH] != NULL)
-       symtabend = (symtab
-                    + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
+      const ElfW(Sym) *matchsym = NULL;
+      if (match->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+                       + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL)
+       {
+         /* We look at all symbol table entries referenced by the
+            hash table.  */
+         for (Elf_Symndx bucket = 0; bucket < match->l_nbuckets; ++bucket)
+           {
+             Elf32_Word symndx = match->l_gnu_buckets[bucket];
+             if (bucket != 0)
+               {
+                 const Elf32_Word *hasharr = &match->l_gnu_chain_zero[symndx];
+
+                 do
+                   {
+                     /* The hash table never references local symbols
+                        so we can omit that test here.  */
+                     if (symtab[symndx].st_shndx != SHN_UNDEF
+#ifdef USE_TLS
+                         && ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
+#endif
+                         && DL_ADDR_SYM_MATCH (match, &symtab[symndx],
+                                               matchsym, addr)
+                         && symtab[symndx].st_name < strtabsize)
+                       matchsym = (ElfW(Sym) *) &symtab[symndx];
+
+                     ++symndx;
+                   }
+                 while ((*hasharr++ & 1u) == 0);
+               }
+           }
+       }
       else
-       /* There is no direct way to determine the number of symbols in the
-          dynamic symbol table and no hash table is present.  The ELF
-          binary is ill-formed but what shall we do?  Use the beginning of
-          the string table which generally follows the symbol table.  */
-       symtabend = (const ElfW(Sym) *) strtab;
-
-      const ElfW(Sym) *matchsym;
-      for (matchsym = NULL; (void *) symtab < (void *) symtabend; ++symtab)
-       if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
-            || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
-#if defined USE_TLS
-           && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
+       {
+         const ElfW(Sym) *symtabend;
+         if (match->l_info[DT_HASH] != NULL)
+           symtabend = (symtab
+                        + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
+         else
+           /* There is no direct way to determine the number of symbols in the
+              dynamic symbol table and no hash table is present.  The ELF
+              binary is ill-formed but what shall we do?  Use the beginning of
+              the string table which generally follows the symbol table.  */
+           symtabend = (const ElfW(Sym) *) strtab;
+
+         for (; (void *) symtab < (void *) symtabend; ++symtab)
+           if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
+                || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
+#ifdef USE_TLS
+               && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
 #endif
-           && symtab->st_shndx != SHN_UNDEF
-           && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
-           && symtab->st_name < strtabsize)
-         matchsym = (ElfW(Sym) *) symtab;
+               && symtab->st_shndx != SHN_UNDEF
+               && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
+               && symtab->st_name < strtabsize)
+             matchsym = (ElfW(Sym) *) symtab;
+       }
 
       if (mapp)
        *mapp = match;
index 4f4d358..fcc34f7 100644 (file)
@@ -1,5 +1,5 @@
 /* Determine whether the host has multiple processors.  Linux version.
-   Copyright (C) 1996, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996, 2002, 2004, 2006 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
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/sysctl.h>
-#include <not-cancel.h>
-
 /* Test whether the machine has more than one processor.  This is not the
    best test but good enough.  More complicated tests would require `malloc'
    which is not available at that time.  */
 static inline int
 is_smp_system (void)
 {
-  static const int sysctl_args[] = { CTL_KERN, KERN_VERSION };
-  char buf[512];
-  size_t reslen = sizeof (buf);
-
-  /* Try reading the number using `sysctl' first.  */
-  if (__sysctl ((int *) sysctl_args,
-               sizeof (sysctl_args) / sizeof (sysctl_args[0]),
-               buf, &reslen, NULL, 0) < 0)
-    {
-      /* This was not successful.  Now try reading the /proc filesystem.  */
-      int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
-      if (__builtin_expect (fd, 0) == -1
-         || (reslen = read_not_cancel (fd, buf, sizeof (buf))) <= 0)
-       /* This also didn't work.  We give up and say it's a UP machine.  */
-       buf[0] = '\0';
-
-      close_not_cancel_no_status (fd);
-    }
-
-  return strstr (buf, "SMP") != NULL;
+  /* Assume all machines are SMP and/or CMT and/or SMT.  */
+  return 1;
 }
index a9d9910..3b97ff0 100644 (file)
@@ -141,7 +141,7 @@ CFLAGS-pwrite.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-pwrite64.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sleep.c = -fexceptions
 CFLAGS-wait.c = -fexceptions -fasynchronous-unwind-tables
-CFLAGS-waitid.c = -fexceptions
+CFLAGS-waitid.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-waitpid.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-getopt.c = -fexceptions
 CFLAGS-wordexp.c = -fexceptions