New spec file.

This commit is contained in:
Ulrich Drepper
2006-06-15 03:21:46 +00:00
parent 1b0714c81d
commit ee4b927bae
35 changed files with 215 additions and 1012 deletions
-5
View File
@@ -1,8 +1,3 @@
2006-07-05 Ulrich Drepper <drepper@redhat.com>
* configure.ac: Add dummy automake conditional to get dependencies
for non-generic linker right. See src/Makefile.am.
2005-11-18 Roland McGrath <roland@redhat.com>
* Makefile.am (DISTCHECK_CONFIGURE_FLAGS): New variable.
-11
View File
@@ -1,14 +1,3 @@
Version 0.122:
libebl:add function to test for relative relocation
elflint: fix and extend DT_RELCOUNT/DT_RELACOUNT checks
elflint, readelf: add support for DT_GNU_HASH
libelf: add elf_gnu_hash
elflint, readelf: add support for 64-bit SysV-style hash tables
Version 0.121:
libelf: bug fixes for rewriting existing files when using mmap.
+1 -12
View File
@@ -1,14 +1,3 @@
2006-07-05 Ulrich Drepper <drepper@redhat.com>
* alpha_init.c: Initialize sysvhash_entrysize.
* s390_init.c: Likewise.
2006-07-04 Ulrich Drepper <drepper@redhat.com>
* common-reloc.c (relative_reloc_p): New function.
(init_reloc): Hook it up.
* ia64_reloc.def: Define NO_RELATIVE_RELOC.
2006-06-13 Roland McGrath <roland@redhat.com>
* ppc64_retval.c: Remove SVR4_STRUCT_RETURN braino.
@@ -16,7 +5,7 @@
2006-06-12 Ulrich Drepper <drepper@redhat.com>
* common-reloc.c (none_reloc_p): New function.
(init_reloc): Hook it up.
(init_reloc): Hoop it up.
2006-02-22 Roland McGrath <roland@redhat.com>
+1 -2
View File
@@ -1,5 +1,5 @@
/* Initialization of Alpha specific backend library.
Copyright (C) 2002, 2005, 2006 Red Hat, Inc.
Copyright (C) 2002, 2005 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -54,7 +54,6 @@ alpha_init (elf, machine, eh, ehlen)
HOOK (eh, dynamic_tag_check);
HOOK (eh, reloc_simple_type);
HOOK (eh, return_value_location);
eh->sysvhash_entrysize = sizeof (Elf64_Xword);
return MODVERSION;
}
-11
View File
@@ -121,14 +121,6 @@ EBLHOOK(none_reloc_p) (int reloc)
return reloc == R_TYPE (NONE);
}
#ifndef NO_RELATIVE_RELOC
bool
EBLHOOK(relative_reloc_p) (int reloc)
{
return reloc == R_TYPE (RELATIVE);
}
#endif
static void
EBLHOOK(init_reloc) (Ebl *ebl)
{
@@ -137,7 +129,4 @@ EBLHOOK(init_reloc) (Ebl *ebl)
ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
ebl->none_reloc_p = EBLHOOK(none_reloc_p);
#ifndef NO_RELATIVE_RELOC
ebl->relative_reloc_p = EBLHOOK(relative_reloc_p);
#endif
}
+1 -3
View File
@@ -1,5 +1,5 @@
/* List the relocation types for ia64. -*- C -*-
Copyright (C) 2005, 2006 Red Hat, Inc.
Copyright (C) 2005 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -106,5 +106,3 @@ RELOC_TYPE (DTPREL32LSB, REL|EXEC|DYN)
RELOC_TYPE (DTPREL64MSB, REL|EXEC|DYN)
RELOC_TYPE (DTPREL64LSB, REL|EXEC|DYN)
RELOC_TYPE (LTOFF_DTPREL22, REL)
#define NO_RELATIVE_RELOC 1
-4
View File
@@ -53,9 +53,5 @@ s390_init (elf, machine, eh, ehlen)
HOOK (eh, register_name);
HOOK (eh, return_value_location);
/* Only the 64-bit format uses the incorrect hash table entry size. */
if (eh->class == ELFCLASS64)
eh->sysvhash_entrysize = sizeof (Elf64_Xword);
return MODVERSION;
}
+8 -5
View File
@@ -154,11 +154,14 @@ rm -rf ${RPM_BUILD_ROOT}
%{_libdir}/libelf.so
%changelog
* Sun May 28 2006 Ulrich Drepper <drepper@redhat.com> 0.121-1
- libelf: bug fixes for rewriting existing files when using mmap
- make all installed headers usable in C++ code
- readelf: better output format
- libdw, libdwfl: handle files without aranges info
* Wed Jun 14 2006 <drepper@redhat.com> 0.121-1
- libelf: bug fixes for rewriting existing files when using mmap.
- make all installed headers usable in C++ code.
- readelf: better output format.
- elflint: fix tests of dynamic section content.
- ld: Implement --as-needed, --execstack, PT_GNU_STACK. Many small patc
hes.
- libdw, libdwfl: handle files without aranges info.
* Tue Apr 4 2006 Ulrich Drepper <drepper@redhat.com> 0.120-1
- Bug fixes.
+2 -5
View File
@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script.
dnl Configure input file for elfutils. -*-autoconf-*-
dnl
dnl Copyright (C) 1996-2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
dnl Copyright (C) 1996-2002, 2003, 2004, 2005 Red Hat, Inc.
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software Foundation,
dnl Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
dnl
AC_INIT([Red Hat elfutils],[0.122],[http://bugzilla.redhat.com/bugzilla/],
AC_INIT([Red Hat elfutils],[0.121],[http://bugzilla.redhat.com/bugzilla/],
[elfutils])
AC_CONFIG_AUX_DIR([config])
@@ -108,9 +108,6 @@ dnl of files if at any time there is no such file, even if the filename
dnl would not be used.
AS_IF([test -z "$base_cpu"], [base_cpu=none])
AC_SUBST(base_cpu)
dnl Support to work around automake's inflexible dependency generation.
dnl See src/Makefile.am for more information.
AM_CONDITIONAL(NEVER, false)
dnl Enable debugging via mudflap. This option will cause most libraries
dnl to be built as archives which are statically linked into the applications.
-24
View File
@@ -1,27 +1,3 @@
2006-07-06 Ulrich Drepper <drepper@redhat.com>
* ebldynamictagname.c: Add support for DT_GNU_HASH.
* ebldynamictagcheck.c: Likewise.
* eblsectiontypename.c: Add support for SHT_GNU_HASH.
2006-07-05 Ulrich Drepper <drepper@redhat.com>
* Makefile.am (gen_SOURCES): Add eblsysvhashentrysize.c.
* libeblP.h (struct ebl): Add sysvhash_entrysize element.
* eblopenbackend.c (fill_defaults): Initialize sysvhash_entrysize.
* eblopenbackend.c (openbackend): If possible, fill machine, class,
and data values in from the ELF file.
2006-07-04 Ulrich Drepper <drepper@redhat.com>
* Makefile.am (gen_SOURCES): Add eblrelativerelocp.c.
* eblrelativerelocp.c: New file.
* ebl-hooks.c: Add relative_reloc_p.
* eblopenbackend.c (default_relative_reloc_p): New function.
(fill_defaults): Hook it up.
* libebl.h: Declare ebl_relative_reloc_p.
2006-06-12 Ulrich Drepper <drepper@redhat.com>
* Makefile.am (gen_SOURCES): Add eblnonerelocp.c.
+1 -2
View File
@@ -56,8 +56,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
eblgotpcreloccheck.c eblcopyrelocp.c eblsectionstripp.c \
eblelfclass.c eblelfdata.c eblelfmachine.c \
ebl_check_special_symbol.c eblbsspltp.c eblretval.c \
eblregname.c eblnonerelocp.c eblrelativerelocp.c \
eblsysvhashentrysize.c
eblregname.c eblnonerelocp.c
libebl_a_SOURCES = $(gen_SOURCES)
-3
View File
@@ -119,9 +119,6 @@ bool EBLHOOK(copy_reloc_p) (int);
/* Check whether given relocation is a no-op relocation. */
bool EBLHOOK(none_reloc_p) (int);
/* Check whether given relocation is a relative relocation. */
bool EBLHOOK(relative_reloc_p) (int);
/* Check whether given symbol's value is ok despite normal checks. */
bool EBLHOOK(check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *,
const char *, const GElf_Shdr *);
+2 -2
View File
@@ -1,5 +1,5 @@
/* Check dynamic tag.
Copyright (C) 2001, 2002, 2006 Red Hat, Inc.
Copyright (C) 2001, 2002 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -66,7 +66,7 @@ ebl_dynamic_tag_check (ebl, tag)
if (!res
&& ((tag >= 0 && tag < DT_NUM)
|| (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT)
|| (tag >= DT_GNU_HASH && tag <= DT_SYMINFO)
|| (tag >= DT_GNU_CONFLICT && tag <= DT_SYMINFO)
|| tag == DT_VERSYM
|| (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM)
|| tag == DT_AUXILIARY
+3 -4
View File
@@ -1,5 +1,5 @@
/* Return dynamic tag name.
Copyright (C) 2001, 2002, 2006 Red Hat, Inc.
Copyright (C) 2001, 2002 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -96,16 +96,15 @@ ebl_dynamic_tag_name (ebl, tag, buf, len)
res = valrntags[tag - DT_GNU_PRELINKED];
}
else if (tag >= DT_GNU_HASH && tag <= DT_SYMINFO)
else if (tag >= DT_GNU_CONFLICT && tag <= DT_SYMINFO)
{
static const char *addrrntags[] =
{
"GNU_HASH", "TLSDESC_PLT", "TLSDESC_DOT",
"GNU_CONFLICT", "GNU_LIBLIST", "CONFIG", "DEPAUDIT", "AUDIT",
"PLTPAD", "MOVETAB", "SYMINFO"
};
res = addrrntags[tag - DT_GNU_HASH];
res = addrrntags[tag - DT_GNU_CONFLICT];
}
else if (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM)
{
+1 -1
View File
@@ -1,4 +1,4 @@
/* Check whether given relocation is a no-op relocation.
/* Check whether given relocation is a copy relocation.
Copyright (C) 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+5 -28
View File
@@ -54,7 +54,7 @@
#include <assert.h>
#include <dlfcn.h>
#include <error.h>
#include <libelfP.h>
#include <gelf.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -89,7 +89,6 @@ static const struct
{ "sparc", "elf_sparcv9", "sparc", 5, EM_SPARCV9, 0, 0 },
{ "sparc", "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 },
{ "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 },
{ "s390", "ebl_s390", "s390", 4, EM_S390, 0, 0 },
{ "m32", "elf_m32", "m32", 3, EM_M32, 0, 0 },
{ "m68k", "elf_m68k", "m68k", 4, EM_68K, 0, 0 },
@@ -100,6 +99,7 @@ static const struct
{ "vpp500", "elf_vpp500", "vpp500", 5, EM_VPP500, 0, 0 },
{ "sparc", "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS, 0, 0 },
{ "i960", "elf_i960", "i960", 4, EM_960, 0, 0 },
{ "s390", "ebl_s390", "s390", 4, EM_S390, 0, 0 },
{ "v800", "ebl_v800", "v800", 4, EM_V800, 0, 0 },
{ "fr20", "ebl_fr20", "fr20", 4, EM_FR20, 0, 0 },
{ "rh32", "ebl_rh32", "rh32", 4, EM_RH32, 0, 0 },
@@ -191,7 +191,6 @@ static bool default_object_note (const char *name, uint32_t type,
static bool default_debugscn_p (const char *name);
static bool default_copy_reloc_p (int reloc);
static bool default_none_reloc_p (int reloc);
static bool default_relative_reloc_p (int reloc);
static bool default_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
const GElf_Sym *sym,
const char *name,
@@ -232,13 +231,11 @@ fill_defaults (Ebl *result)
result->debugscn_p = default_debugscn_p;
result->copy_reloc_p = default_copy_reloc_p;
result->none_reloc_p = default_none_reloc_p;
result->relative_reloc_p = default_relative_reloc_p;
result->check_special_symbol = default_check_special_symbol;
result->bss_plt_p = default_bss_plt_p;
result->return_value_location = default_return_value_location;
result->register_name = default_register_name;
result->destr = default_destr;
result->sysvhash_entrysize = sizeof (Elf32_Word);
}
@@ -283,28 +280,9 @@ openbackend (elf, emulation, machine)
/* Well, we know the emulation name now. */
result->emulation = machines[cnt].emulation;
/* We access some data structures directly. Make sure the 32 and
64 bit variants are laid out the same. */
assert (offsetof (Elf32_Ehdr, e_machine)
== offsetof (Elf64_Ehdr, e_machine));
assert (sizeof (((Elf32_Ehdr *) 0)->e_machine)
== sizeof (((Elf64_Ehdr *) 0)->e_machine));
assert (offsetof (Elf, state.elf32.ehdr)
== offsetof (Elf, state.elf64.ehdr));
/* Prefer taking the information from the ELF file. */
if (elf == NULL)
{
result->machine = machines[cnt].em;
result->class = machines[cnt].class;
result->data = machines[cnt].data;
}
else
{
result->machine = elf->state.elf32.ehdr->e_machine;
result->class = elf->state.elf32.ehdr->e_ident[EI_CLASS];
result->data = elf->state.elf32.ehdr->e_ident[EI_DATA];
}
result->machine = machines[cnt].em;
result->class = machines[cnt].class;
result->data = machines[cnt].data;
#ifndef LIBEBL_SUBDIR
# define LIBEBL_SUBDIR PACKAGE
@@ -630,7 +608,6 @@ default_copy_reloc_p (int reloc __attribute__ ((unused)))
return false;
}
strong_alias (default_copy_reloc_p, default_none_reloc_p)
strong_alias (default_copy_reloc_p, default_relative_reloc_p)
static bool
default_check_special_symbol (Elf *elf __attribute__ ((unused)),
-64
View File
@@ -1,64 +0,0 @@
/* Check whether given relocation is a relocation relocation.
Copyright (C) 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2006.
Red Hat elfutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the
Free Software Foundation; version 2 of the License.
Red Hat elfutils 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
General Public License for more details.
You should have received a copy of the GNU General Public License along
with Red Hat elfutils; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
In addition, as a special exception, Red Hat, Inc. gives You the
additional right to link the code of Red Hat elfutils with code licensed
under any Open Source Initiative certified open source license
(http://www.opensource.org/licenses/index.php) which requires the
distribution of source code with any binary distribution and to
distribute linked combinations of the two. Non-GPL Code permitted under
this exception must only link to the code of Red Hat elfutils through
those well defined interfaces identified in the file named EXCEPTION
found in the source code files (the "Approved Interfaces"). The files
of Non-GPL Code may instantiate templates or use macros or inline
functions from the Approved Interfaces without causing the resulting
work to be covered by the GNU General Public License. Only Red Hat,
Inc. may make changes or additions to the list of Approved Interfaces.
Red Hat's grant of this exception is conditioned upon your not adding
any new exceptions. If you wish to add a new Approved Interface or
exception, please contact Red Hat. You must obey the GNU General Public
License in all respects for all of the Red Hat elfutils code and other
code used in conjunction with Red Hat elfutils except the Non-GPL Code
covered by this exception. If you modify this file, you may extend this
exception to your version of the file, but you are not obligated to do
so. If you do not wish to provide this exception without modification,
you must delete this exception statement from your version and license
this file solely under the GPL without exception.
Red Hat elfutils is an included package of the Open Invention Network.
An included package of the Open Invention Network is a package for which
Open Invention Network licensees cross-license their patents. No patent
license is granted, either expressly or impliedly, by designation as an
included package. Should you wish to participate in the Open Invention
Network licensing program, please visit www.openinventionnetwork.com
<http://www.openinventionnetwork.com>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <libeblP.h>
bool
ebl_relative_reloc_p (ebl, reloc)
Ebl *ebl;
int reloc;
{
return ebl->relative_reloc_p (reloc);
}
+1 -3
View File
@@ -1,5 +1,5 @@
/* Return section type name.
Copyright (C) 2001, 2002, 2006 Red Hat, Inc.
Copyright (C) 2001, 2002 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -116,8 +116,6 @@ ebl_section_type_name (ebl, section, buf, len)
res = "CHECKSUM";
else if (section == SHT_GNU_LIBLIST)
res = "GNU_LIBLIST";
else if (section == SHT_GNU_HASH)
res = "GNU_HASH";
/* Handle OS-specific section names. */
else
{
-63
View File
@@ -1,63 +0,0 @@
/* Return OS ABI name
Copyright (C) 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2006.
Red Hat elfutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the
Free Software Foundation; version 2 of the License.
Red Hat elfutils 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
General Public License for more details.
You should have received a copy of the GNU General Public License along
with Red Hat elfutils; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
In addition, as a special exception, Red Hat, Inc. gives You the
additional right to link the code of Red Hat elfutils with code licensed
under any Open Source Initiative certified open source license
(http://www.opensource.org/licenses/index.php) which requires the
distribution of source code with any binary distribution and to
distribute linked combinations of the two. Non-GPL Code permitted under
this exception must only link to the code of Red Hat elfutils through
those well defined interfaces identified in the file named EXCEPTION
found in the source code files (the "Approved Interfaces"). The files
of Non-GPL Code may instantiate templates or use macros or inline
functions from the Approved Interfaces without causing the resulting
work to be covered by the GNU General Public License. Only Red Hat,
Inc. may make changes or additions to the list of Approved Interfaces.
Red Hat's grant of this exception is conditioned upon your not adding
any new exceptions. If you wish to add a new Approved Interface or
exception, please contact Red Hat. You must obey the GNU General Public
License in all respects for all of the Red Hat elfutils code and other
code used in conjunction with Red Hat elfutils except the Non-GPL Code
covered by this exception. If you modify this file, you may extend this
exception to your version of the file, but you are not obligated to do
so. If you do not wish to provide this exception without modification,
you must delete this exception statement from your version and license
this file solely under the GPL without exception.
Red Hat elfutils is an included package of the Open Invention Network.
An included package of the Open Invention Network is a package for which
Open Invention Network licensees cross-license their patents. No patent
license is granted, either expressly or impliedly, by designation as an
included package. Should you wish to participate in the Open Invention
Network licensing program, please visit www.openinventionnetwork.com
<http://www.openinventionnetwork.com>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <libeblP.h>
int
ebl_sysvhash_entrysize (ebl)
Ebl *ebl;
{
return ebl->sysvhash_entrysize;
}
-6
View File
@@ -192,9 +192,6 @@ extern bool ebl_copy_reloc_p (Ebl *ebl, int reloc);
/* Check whether given relocation is a no-op relocation. */
extern bool ebl_none_reloc_p (Ebl *ebl, int reloc);
/* Check whether given relocation is a relative relocation. */
extern bool ebl_relative_reloc_p (Ebl *ebl, int reloc);
/* Check whether section should be stripped. */
extern bool ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr,
const GElf_Shdr *shdr, const char *name,
@@ -203,9 +200,6 @@ extern bool ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr,
/* Check if backend uses a bss PLT in this file. */
extern bool ebl_bss_plt_p (Ebl *ebl, GElf_Ehdr *ehdr);
/* Return size of entry in SysV-style hash table. */
extern int ebl_sysvhash_entrysize (Ebl *ebl);
/* Return location expression to find return value given a
DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing
function itself (whose DW_AT_type attribute describes its return type).
+1 -5
View File
@@ -1,5 +1,5 @@
/* Internal definitions for interface for libebl.
Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc.
Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -77,9 +77,6 @@ struct ebl
# include "ebl-hooks.h"
# undef EBLHOOK
/* Size of entry in Sysv-style hash table. */
int sysvhash_entrysize;
/* Internal data. */
void *dlhandle;
};
@@ -90,7 +87,6 @@ typedef const char *(*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *, size_t);
/* gettext helper macros. */
#undef _
#define _(Str) dgettext ("elfutils", Str)
#endif /* libeblP.h */
-7
View File
@@ -1,10 +1,3 @@
2006-07-06 Ulrich Drepper <drepper@redhat.com>
* elf_gnu_hash.c: New file.
* libelf.h: Declare elf_gnu_hash.
* Makefile.am (libelf_a_SOURCES): Add elf_gnu_hash.
* libelf.map: Add elf_gnu_map for version ELFUTILS_1.2.
2006-05-28 Ulrich Drepper <drepper@redhat.com>
* elf32_updatefile.c (updatemmap): Preserve section content if
+2 -3
View File
@@ -1,6 +1,6 @@
## Process this file with automake to create Makefile.in
##
## Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
## Copyright (C) 1996-2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
## This file is part of Red Hat elfutils.
##
## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -96,8 +96,7 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
elf_clone.c \
gelf_getlib.c gelf_update_lib.c \
elf32_offscn.c elf64_offscn.c gelf_offscn.c \
elf_getaroff.c \
elf_gnu_hash.c
elf_getaroff.c
if !MUDFLAP
libelf_pic_a_SOURCES =
+1 -5
View File
@@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros.
Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Copyright (C) 1995-2003, 2004, 2005 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
@@ -330,7 +330,6 @@ typedef struct
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* Number of defined types. */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_GNU_HASH 0x6ffffff6 /* GNU style symbol hash table. */
#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
@@ -700,9 +699,6 @@ typedef struct
If any adjustment is made to the ELF object after it has been
built these entries will need to be adjusted. */
#define DT_ADDRRNGLO 0x6ffffe00
#define DT_GNU_HASH 0x6ffffef5 /* Address of GNU symbol hash table */
#define DT_TLSDESC_PLT 0x6ffffef6
#define DT_TLSDESC_GOT 0x6ffffef7
#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
#define DT_CONFIG 0x6ffffefa /* Configuration information. */
-68
View File
@@ -1,68 +0,0 @@
/* GNU-style Hash function used in ELF implementations.
Copyright (C) 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
Red Hat elfutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the
Free Software Foundation; version 2 of the License.
Red Hat elfutils 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
General Public License for more details.
You should have received a copy of the GNU General Public License along
with Red Hat elfutils; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
In addition, as a special exception, Red Hat, Inc. gives You the
additional right to link the code of Red Hat elfutils with code licensed
under any Open Source Initiative certified open source license
(http://www.opensource.org/licenses/index.php) which requires the
distribution of source code with any binary distribution and to
distribute linked combinations of the two. Non-GPL Code permitted under
this exception must only link to the code of Red Hat elfutils through
those well defined interfaces identified in the file named EXCEPTION
found in the source code files (the "Approved Interfaces"). The files
of Non-GPL Code may instantiate templates or use macros or inline
functions from the Approved Interfaces without causing the resulting
work to be covered by the GNU General Public License. Only Red Hat,
Inc. may make changes or additions to the list of Approved Interfaces.
Red Hat's grant of this exception is conditioned upon your not adding
any new exceptions. If you wish to add a new Approved Interface or
exception, please contact Red Hat. You must obey the GNU General Public
License in all respects for all of the Red Hat elfutils code and other
code used in conjunction with Red Hat elfutils except the Non-GPL Code
covered by this exception. If you modify this file, you may extend this
exception to your version of the file, but you are not obligated to do
so. If you do not wish to provide this exception without modification,
you must delete this exception statement from your version and license
this file solely under the GPL without exception.
Red Hat elfutils is an included package of the Open Invention Network.
An included package of the Open Invention Network is a package for which
Open Invention Network licensees cross-license their patents. No patent
license is granted, either expressly or impliedly, by designation as an
included package. Should you wish to participate in the Open Invention
Network licensing program, please visit www.openinventionnetwork.com
<http://www.openinventionnetwork.com>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <libelfP.h>
/* Get the implementation. */
#include <dl-hash.h>
unsigned long int
elf_gnu_hash (string)
const char *string;
{
uint_fast32_t h = 5381;
for (unsigned char c = *string; c != '\0'; c = *++string)
h = h * 33 + c;
return h & 0xffffffff;
}
+1 -5
View File
@@ -1,5 +1,5 @@
/* Interface for libelf.
Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2006 Red Hat, Inc.
Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -371,10 +371,6 @@ extern void elf_fill (int __fill);
extern unsigned long int elf_hash (const char *__string)
__attribute__ ((__pure__));
/* Compute hash value using the GNU-specific hash function. */
extern unsigned long int elf_gnu_hash (const char *__string)
__attribute__ ((__pure__));
/* Compute simple checksum from permanent parts of the ELF file. */
extern long int elf32_checksum (Elf *__elf);
-5
View File
@@ -112,8 +112,3 @@ ELFUTILS_1.1.1 {
gelf_offscn;
elf_getaroff;
} ELFUTILS_1.1;
ELFUTILS_1.2 {
global:
elf_gnu_hash;
} ELFUTILS_1.1.1;
-42
View File
@@ -1,45 +1,3 @@
2006-07-06 Ulrich Drepper <drepper@redhat.com>
* elflint.c: Adjust for latest new hash table format.
* readelf.c: Likewise.
* elflint.c (check_versym): Ignore hidden bit when comparing version
numbers.
2006-07-05 Ulrich Drepper <drepper@redhat.com>
* ldgeneric.c (ld_generic_create_outfile): Correctly recognize
discarded COMDAT symbols.
* i386_ld.c (elf_i386_count_relocations): Lot of corrections.
(elf_i386_create_relocations): Likewise.
* ld.h (struct symbol): Add local and hidden bits.
* ld.c (create_special_section_symbol): These synthsized symbols
are local and hidden.
* ldgeneric.c (file_process2): Check whether input file matches
the emulation.
(fillin_special_symbol): Create symbols as local and/or hidden
if requested.
(ld_generic_create_outfile): Make local copy of symbol.
Don't hide global, defined symbols in dynamic symbol table unless
requested. Synthetic symbols have no version information.
* elflint.c: Add support for checking 64-bit SysV-style hash tables.
* readelf.c: Add support for printing 64-bit SysV-style hash tables.
2006-07-04 Ulrich Drepper <drepper@redhat.com>
* elflint.c (is_rel_dyn): Fix and extend DT_RELCOUNT/DT_RELACOUNT
testing.
2006-07-03 Ulrich Drepper <drepper@redhat.com>
* elflint.c: Add testing of DT_GNU_HASH.
* readelf.c: Implement showing histogram for DT_GNU_HASH section.
* Makefile.am: Add hacks to create dependency files for non-generic
linker.
2006-06-12 Ulrich Drepper <drepper@redhat.com>
* ldgeneric.c (ld_generic_generate_sections): Don't create .interp
+2 -11
View File
@@ -63,12 +63,6 @@ else
noinst_LIBRARIES = libld_elf.a $(ld_dsos)
noinst_PROGRAMS = $(ld_dsos:_pic.a=.so)
endif
if NEVER
# We never build this library but we need to get the dependency files
# of all the linker backends that might be used in a non-generic linker.
noinst_LIBRARIES += libdummy.a
libdummy_a_SOURCES = i386_ld.c
endif
textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
@@ -108,7 +102,6 @@ size_LDADD = $(libelf) $(libeu) $(libmudflap)
strip_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
ld_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
if NATIVE_LD
# -ldl is always needed for libebl.
ld_LDADD += libld_elf.a
endif
ld_LDFLAGS = -rdynamic
@@ -124,10 +117,9 @@ ldlex.o: ldscript.c
ldlex_no_Werror = yes
ldscript.h: ldscript.c
if NATIVE_LD
# Machine-specific linker code.
libld_elf_a_SOURCES := $(base_cpu)_ld.c
else
libld_elf_a_SOURCES = $(base_cpu)_ld.c
libld_elf_i386_pic_a_SOURCES =
am_libld_elf_i386_pic_a_OBJECTS = i386_ld.os
@@ -137,7 +129,6 @@ libld_elf_i386.so: libld_elf_i386_pic.a libld_elf_i386.map
$(libelf) $(libeu) \
-Wl,--version-script,$(srcdir)/libld_elf_i386.map
$(textrel_check)
endif
%.os: %.c %.o
+40 -308
View File
@@ -951,14 +951,14 @@ section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segm
static bool
is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
bool is_rela)
bool rela)
{
/* If this is no executable or DSO it cannot be a .rel.dyn section. */
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
return false;
/* Check the section name. Unfortunately necessary. */
if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn"))
if (strcmp (section_name (ebl, idx), rela ? ".rela.dyn" : ".rel.dyn"))
return false;
/* When a .rel.dyn section is used a DT_RELCOUNT dynamic section
@@ -984,106 +984,14 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
if (dyn->d_tag == DT_RELCOUNT)
{
/* Found it. Does the type match. */
if (is_rela)
/* Found it. One last check: does the number
specified number of relative relocations exceed
the total number of relocations? */
if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
ERROR (gettext ("\
section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"),
idx, section_name (ebl, idx));
else
{
/* Does the number specified number of relative
relocations exceed the total number of
relocations? */
if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
ERROR (gettext ("\
section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
idx, section_name (ebl, idx),
(int) dyn->d_un.d_val);
/* Make sure the specified number of relocations are
relative. */
Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
idx), NULL);
if (reldata != NULL)
for (size_t inner = 0;
inner < shdr->sh_size / shdr->sh_entsize;
++inner)
{
GElf_Rel rel_mem;
GElf_Rel *rel = gelf_getrel (reldata, inner,
&rel_mem);
if (rel == NULL)
/* The problem will be reported elsewhere. */
break;
if (ebl_relative_reloc_p (ebl,
GELF_R_TYPE (rel->r_info)))
{
if (inner >= dyn->d_un.d_val)
ERROR (gettext ("\
section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
idx, section_name (ebl, idx),
(int) dyn->d_un.d_val);
}
else if (inner < dyn->d_un.d_val)
ERROR (gettext ("\
section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
idx, section_name (ebl, idx),
inner, (int) dyn->d_un.d_val);
}
}
}
if (dyn->d_tag == DT_RELACOUNT)
{
/* Found it. Does the type match. */
if (!is_rela)
ERROR (gettext ("\
section [%2d] '%s': DT_RELACOUNT used for this REL section\n"),
idx, section_name (ebl, idx));
else
{
/* Does the number specified number of relative
relocations exceed the total number of
relocations? */
if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
ERROR (gettext ("\
section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
idx, section_name (ebl, idx),
(int) dyn->d_un.d_val);
/* Make sure the specified number of relocations are
relative. */
Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
idx), NULL);
if (reldata != NULL)
for (size_t inner = 0;
inner < shdr->sh_size / shdr->sh_entsize;
++inner)
{
GElf_Rela rela_mem;
GElf_Rela *rela = gelf_getrela (reldata, inner,
&rela_mem);
if (rela == NULL)
/* The problem will be reported elsewhere. */
break;
if (ebl_relative_reloc_p (ebl,
GELF_R_TYPE (rela->r_info)))
{
if (inner >= dyn->d_un.d_val)
ERROR (gettext ("\
section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
idx, section_name (ebl, idx),
(int) dyn->d_un.d_val);
}
else if (inner < dyn->d_un.d_val)
ERROR (gettext ("\
section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
idx, section_name (ebl, idx),
inner, (int) dyn->d_un.d_val);
}
}
idx, section_name (ebl, idx),
(int) dyn->d_un.d_val);
}
}
@@ -1810,194 +1718,7 @@ extended section index is %" PRIu32 " but symbol index is not XINDEX\n"),
static void
check_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
GElf_Shdr *symshdr)
{
Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize)
ERROR (gettext ("\
section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
idx, section_name (ebl, idx), (long int) shdr->sh_size,
(long int) ((2 + nbucket + nchain) * shdr->sh_entsize));
size_t maxidx = nchain;
if (symshdr != NULL)
{
size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
if (nchain > symshdr->sh_size / symshdr->sh_entsize)
ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
idx, section_name (ebl, idx));
maxidx = symsize;
}
size_t cnt;
for (cnt = 2; cnt < 2 + nbucket; ++cnt)
if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx)
ERROR (gettext ("\
section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt - 2);
for (; cnt < 2 + nbucket + nchain; ++cnt)
if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx)
ERROR (gettext ("\
section [%2d] '%s': hash chain reference %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt - 2 - nbucket);
}
static void
check_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
GElf_Shdr *symshdr)
{
Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize)
ERROR (gettext ("\
section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
idx, section_name (ebl, idx), (long int) shdr->sh_size,
(long int) ((2 + nbucket + nchain) * shdr->sh_entsize));
size_t maxidx = nchain;
if (symshdr != NULL)
{
size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
if (nchain > symshdr->sh_size / symshdr->sh_entsize)
ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
idx, section_name (ebl, idx));
maxidx = symsize;
}
size_t cnt;
for (cnt = 2; cnt < 2 + nbucket; ++cnt)
if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx)
ERROR (gettext ("\
section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt - 2);
for (; cnt < 2 + nbucket + nchain; ++cnt)
if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx)
ERROR (gettext ("\
section [%2d] '%s': hash chain reference %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt - 2 - nbucket);
}
static void
check_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
GElf_Shdr *symshdr)
{
Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0];
Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
if (shdr->sh_size < (2 + 2 * nbuckets) * sizeof (Elf32_Word))
{
ERROR (gettext ("\
section [%2d] '%s': hash table section is too small (is %ld, expected at least%ld)\n"),
idx, section_name (ebl, idx), (long int) shdr->sh_size,
(long int) ((2 + 2 * nbuckets) * sizeof (Elf32_Word)));
return;
}
size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (2 + 2 * nbuckets);
if (symshdr != NULL)
maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize);
/* We need the symbol section data. */
Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL);
size_t cnt;
for (cnt = 2; cnt < 2 + 2 * nbuckets; cnt += 2)
{
Elf32_Word bitset = ((Elf32_Word *) data->d_buf)[cnt];
Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt + 1];
if (symidx == 0)
{
/* Nothing in here. No bit in the bitset should be set either. */
if (bitset != 0)
ERROR (gettext ("\
section [%2d] '%s': hash chain for bucket %zu empty but bitset is not\n"),
idx, section_name (ebl, idx), cnt / 2 - 1);
continue;
}
if (symidx < symbias)
{
ERROR (gettext ("\
section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"),
idx, section_name (ebl, idx), cnt / 2 - 1);
continue;
}
Elf32_Word collected_bitset = 0;
while (symidx - symbias < maxidx)
{
Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[2 + 2 * nbuckets
+ symidx
- symbias];
if (symdata != NULL)
{
/* Check that the referenced symbol is not undefined. */
GElf_Sym sym_mem;
GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem);
if (sym != NULL && sym->st_shndx == SHN_UNDEF)
ERROR (gettext ("\
section [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"),
idx, section_name (ebl, idx), symidx, cnt / 2 - 1);
const char *symname = elf_strptr (ebl->elf, symshdr->sh_link,
sym->st_name);
if (symname != NULL)
{
Elf32_Word hval = elf_gnu_hash (symname);
if ((hval & ~1u) != (chainhash & ~1u))
ERROR (gettext ("\
section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"),
idx, section_name (ebl, idx), symidx, cnt / 2 - 1);
}
}
collected_bitset |= 1 << ((chainhash >> 5) & 31);
if ((chainhash & 1) != 0)
break;
++symidx;
}
if (symidx - symbias >= maxidx)
ERROR (gettext ("\
section [%2d] '%s': hash chain for bucket %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt / 2 - 1);
else if (symshdr != NULL
&& symidx > symshdr->sh_size / symshdr->sh_entsize)
ERROR (gettext ("\
section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt / 2 - 1);
if (bitset != collected_bitset)
ERROR (gettext ("\
section [%2d] '%s': bitset for bucket %zu does not match chain entries: computed %#x, reported %#x\n"),
idx, section_name (ebl, idx), cnt / 2 - 1,
collected_bitset, bitset);
}
}
static void
check_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
check_hash (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
if (ehdr->e_type == ET_REL)
{
@@ -2023,11 +1744,9 @@ section [%2d] '%s': relocatable files cannot have hash tables\n"),
section [%2d] '%s': hash table not for dynamic symbol table\n"),
idx, section_name (ebl, idx));
if (shdr->sh_entsize != (tag == SHT_GNU_HASH
? sizeof (Elf32_Word)
: (size_t) ebl_sysvhash_entrysize (ebl)))
if (shdr->sh_entsize != sizeof (Elf32_Word))
ERROR (gettext ("\
section [%2d] '%s': hash table entry size incorrect\n"),
section [%2d] '%s': entry size does not match Elf32_Word\n"),
idx, section_name (ebl, idx));
if ((shdr->sh_flags & SHF_ALLOC) == 0)
@@ -2037,26 +1756,40 @@ section [%2d] '%s': hash table entry size incorrect\n"),
if (shdr->sh_size < 2 * shdr->sh_entsize)
{
ERROR (gettext ("\
section [%2d] '%s': hash table has not even room for initial two administrative entries\n"),
section [%2d] '%s': hash table has not even room for nbucket and nchain\n"),
idx, section_name (ebl, idx));
return;
}
switch (tag)
Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize)
ERROR (gettext ("\
section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
idx, section_name (ebl, idx), (long int) shdr->sh_size,
(long int) ((2 + nbucket + nchain) * shdr->sh_entsize));
if (symshdr != NULL)
{
case SHT_HASH:
if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
check_sysv_hash64 (ebl, shdr, data, idx, symshdr);
else
check_sysv_hash (ebl, shdr, data, idx, symshdr);
break;
size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
size_t cnt;
case SHT_GNU_HASH:
check_gnu_hash (ebl, shdr, data, idx, symshdr);
break;
if (nchain < symshdr->sh_size / symshdr->sh_entsize)
ERROR (gettext ("section [%2d] '%s': chain array not large enough\n"),
idx, section_name (ebl, idx));
default:
assert (! "should not happen");
for (cnt = 2; cnt < 2 + nbucket; ++cnt)
if (((Elf32_Word *) data->d_buf)[cnt] >= symsize)
ERROR (gettext ("\
section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt - 2);
for (; cnt < 2 + nbucket + nchain; ++cnt)
if (((Elf32_Word *) data->d_buf)[cnt] >= symsize)
ERROR (gettext ("\
section [%2d] '%s': hash chain reference %zu out of bounds\n"),
idx, section_name (ebl, idx), cnt - 2 - nbucket);
}
}
@@ -2445,7 +2178,7 @@ section [%2d] '%s': symbol %d: local symbol with version\n"),
index we need for this symbol. */
struct version_namelist *runp = version_namelist;
while (runp != NULL)
if (runp->ndx == (*versym & 0x7fff))
if (runp->ndx == *versym)
break;
else
runp = runp->next;
@@ -3212,8 +2945,7 @@ section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
break;
case SHT_HASH:
case SHT_GNU_HASH:
check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt);
check_hash (ebl, ehdr, shdr, cnt);
break;
case SHT_NULL:
+17 -23
View File
@@ -72,7 +72,7 @@ elf_i386_relocate_section (struct ld_state *statep __attribute__ ((unused)),
Elf_Data *data;
/* Iterate over all the input sections. Appropriate data buffers in the
output sections were already created. */
output sections were already created. I get them iteratively, too. */
runp = firstp;
data = NULL;
do
@@ -149,8 +149,8 @@ elf_i386_relocate_section (struct ld_state *statep __attribute__ ((unused)),
assert (xndx < SHN_LORESERVE || xndx > SHN_HIRESERVE);
/* We fortunately don't have to do much. The relocations
mostly get only updates of the offset. Only for a
relocation referring to a section do we have to do
mostly get only updates of the offset. Only is a
relocation referred to a section do we have to do
something. In this case the reference to the sections
has no direct equivalent since the part the input section
contributes need not start at the same offset as in the
@@ -159,13 +159,15 @@ elf_i386_relocate_section (struct ld_state *statep __attribute__ ((unused)),
itself. */
if (XELF_ST_TYPE (sym->st_info) == STT_SECTION)
{
/* We expect here only R_386_32 relocations. */
Elf32_Word toadd;
/* We expect here on R_386_32 relocations. */
assert (XELF_R_TYPE (rel->r_info) == R_386_32);
/* Avoid writing to the section memory if this is
effectively a no-op since it might save a
copy-on-write operation. */
Elf32_Word toadd = file->scninfo[xndx].offset;
toadd = file->scninfo[xndx].offset;
if (toadd != 0)
add_4ubyte_unaligned (reltgtdata->d_buf + rel->r_offset,
toadd);
@@ -525,15 +527,13 @@ elf_i386_count_relocations (struct ld_state *statep, struct scninfo *scninfo)
/* Symbols in COMDAT group sections which are discarded do
not have to be relocated. */
if (r_sym >= scninfo->fileinfo->nlocalsymbols
&& unlikely (scninfo->fileinfo->symref[r_sym] == NULL))
if (unlikely (scninfo->fileinfo->symref[r_sym] == NULL))
continue;
switch (XELF_R_TYPE (rel->r_info))
{
case R_386_GOT32:
if (! scninfo->fileinfo->symref[r_sym]->defined
|| scninfo->fileinfo->symref[r_sym]->in_dso)
if (! scninfo->fileinfo->symref[r_sym]->defined)
relsize += sizeof (Elf32_Rel);
/* This relocation is not emitted in the output file but
@@ -556,8 +556,6 @@ elf_i386_count_relocations (struct ld_state *statep, struct scninfo *scninfo)
if (statep->file_type == dso_file_type)
{
relsize += sizeof (Elf32_Rel);
// XXX Do we have to check whether the target
// XXX section is read-only first?
statep->dt_flags |= DF_TEXTREL;
}
else
@@ -577,9 +575,10 @@ elf_i386_count_relocations (struct ld_state *statep, struct scninfo *scninfo)
}
}
else if (statep->file_type == dso_file_type
&& r_sym >= SCNINFO_SHDR (scninfo->fileinfo->scninfo[shdr->sh_link].shdr).sh_info
&& scninfo->fileinfo->symref[r_sym]->outdynsymidx != 0
&& XELF_R_TYPE (rel->r_info) == R_386_32)
relsize += sizeof (Elf32_Rel);
break;
case R_386_PLT32:
@@ -703,7 +702,8 @@ elf_i386_create_relocations (struct ld_state *statep,
/* Cache the access to the symbol table data. */
Elf_Data *symdata = elf_getdata (scninfo[rshdr->sh_link].scn, NULL);
for (int cnt = 0; cnt < nrels; ++cnt)
int cnt;
for (cnt = 0; cnt < nrels; ++cnt)
{
XElf_Rel_vardef (rel);
XElf_Rel *rel2;
@@ -812,7 +812,8 @@ elf_i386_create_relocations (struct ld_state *statep,
}
}
else if (statep->file_type == dso_file_type
&& XELF_R_TYPE (rel->r_info) == R_386_32)
&& idx >= SCNINFO_SHDR (scninfo[rshdr->sh_link].shdr).sh_info
&& symref[idx]->outdynsymidx != 0)
{
#if NATIVE_ELF != 0
xelf_getrel_ptr (reldyndata, nreldyn, rel2);
@@ -820,15 +821,8 @@ elf_i386_create_relocations (struct ld_state *statep,
rel2 = &rel_mem;
#endif
rel2->r_offset = value;
/* For symbols we do not export we generate a relative
relocation. */
if (idx < SCNINFO_SHDR (scninfo[rshdr->sh_link].shdr).sh_info
|| symref[idx]->outdynsymidx == 0)
rel2->r_info = XELF_R_INFO (0, R_386_RELATIVE);
else
rel2->r_info
= XELF_R_INFO (symref[idx]->outdynsymidx, R_386_32);
rel2->r_info
= XELF_R_INFO (symref[idx]->outdynsymidx, R_386_32);
(void) xelf_update_rel (reldyndata, nreldyn, rel2);
++nreldyn;
-2
View File
@@ -1519,8 +1519,6 @@ create_special_section_symbol (struct symbol **symp, const char *name)
abort ();
(*symp)->defined = 1;
(*symp)->local = 1;
(*symp)->hidden = 1;
(*symp)->type = STT_OBJECT;
++ld_state.nsymtab;
+1 -3
View File
@@ -446,8 +446,6 @@ struct symbol
unsigned int weak:1;
unsigned int added:1;
unsigned int merged:1;
unsigned int local:1;
unsigned int hidden:1;
/* Nonzero if the symbol is on the from_dso list. */
unsigned int on_dsolist:1;
/* Nonzero if symbol needs copy relocation, reset when the
@@ -963,7 +961,7 @@ struct ld_state
/* Execuatable stack selection. */
enum execstack
{
execstack_false = 0,
execstack_false = 0,
execstack_true,
execstack_false_force
} execstack;
+33 -71
View File
@@ -1008,7 +1008,7 @@ add_section (struct usedfiles *fileinfo, struct scninfo *scninfo)
= find_section_group (runp->fileinfo,
elf_ndxscn (runp->scn),
&grpscndata);
if (strcmp (grpscn->symbols->name,
grpscn2->symbols->name) == 0)
{
@@ -1436,9 +1436,9 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
_GLOBAL_OFFSET_TABLE_, _DYNAMIC. */
// XXX This loop is hot and the following tests hardly ever match.
// XXX Maybe move the tests somewhere they are executed less often.
if (((unlikely (hval == 165832675ul)
if (((unlikely (hval == 165832675)
&& strcmp (search.name, "_DYNAMIC") == 0)
|| (unlikely (hval == 102264335ul)
|| (unlikely (hval == 102264335)
&& strcmp (search.name, "_GLOBAL_OFFSET_TABLE_") == 0))
&& sym->st_shndx != SHN_UNDEF
/* If somebody defines such a variable in a relocatable we
@@ -1451,7 +1451,7 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
struct symbol *newp;
if (likely (oldp == NULL))
{
/* No symbol of this name known. Add it. */
/* No symbol of this name know. Add it. */
newp = (struct symbol *) obstack_alloc (&ld_state.smem,
sizeof (*newp));
newp->name = search.name;
@@ -1467,8 +1467,6 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
newp->weak = XELF_ST_BIND (sym->st_info) == STB_WEAK;
newp->added = 0;
newp->merged = 0;
newp->local = 0;
newp->hidden = 0;
newp->need_copy = 0;
newp->on_dsolist = 0;
newp->in_dso = secttype == SHT_DYNSYM;
@@ -1934,18 +1932,6 @@ file_process2 (struct usedfiles *fileinfo)
return 1;
}
/* Make sure the file type matches the backend. */
if (FILEINFO_EHDR (fileinfo->ehdr).e_machine
!= ebl_get_elfmachine (ld_state.ebl))
{
fprintf (stderr, gettext ("\
%s: input file incompatible with ELF machine type %s\n"),
fileinfo->rfname,
ebl_backend_name (ld_state.ebl));
fileinfo->status = closed;
return 1;
}
/* Determine the section header string table section index. */
if (unlikely (elf_getshstrndx (fileinfo->elf, &fileinfo->shstrndx)
< 0))
@@ -2549,7 +2535,7 @@ ld_generic_open_outfile (struct ld_state *statep, int machine, int klass,
{
strcpy (mempcpy (tempfname, ld_state.outfname, outfname_len), ".XXXXXX");
/* The use of mktemp() here is fine. We do not want to use
/* The useof mktemp() here is fine. We do not want to use
mkstemp() since then the umask isn't used. And the output
file will have these permissions anyhow. Any intruder could
change the file later if it would be possible now. */
@@ -3256,7 +3242,7 @@ reduce_symbol_p (XElf_Sym *sym, struct Ebl_Strent *strent)
{
search.id = strndupa (str, version - str);
if (*++version == VER_CHR)
/* Skip the second '@' signaling a default definition. */
/* Skip the second '@' signalling a default definition. */
++version;
}
else
@@ -3574,9 +3560,9 @@ fillin_special_symbol (struct symbol *symst, size_t scnidx, size_t nsym,
/* The name offset will be filled in later. */
sym->st_name = 0;
/* Traditionally: globally visible. */
sym->st_info = XELF_ST_INFO (symst->local ? STB_LOCAL : STB_GLOBAL,
symst->type);
sym->st_other = symst->hidden ? STV_HIDDEN : STV_DEFAULT;
sym->st_info = XELF_ST_INFO (STB_GLOBAL, symst->type);
/* No special visibility or so. */
sym->st_other = 0;
/* Reference to the GOT or dynamic section. Since the GOT and
dynamic section are only created for executables and DSOs it
cannot be that the section index is too large. */
@@ -3733,7 +3719,7 @@ create_verneed_data (XElf_Off offset, Elf_Data *verneeddata,
For executables (shared or not) we have to create the program header,
additional sections like the .interp, eventually (in addition) create
a dynamic symbol table and a dynamic section. Also the relocations
have to be processed differently. */
have to be processed differently. */
static int
ld_generic_create_outfile (struct ld_state *statep)
{
@@ -4601,7 +4587,6 @@ ld_generic_create_outfile (struct ld_state *statep)
file = ld_state.relfiles->next;
symdata = elf_getdata (elf_getscn (ld_state.outelf, ld_state.symscnidx),
NULL);
do
{
size_t maxcnt;
@@ -4660,11 +4645,11 @@ ld_generic_create_outfile (struct ld_state *statep)
continue;
#if NATIVE_ELF != 0
/* Copy old data. We create a temporary copy because the
symbol might still be discarded. */
XElf_Sym sym_mem;
sym_mem = *sym;
sym = &sym_mem;
/* Copy old data. */
XElf_Sym *sym2 = sym;
assert (nsym < nsym_allocated);
xelf_getsym (symdata, nsym, sym);
*sym = *sym2;
#endif
if (sym->st_shndx != SHN_UNDEF
@@ -4769,7 +4754,6 @@ section index too large in dynamic symbol table"));
/* Once we know the name this field will get the correct
offset. For now set it to zero which means no name
associated. */
GElf_Word st_name = sym->st_name;
sym->st_name = 0;
/* If we had to merge sections we have a completely new
@@ -4780,50 +4764,30 @@ section index too large in dynamic symbol table"));
/* Create the record in the output sections. */
assert (nsym < nsym_allocated);
xelf_update_symshndx (symdata, xndxdata, nsym, sym, xndx, 1);
xelf_update_symshndx (symdata, xndxdata, nsym, sym, xndx, 0);
/* Add the reference to the symbol record in case we need it.
Find the symbol if this has not happened yet. We do
not need the information for local symbols. */
if (defp == NULL && cnt >= file->nlocalsymbols)
{
defp = file->symref[cnt];
defp = file->symref[cnt];
if (defp == NULL)
/* Ignore symbols in discarded COMDAT group sections. */
if (defp != NULL)
{
/* Store the reference to the symbol record. The
sorting code will have to keep this array in the
correct order, too. */
ndxtosym[nsym] = defp;
/* One more entry finished. */
if (cnt >= file->nlocalsymbols)
{
/* This is a symbol in a discarded COMDAT section.
Find the definition we actually use. */
// XXX The question is: do we have to do this here
// XXX or can we do it earlier when we discard the
// XXX section.
struct symbol search;
search.name = elf_strptr (file->elf, file->symstridx,
st_name);
struct symbol *realp
= ld_symbol_tab_find (&ld_state.symbol_tab,
elf_hash (search.name), &search);
if (realp == NULL)
// XXX What to do here?
error (EXIT_FAILURE, 0,
"couldn't find symbol from COMDAT section");
file->symref[cnt] = realp;
continue;
assert (file->symref[cnt]->outsymidx == 0);
file->symref[cnt]->outsymidx = nsym;
}
file->symindirect[cnt] = nsym++;
}
/* Store the reference to the symbol record. The sorting
code will have to keep this array in the correct order, too. */
ndxtosym[nsym] = defp;
/* One more entry finished. */
if (cnt >= file->nlocalsymbols)
{
assert (file->symref[cnt]->outsymidx == 0);
file->symref[cnt]->outsymidx = nsym;
}
file->symindirect[cnt] = nsym++;
}
}
while ((file = file->next) != ld_state.relfiles->next);
@@ -4831,6 +4795,7 @@ section index too large in dynamic symbol table"));
nothing. */
assert (xndxdata == NULL || need_xndx);
/* Create the version related sections. */
if (ld_state.verneedscnidx != 0)
{
@@ -5263,8 +5228,7 @@ section index too large in dynamic symbol table"));
if (XELF_ST_TYPE (sym->st_info) == STT_FILE
|| XELF_ST_VISIBILITY (sym->st_other) == STV_INTERNAL
|| XELF_ST_VISIBILITY (sym->st_other) == STV_HIDDEN
|| (!ld_state.export_all_dynamic
&& !ndxtosym[cnt]->in_dso && ndxtosym[cnt]->defined))
|| (!ndxtosym[cnt]->in_dso && ndxtosym[cnt]->defined))
{
symstrent[cnt] = NULL;
continue;
@@ -5287,9 +5251,7 @@ section index too large in dynamic symbol table"));
{
struct symbol *symp = ndxtosym[cnt];
/* Synthetic symbols (i.e., those with no file attached)
have no version information. */
if (symp->file != NULL && symp->file->verdefdata != NULL)
if (symp->file->verdefdata != NULL)
{
GElf_Versym versym;
+91 -196
View File
@@ -2320,194 +2320,6 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
}
static void
print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
uint_fast32_t maxlength, Elf32_Word nbucket,
uint_fast32_t nsyms, uint32_t *lengths)
{
uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
++counts[lengths[cnt]];
GElf_Shdr glink;
printf (ngettext ("\
\nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
\nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
nbucket),
(unsigned int) elf_ndxscn (scn),
elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
(int) nbucket,
gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
shdr->sh_addr,
shdr->sh_offset,
(unsigned int) shdr->sh_link,
elf_strptr (ebl->elf, shstrndx,
gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
&glink)->sh_name));
if (nbucket > 0)
{
uint64_t success = 0;
fputs_unlocked (gettext ("\
Length Number % of total Coverage\n"), stdout);
printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
counts[0], (counts[0] * 100.0) / nbucket);
uint64_t nzero_counts = 0;
for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
{
nzero_counts += counts[cnt] * cnt;
printf (gettext ("\
%7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
(int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
(nzero_counts * 100.0) / nsyms);
}
Elf32_Word acc = 0;
for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
{
acc += cnt;
success += counts[cnt] * acc;
}
printf (gettext ("\
Average number of tests: successful lookup: %f\n\
unsuccessful lookup: %f\n"),
(double) success / (double) nzero_counts,
(double) nzero_counts / (double) nbucket);
}
free (counts);
}
/* This function handles the traditional System V-style hash table format. */
static void
handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
{
Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL)
{
error (0, 0, gettext ("cannot get data for section %d: %s"),
(int) elf_ndxscn (scn), elf_errmsg (-1));
return;
}
Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
uint_fast32_t maxlength = 0;
uint_fast32_t nsyms = 0;
for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
{
Elf32_Word inner = bucket[cnt];
while (inner > 0 && inner < nchain)
{
++nsyms;
if (maxlength < ++lengths[cnt])
++maxlength;
inner = chain[inner];
}
}
print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
lengths);
free (lengths);
}
/* This function handles the incorrect, System V-style hash table
format some 64-bit architectures use. */
static void
handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
{
Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL)
{
error (0, 0, gettext ("cannot get data for section %d: %s"),
(int) elf_ndxscn (scn), elf_errmsg (-1));
return;
}
Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
uint_fast32_t maxlength = 0;
uint_fast32_t nsyms = 0;
for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
{
Elf64_Xword inner = bucket[cnt];
while (inner > 0 && inner < nchain)
{
++nsyms;
if (maxlength < ++lengths[cnt])
++maxlength;
inner = chain[inner];
}
}
print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
lengths);
free (lengths);
}
/* This function handles the GNU-style hash table format. */
static void
handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
{
Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL)
{
error (0, 0, gettext ("cannot get data for section %d: %s"),
(int) elf_ndxscn (scn), elf_errmsg (-1));
return;
}
Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + 2 * nbucket];
uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
uint_fast32_t maxlength = 0;
uint_fast32_t nsyms = 0;
for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
if (bucket[2 * cnt + 1] != 0)
{
Elf32_Word inner = bucket[2 * cnt + 1] - symbias;
do
{
++nsyms;
if (maxlength < ++lengths[cnt])
++maxlength;
}
while ((chain[inner++] & 1) == 0);
}
print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
lengths);
free (lengths);
}
/* Find the symbol table(s). For this we have to search through the
section table. */
static void
@@ -2526,17 +2338,100 @@ handle_hash (Ebl *ebl)
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
if (shdr != NULL)
if (shdr != NULL && shdr->sh_type == SHT_HASH)
{
if (shdr->sh_type == SHT_HASH)
Elf_Data *data = elf_getdata (scn, NULL);
if (data == NULL)
{
if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
else
handle_sysv_hash (ebl, scn, shdr, shstrndx);
error (0, 0, gettext ("cannot get data for section %d: %s"),
(int) elf_ndxscn (scn), elf_errmsg (-1));
continue;
}
else if (shdr->sh_type == SHT_GNU_HASH)
handle_gnu_hash (ebl, scn, shdr, shstrndx);
Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
GElf_Shdr glink;
printf (ngettext ("\
\nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
\nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
nbucket),
(unsigned int) elf_ndxscn (scn),
elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
(int) nbucket,
gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
shdr->sh_addr,
shdr->sh_offset,
(unsigned int) shdr->sh_link,
elf_strptr (ebl->elf, shstrndx,
gelf_getshdr (elf_getscn (ebl->elf,
shdr->sh_link),
&glink)->sh_name));
uint32_t *lengths = (uint32_t *) xcalloc (nbucket,
sizeof (uint32_t));
Elf32_Word maxlength = 0;
Elf32_Word nsyms = 0;
for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
if (bucket[cnt] != 0)
{
Elf32_Word inner = bucket[cnt];
while (inner > 0 && inner < nchain)
{
++nsyms;
if (maxlength < ++lengths[cnt])
++maxlength;
inner = chain[inner];
}
}
uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1,
sizeof (uint32_t));
for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
++counts[lengths[cnt]];
if (nbucket > 0)
{
uint64_t success = 0;
fputs_unlocked (gettext ("\
Length Number % of total Coverage\n"), stdout);
printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
counts[0], (counts[0] * 100.0) / nbucket);
uint64_t nzero_counts = 0;
for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
{
nzero_counts += counts[cnt] * cnt;
printf (gettext ("\
%7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
(int) cnt,
counts[cnt], (counts[cnt] * 100.0) / nbucket,
(nzero_counts * 100.0) / nsyms);
}
Elf32_Word acc = 0;
for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
{
acc += cnt;
success += counts[cnt] * acc;
}
printf (gettext ("\
Average number of tests: successful lookup: %f\n\
unsuccessful lookup: %f\n"),
(double) success / (double) nzero_counts,
(double) nzero_counts / (double) nbucket);
}
free (counts);
free (lengths);
}
}
}