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.
This commit is contained in:
Ulrich Drepper 2006-08-02 16:45:53 +00:00
parent 5632cd2060
commit 82ee37c510
4 changed files with 69 additions and 48 deletions

View file

@ -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

View 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]);
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 = 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];
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
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
&& symtab->st_shndx != SHN_UNDEF
&& DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
&& symtab->st_name < strtabsize)
matchsym = (ElfW(Sym) *) symtab;
&& 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
{
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;
}
if (mapp)
*mapp = match;

View 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
@ -17,36 +17,12 @@
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;
}

View 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