mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-14 22:49:24 -04:00
New spec file.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
@@ -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,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;
|
||||
}
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
@@ -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)),
|
||||
|
||||
@@ -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,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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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. */
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user