Finish elflint .gnu.attributes checking

This commit is contained in:
Roland McGrath
2008-02-21 06:19:39 +00:00
parent 712d78eced
commit 059c83e5db
31 changed files with 908 additions and 165 deletions
+23
View File
@@ -1,3 +1,26 @@
2008-02-20 Roland McGrath <roland@redhat.com>
* ppc_attrs.c: New file.
* Makefile.am (ppc_SRCS, ppc64_SRCS): Add it.
* ppc_init.c (ppc_init): Initialize check_object_attribute hook.
2008-02-14 Roland McGrath <roland@redhat.com>
* alpha_auxv.c: New file.
* Makefile.am (alpha_SRCS): Add it.
* alpha_init.c (alpha_init): Initialize auxv_info hook.
2008-02-08 Roland McGrath <roland@redhat.com>
* ppc_corenote.c (spe_regs): New const variable.
(EXTRA_NOTES): Use it for NT_PPC_SPE.
2008-01-02 Roland McGrath <roland@redhat.com>
* i386_corenote.c (tls_items): New const table.
(tls_info): New function, uses it.
(EXTRA_NOTES): Use it to handle NT_386_TLS.
2008-01-08 Ulrich Drepper <drepper@redhat.com>
* Makefile.am: Add x86-64 disassembler.
+3 -3
View File
@@ -81,7 +81,7 @@ libebl_ia64_pic_a_SOURCES = $(ia64_SRCS)
am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os)
alpha_SRCS = alpha_init.c alpha_symbol.c alpha_retval.c alpha_regs.c \
alpha_corenote.c
alpha_corenote.c alpha_auxv.c
libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
@@ -95,12 +95,12 @@ libebl_sparc_pic_a_SOURCES = $(sparc_SRCS)
am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
ppc_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c ppc_regs.c \
ppc_corenote.c ppc_auxv.c
ppc_corenote.c ppc_auxv.c ppc_attrs.c
libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
ppc64_corenote.c ppc_regs.c ppc_auxv.c
ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c
libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
+46
View File
@@ -0,0 +1,46 @@
/* Alpha-specific auxv handling.
Copyright (C) 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
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.
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
#define BACKEND alpha_
#include "libebl_CPU.h"
int
EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format)
{
if (a_type != AT_HWCAP)
return 0;
*name = "HWCAP";
*format = "b"
"bwx\0" "fix\0" "cix\0" "0x08\0"
"0x10\0" "0x20\0" "0x40\0" "0x80\0"
"max\0" "precise_trap\0"
"\0";
return 1;
}
+2 -1
View File
@@ -1,5 +1,5 @@
/* Initialization of Alpha specific backend library.
Copyright (C) 2002, 2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 2002, 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -57,6 +57,7 @@ alpha_init (elf, machine, eh, ehlen)
HOOK (eh, machine_section_flag_check);
HOOK (eh, register_info);
HOOK (eh, core_note);
HOOK (eh, auxv_info);
eh->sysvhash_entrysize = sizeof (Elf64_Xword);
return MODVERSION;
+30 -2
View File
@@ -1,5 +1,5 @@
/* i386 specific core note handling.
Copyright (C) 2007 Red Hat, Inc.
Copyright (C) 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -101,6 +101,34 @@ static const Ebl_Register_Location prxfpreg_regs[] =
};
#define EXTRA_NOTES \
EXTRA_REGSET (NT_PRFPXREG, 512, prxfpreg_regs)
EXTRA_REGSET (NT_PRFPXREG, 512, prxfpreg_regs) \
case NT_386_TLS: \
return tls_info (descsz, regs_offset, nregloc, reglocs, nitems, items);
#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
static const Ebl_Core_Item tls_items[] =
{
{ .type = ELF_T_WORD, .offset = 0x0, .format = 'd', .name = "index" },
{ .type = ELF_T_WORD, .offset = 0x4, .format = 'x', .name = "base" },
{ .type = ELF_T_WORD, .offset = 0x8, .format = 'x', .name = "limit" },
{ .type = ELF_T_WORD, .offset = 0xc, .format = 'x', .name = "flags" },
};
static int
tls_info (GElf_Word descsz, GElf_Word *regs_offset,
size_t *nregloc, const Ebl_Register_Location **reglocs,
size_t *nitems, const Ebl_Core_Item **items)
{
if (descsz % 16 != 0)
return 0;
*regs_offset = 0;
*nregloc = 0;
*reglocs = NULL;
*nitems = sizeof tls_items / sizeof tls_items[0];
*items = tls_items;
return 1;
}
#include "linux-core-note.c"
+76
View File
@@ -0,0 +1,76 @@
/* Object attribute tags for PowerPC.
Copyright (C) 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
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.
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 <string.h>
#include <dwarf.h>
#define BACKEND ppc_
#include "libebl_CPU.h"
bool
ppc_check_object_attribute (ebl, vendor, tag, value, tag_name, value_name)
Ebl *ebl __attribute__ ((unused));
const char *vendor;
int tag;
uint64_t value;
const char **tag_name;
const char **value_name;
{
if (!strcmp (vendor, "gnu"))
switch (tag)
{
case 4:
*tag_name = "GNU_Power_ABI_FP";
static const char *fp_kinds[] =
{
"Hard or soft float",
"Hard float",
"Soft float",
};
if (value < sizeof fp_kinds / sizeof fp_kinds[0])
*value_name = fp_kinds[value];
return true;
case 8:
*tag_name = "GNU_Power_ABI_Vector";
static const char *vector_kinds[] =
{
"Any", "Generic", "AltiVec", "SPE"
};
if (value < sizeof vector_kinds / sizeof vector_kinds[0])
*value_name = vector_kinds[value];
return true;
}
return false;
}
__typeof (ppc_check_object_attribute)
ppc64_check_object_attribute
__attribute__ ((alias ("ppc_check_object_attribute")));
+13 -2
View File
@@ -1,5 +1,5 @@
/* PowerPC specific core note handling.
Copyright (C) 2007 Red Hat, Inc.
Copyright (C) 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -81,8 +81,19 @@ static const Ebl_Register_Location altivec_regs[] =
{ .offset = 33 * 16, .regno = 356, .count = 1, .bits = 32, .pad = 12 }
};
static const Ebl_Register_Location spe_regs[] =
{
/* evr0-evr31
{ .offset = 0, .regno = ???, .count = 32, .bits = 32 },
* acc *
{ .offset = 32 * 4, .regno = ???, .count = 1, .bits = 64 }, */
/* spefscr */
{ .offset = 34 * 4, .regno = 612, .count = 1, .bits = 32 }
};
#define EXTRA_NOTES \
EXTRA_REGSET (NT_PPC_VMX, 34 * 16, altivec_regs)
EXTRA_REGSET (NT_PPC_VMX, 34 * 16, altivec_regs) \
EXTRA_REGSET (NT_PPC_SPE, 35 * 4, spe_regs)
#if BITS == 32
# define ULONG uint32_t
+2 -1
View File
@@ -1,5 +1,5 @@
/* Initialization of PPC specific backend library.
Copyright (C) 2004, 2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -59,6 +59,7 @@ ppc_init (elf, machine, eh, ehlen)
HOOK (eh, register_info);
HOOK (eh, core_note);
HOOK (eh, auxv_info);
HOOK (eh, check_object_attribute);
return MODVERSION;
}
+16
View File
@@ -1,3 +1,19 @@
2008-02-19 Roland McGrath <roland@redhat.com>
* relocate.c (relocate_section): Check for an unhandled relocation
type before resolving a reloc's symbol. Lift DWFL_E_BADRELTYPE ->
DWFL_E_UNKNOWN_MACHINE check out of loops.
* dwfl_module_getdwarf.c (load_dw): Skip relocation if
DEBUGFILE->relocated is already set.
2008-01-26 Roland McGrath <roland@redhat.com>
* dwfl_module_getdwarf.c (open_elf): Open FILE->name if it's non-null.
* dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Don't clear
incoming *FILE_NAME at the start.
2008-01-08 Roland McGrath <roland@redhat.com>
* Makefile.am (euinclude): Variable removed.
+3 -2
View File
@@ -1,5 +1,5 @@
/* Find an ELF file for a module from its build ID.
Copyright (C) 2007 Red Hat, Inc.
Copyright (C) 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -57,7 +57,8 @@ int
internal_function
__libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name)
{
*file_name = NULL;
/* If *FILE_NAME was primed into the module, leave it there
as the fallback when we have nothing to offer. */
errno = 0;
if (mod->build_id_len <= 0)
return -1;
+7 -2
View File
@@ -1,5 +1,5 @@
/* Find debugging and symbol information for a module in libdwfl.
Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -61,6 +61,11 @@ open_elf (Dwfl_Module *mod, struct dwfl_file *file)
{
if (file->elf == NULL)
{
/* If there was a pre-primed file name left that the callback left
behind, try to open that file name. */
if (file->fd < 0 && file->name != NULL)
file->fd = TEMP_FAILURE_RETRY (open64 (file->name, O_RDONLY));
if (file->fd < 0)
return CBFAIL;
@@ -585,7 +590,7 @@ __libdwfl_module_getebl (Dwfl_Module *mod)
static Dwfl_Error
load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
{
if (mod->e_type == ET_REL)
if (mod->e_type == ET_REL && !debugfile->relocated)
{
const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
+22 -6
View File
@@ -1,5 +1,5 @@
/* Relocate debug information.
Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -306,6 +306,12 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
Dwfl_Error relocate (GElf_Addr offset, const GElf_Sxword *addend,
int rtype, int symndx)
{
/* First see if this is a reloc we can handle.
If we are skipping it, don't bother resolving the symbol. */
Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
if (unlikely (type == ELF_T_NUM))
return DWFL_E_BADRELTYPE;
/* First, resolve the symbol to an absolute value. */
GElf_Addr value;
@@ -342,7 +348,6 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \
DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
size_t size;
Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
switch (type)
{
#define DO_TYPE(NAME, Name) \
@@ -352,10 +357,6 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
TYPES;
#undef DO_TYPE
default:
/* This might be because ebl_openbackend failed to find
any libebl_CPU.so library. Diagnose that clearly. */
if (ebl_get_elfmachine (mod->ebl) == EM_NONE)
return DWFL_E_UNKNOWN_MACHINE;
return DWFL_E_BADRELTYPE;
}
@@ -437,6 +438,19 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
return DWFL_E_LIBELF;
Dwfl_Error result = DWFL_E_NOERROR;
bool first_badreltype = true;
inline void check_badreltype (void)
{
if (first_badreltype)
{
first_badreltype = false;
if (ebl_get_elfmachine (mod->ebl) == EM_NONE)
/* This might be because ebl_openbackend failed to find
any libebl_CPU.so library. Diagnose that clearly. */
result = DWFL_E_UNKNOWN_MACHINE;
}
}
size_t nrels = shdr->sh_size / shdr->sh_entsize;
size_t complete = 0;
if (shdr->sh_type == SHT_REL)
@@ -448,6 +462,7 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
result = relocate (r->r_offset, NULL,
GELF_R_TYPE (r->r_info),
GELF_R_SYM (r->r_info));
check_badreltype ();
if (partial)
switch (result)
{
@@ -476,6 +491,7 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
result = relocate (r->r_offset, &r->r_addend,
GELF_R_TYPE (r->r_info),
GELF_R_SYM (r->r_info));
check_badreltype ();
if (partial)
switch (result)
{
+22
View File
@@ -1,3 +1,25 @@
2008-02-20 Roland McGrath <roland@redhat.com>
* libebl.h: Declare ebl_check_object_attribute.
* eblcheckobjattr.c: New file.
* Makefile.am (gen_SOURCES): Add it.
* ebl-hooks.h: Add check_object_attribute hook.
* eblopenbackend.c (default_check_object_attribute): New function.
(fill_defaults): Initialize pointer to it.
2008-02-19 Roland McGrath <roland@redhat.com>
* eblsectiontypename.c (ebl_section_type_name):
Handle SHT_GNU_ATTRIBUTES.
2008-02-08 Roland McGrath <roland@redhat.com>
* eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PPC_SPE.
2008-01-30 Roland McGrath <roland@redhat.com>
* eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_386_TLS.
2007-10-18 Roland McGrath <roland@redhat.com>
* eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PPC_VMX.
+2 -2
View File
@@ -1,6 +1,6 @@
## Process this file with automake to create Makefile.in
##
## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
## Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008 Red Hat, Inc.
## This file is part of Red Hat elfutils.
##
## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -58,7 +58,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
eblelfclass.c eblelfdata.c eblelfmachine.c \
ebl_check_special_symbol.c eblbsspltp.c eblretval.c \
eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \
eblsysvhashentrysize.c eblauxvinfo.c
eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c
libebl_a_SOURCES = $(gen_SOURCES)
+5 -1
View File
@@ -115,6 +115,10 @@ int EBLHOOK(core_note) (GElf_Word, GElf_Word, GElf_Word *, size_t *,
/* Handle object file note. */
bool EBLHOOK(object_note) (const char *, uint32_t, uint32_t, const char *);
/* Check object attribute. */
bool EBLHOOK(check_object_attribute) (Ebl *, const char *, int, uint64_t,
const char **, const char **);
/* Describe auxv element type. */
int EBLHOOK(auxv_info) (GElf_Xword, const char **, const char **);
@@ -148,7 +152,7 @@ ssize_t EBLHOOK(register_info) (Ebl *ebl,
const char **prefix, const char **setname,
int *bits, int *type);
/* Disassembler function. */
/* Disassembler function. */
int EBLHOOK(disasm) (const uint8_t **startp, const uint8_t *end,
GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb,
DisasmGetSymCB_t symcb, void *outcbarg, void *symcbarg);
+81
View File
@@ -0,0 +1,81 @@
/* Check object attributes.
Copyright (C) 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
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 <string.h>
#include <libeblP.h>
bool
ebl_check_object_attribute (ebl, vendor, tag, value, tag_name, value_name)
Ebl *ebl;
const char *vendor;
int tag;
uint64_t value;
const char **tag_name;
const char **value_name;
{
if (ebl->check_object_attribute (ebl, vendor, tag, value,
tag_name, value_name))
return true;
if (strcmp (vendor, "gnu"))
return false;
if (tag == 32)
{
*tag_name = "compatibility";
return true;
}
return false;
}
+3 -1
View File
@@ -1,5 +1,5 @@
/* Return note type name.
Copyright (C) 2002, 2007 Red Hat, Inc.
Copyright (C) 2002, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -99,6 +99,8 @@ ebl_core_note_type_name (ebl, type, buf, len)
#define KNOWNSTYPE(name) case NT_##name: res = #name; break
KNOWNSTYPE (PRXFPREG);
KNOWNSTYPE (PPC_VMX);
KNOWNSTYPE (PPC_SPE);
KNOWNSTYPE (386_TLS);
#undef KNOWNSTYPE
default:
+18 -1
View File
@@ -1,5 +1,5 @@
/* Generate ELF backend handle.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -210,6 +210,10 @@ static ssize_t default_register_info (Ebl *ebl,
const char **prefix,
const char **setname,
int *bits, int *type);
static bool default_check_object_attribute (Ebl *ebl, const char *vendor,
int tag, uint64_t value,
const char **tag_name,
const char **value_name);
static void
@@ -246,6 +250,7 @@ fill_defaults (Ebl *result)
result->bss_plt_p = default_bss_plt_p;
result->return_value_location = default_return_value_location;
result->register_info = default_register_info;
result->check_object_attribute = default_check_object_attribute;
result->disasm = NULL;
result->destr = default_destr;
result->sysvhash_entrysize = sizeof (Elf32_Word);
@@ -700,3 +705,15 @@ default_register_info (Ebl *ebl __attribute__ ((unused)),
*type = DW_ATE_void;
return snprintf (name, namelen, "reg%d", regno);
}
static bool
default_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
const char *vendor __attribute__ ((unused)),
int tag __attribute__ ((unused)),
uint64_t value __attribute__ ((unused)),
const char **tag_name, const char **value_name)
{
*tag_name = NULL;
*value_name = NULL;
return false;
}
+29 -22
View File
@@ -1,5 +1,5 @@
/* Return section type name.
Copyright (C) 2001, 2002, 2006 Red Hat, Inc.
Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -110,31 +110,38 @@ ebl_section_type_name (ebl, section, buf, len)
res = sunwtypes[section - SHT_LOSUNW];
}
else
{
/* A few GNU additions. */
if (section == SHT_CHECKSUM)
/* A few GNU additions. */
switch (section)
{
case SHT_CHECKSUM:
res = "CHECKSUM";
else if (section == SHT_GNU_LIBLIST)
break;
case SHT_GNU_LIBLIST:
res = "GNU_LIBLIST";
else if (section == SHT_GNU_HASH)
break;
case SHT_GNU_HASH:
res = "GNU_HASH";
/* Handle OS-specific section names. */
else
{
if (section >= SHT_LOOS && section <= SHT_HIOS)
snprintf (buf, len, "SHT_LOOS+%x", section - SHT_LOOS);
/* Handle processor-specific section names. */
else if (section >= SHT_LOPROC && section <= SHT_HIPROC)
snprintf (buf, len, "SHT_LOPROC+%x", section - SHT_LOPROC);
else if ((unsigned int) section >= SHT_LOUSER
&& (unsigned int) section <= SHT_HIUSER)
snprintf (buf, len, "SHT_LOUSER+%x", section - SHT_LOUSER);
else
snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section);
break;
case SHT_GNU_ATTRIBUTES:
res = "GNU_ATTRIBUTES";
break;
res = buf;
}
}
default:
/* Handle OS-specific section names. */
if (section >= SHT_LOOS && section <= SHT_HIOS)
snprintf (buf, len, "SHT_LOOS+%x", section - SHT_LOOS);
/* Handle processor-specific section names. */
else if (section >= SHT_LOPROC && section <= SHT_HIPROC)
snprintf (buf, len, "SHT_LOPROC+%x", section - SHT_LOPROC);
else if ((unsigned int) section >= SHT_LOUSER
&& (unsigned int) section <= SHT_HIUSER)
snprintf (buf, len, "SHT_LOUSER+%x", section - SHT_LOUSER);
else
snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section);
res = buf;
break;
}
}
return res;
+10 -1
View File
@@ -1,5 +1,5 @@
/* Interface for libebl.
Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -182,6 +182,15 @@ extern const char *ebl_object_note_type_name (Ebl *ebl, uint32_t type,
extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
uint32_t descsz, const char *desc);
/* Check whether an attribute in a .gnu_attributes section is recognized.
Fills in *TAG_NAME with the name for this tag.
If VALUE is a known value for that tag, also fills in *VALUE_NAME. */
extern bool ebl_check_object_attribute (Ebl *ebl, const char *vendor,
int tag, uint64_t value,
const char **tag_name,
const char **value_name);
/* Check section name for being that of a debug informatino section. */
extern bool ebl_debugscn_p (Ebl *ebl, const char *name);
+17
View File
@@ -1,8 +1,25 @@
2008-02-19 Roland McGrath <roland@redhat.com>
* elf.h: Update from glibc.
2008-02-08 Roland McGrath <roland@redhat.com>
* elf.h: Update from glibc.
2008-01-31 Ulrich Drepper <drepper@redhat.com>
* elf_strptr.c (elf_strptr): Don't fail if the ELF file is currently
under construction and no raw data can be read from disk.
2008-01-30 Roland McGrath <roland@redhat.com>
* elf.h: Update from glibc.
2008-01-26 Roland McGrath <roland@redhat.com>
* elf_begin.c (__libelf_next_arhdr): Rewrite conversions using a macro.
Fixes various pastos in wrong type in sizeof, wrong string parsed.
2008-01-20 Roland McGrath <roland@redhat.com>
* elf_getaroff.c: Calculate from start_offset, instead of using
+6 -1
View File
@@ -1,5 +1,6 @@
/* This file defines standard ELF types, structures, and macros.
Copyright (C) 1995-2003,2004,2005,2006,2007 Free Software Foundation, Inc.
Copyright (C) 1995-2003,2004,2005,2006,2007,2008
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,6 +331,7 @@ 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_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
@@ -605,6 +607,8 @@ typedef struct
#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
/* Legal values for the note segment descriptor types for object files. */
@@ -1278,6 +1282,7 @@ typedef struct
#define HWCAP_SPARC_V9 16 /* The CPU is v9, so v8plus is ok. */
#define HWCAP_SPARC_ULTRA3 32
#define HWCAP_SPARC_BLKINIT 64 /* Sun4v with block-init/load-twin. */
#define HWCAP_SPARC_N2 128
/* MIPS R3000 specific definitions. */
+32 -99
View File
@@ -1,5 +1,5 @@
/* Create descriptor for processing file.
Copyright (C) 1998-2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 1998-2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -850,112 +850,45 @@ __libelf_next_arhdr (elf)
elf_ar_hdr->ar_name = elf->state.ar.ar_name;
}
if (unlikely (ar_hdr->ar_size[0] == ' '))
/* Something is really wrong. We cannot live without a size for
the member since it will not be possible to find the next
archive member. */
{
__libelf_seterrno (ELF_E_INVALID_ARCHIVE);
return -1;
}
/* Since there are no specialized functions to convert ASCII to
time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
atoll depending on the size of the types. We are also prepared
for the case where the whole field in the `struct ar_hdr' is
filled in which case we cannot simply use atol/l but instead have
to create a temporary copy. */
if (ar_hdr->ar_date[sizeof (ar_hdr->ar_date) - 1] == ' ')
{
if (ar_hdr->ar_date[0] == ' ')
elf_ar_hdr->ar_date = 0;
else
elf_ar_hdr->ar_date = (sizeof (time_t) <= sizeof (long int)
? (time_t) atol (ar_hdr->ar_date)
: (time_t) atoll (ar_hdr->ar_date));
}
else
{
char buf[sizeof (ar_hdr->ar_date) + 1];
*((char *) __mempcpy (buf, ar_hdr->ar_date, sizeof (ar_hdr->ar_date)))
= '\0';
elf_ar_hdr->ar_date = (sizeof (time_t) <= sizeof (long int)
? (time_t) atol (ar_hdr->ar_date)
: (time_t) atoll (ar_hdr->ar_date));
}
if (ar_hdr->ar_uid[sizeof (ar_hdr->ar_uid) - 1] == ' ')
{
if (ar_hdr->ar_uid[0] == ' ')
elf_ar_hdr->ar_uid = 0;
else
elf_ar_hdr->ar_uid = (sizeof (uid_t) <= sizeof (long int)
? (uid_t) atol (ar_hdr->ar_uid)
: (uid_t) atoll (ar_hdr->ar_uid));
}
else
{
char buf[sizeof (ar_hdr->ar_uid) + 1];
*((char *) __mempcpy (buf, ar_hdr->ar_uid, sizeof (ar_hdr->ar_uid)))
= '\0';
elf_ar_hdr->ar_uid = (sizeof (uid_t) <= sizeof (long int)
? (uid_t) atol (ar_hdr->ar_uid)
: (uid_t) atoll (ar_hdr->ar_uid));
}
#define INT_FIELD(FIELD) \
do \
{ \
char buf[sizeof (ar_hdr->FIELD) + 1]; \
const char *string = ar_hdr->FIELD; \
if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \
{ \
*((char *) __mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \
= '\0'; \
string = buf; \
} \
if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \
elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string); \
else \
elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string); \
} \
while (0)
if (ar_hdr->ar_gid[sizeof (ar_hdr->ar_gid) - 1] == ' ')
{
if (ar_hdr->ar_gid[0] == ' ')
elf_ar_hdr->ar_gid = 0;
else
elf_ar_hdr->ar_gid = (sizeof (gid_t) <= sizeof (long int)
? (gid_t) atol (ar_hdr->ar_gid)
: (gid_t) atoll (ar_hdr->ar_gid));
}
else
{
char buf[sizeof (ar_hdr->ar_gid) + 1];
*((char *) __mempcpy (buf, ar_hdr->ar_gid, sizeof (ar_hdr->ar_gid)))
= '\0';
elf_ar_hdr->ar_gid = (sizeof (gid_t) <= sizeof (long int)
? (gid_t) atol (ar_hdr->ar_gid)
: (gid_t) atoll (ar_hdr->ar_gid));
}
if (ar_hdr->ar_mode[sizeof (ar_hdr->ar_mode) - 1] == ' ')
{
if (ar_hdr->ar_mode[0] == ' ')
elf_ar_hdr->ar_mode = 0;
else
elf_ar_hdr->ar_mode = (sizeof (mode_t) <= sizeof (long int)
? (mode_t) strtol (ar_hdr->ar_mode, NULL, 8)
: (mode_t) strtoll (ar_hdr->ar_mode, NULL, 8));
}
else
{
char buf[sizeof (ar_hdr->ar_mode) + 1];
*((char *) __mempcpy (buf, ar_hdr->ar_mode, sizeof (ar_hdr->ar_mode)))
= '\0';
elf_ar_hdr->ar_mode = (sizeof (mode_t) <= sizeof (long int)
? (mode_t) strtol (ar_hdr->ar_mode, NULL, 8)
: (mode_t) strtoll (ar_hdr->ar_mode, NULL, 8));
}
if (ar_hdr->ar_size[sizeof (ar_hdr->ar_size) - 1] == ' ')
{
if (unlikely (ar_hdr->ar_size[0] == ' '))
/* Something is really wrong. We cannot live without a size for
the member since it will not be possible to find the next
archive member. */
{
__libelf_seterrno (ELF_E_INVALID_ARCHIVE);
return -1;
}
else
elf_ar_hdr->ar_size = (sizeof (time_t) == sizeof (long int)
? (off_t) atol (ar_hdr->ar_size)
: (off_t) atoll (ar_hdr->ar_size));
}
else
{
char buf[sizeof (ar_hdr->ar_size) + 1];
*((char *) __mempcpy (buf, ar_hdr->ar_size, sizeof (ar_hdr->ar_size)))
= '\0';
elf_ar_hdr->ar_size = (sizeof (time_t) == sizeof (long int)
? (off_t) atol (ar_hdr->ar_size)
: (off_t) atoll (ar_hdr->ar_size));
}
INT_FIELD (ar_date);
INT_FIELD (ar_uid);
INT_FIELD (ar_gid);
INT_FIELD (ar_mode);
INT_FIELD (ar_size);
return 0;
}
+24
View File
@@ -1,3 +1,21 @@
2008-02-20 Roland McGrath <roland@redhat.com>
* readelf.c (print_attributes): New function.
(process_elf_file): Call it under -A.
* elflint.c (check_attributes): Implement it for real.
2008-02-19 Roland McGrath <roland@redhat.com>
* elflint.c (special_sections): Handle .gnu.attributes section.
(check_sections): Likewise.
(check_attributes): New function.
2008-02-10 Roland McGrath <roland@redhat.com>
* elfcmp.c (main): Ignore sh_offset differences in non-SHF_ALLOC
sections and ET_REL files.
2008-02-02 Ulrich Drepper <drepper@redhat.com>
* elf32-i386.script: Add .eh_frame_hdr, .tdata, and .tbss sections.
@@ -108,6 +126,12 @@
* objdump.c (show_disasm): Adjust disassembler format string for
removal of %e.
2008-01-04 Roland McGrath <roland@redhat.com>
* readelf.c (handle_core_items): Take new arg DESCSZ; if nonzero,
a size greater than the items cover means multiple sets of items.
(handle_core_note): Update caller.
2008-01-04 Roland McGrath <roland@redhat.com>
* strip.c (handle_elf): Move SHDRIDX defn to silence gcc warning.
+4 -2
View File
@@ -1,5 +1,5 @@
/* Compare relevant content of two ELF files.
Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2005.
@@ -259,7 +259,9 @@ main (int argc, char *argv[])
// XXX Any flags which should be ignored?
|| shdr1->sh_flags != shdr2->sh_flags
|| shdr1->sh_addr != shdr2->sh_addr
|| shdr1->sh_offset != shdr2->sh_offset
|| (shdr1->sh_offset != shdr2->sh_offset
&& (shdr1->sh_flags & SHF_ALLOC)
&& ehdr1->e_type != ET_REL)
|| shdr1->sh_size != shdr2->sh_size
|| shdr1->sh_link != shdr2->sh_link
|| shdr1->sh_info != shdr2->sh_info
+200 -1
View File
@@ -46,7 +46,12 @@
#include <elf-knowledge.h>
#include <system.h>
#include "../libelf/libelfP.h"
#include "../libelf/common.h"
#include "../libebl/libeblP.h"
#include "../libdw/libdwP.h"
#include "../libdwfl/libdwflP.h"
#include "../libdw/memory-access.h"
/* Name and version of program. */
@@ -3099,6 +3104,194 @@ section [%2d] '%s': unknown parent version '%s'\n"),
}
}
static void
check_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
if (shdr->sh_size == 0)
{
ERROR (gettext ("section [%2d] '%s': empty object attributes section\n"),
idx, section_name (ebl, idx));
return;
}
Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL);
if (data == NULL || data->d_size == 0)
{
ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
idx, section_name (ebl, idx));
return;
}
inline size_t pos (const unsigned char *p)
{
return p - (const unsigned char *) data->d_buf;
}
const unsigned char *p = data->d_buf;
if (*p++ != 'A')
{
ERROR (gettext ("section [%2d] '%s': unrecognized attribute format\n"),
idx, section_name (ebl, idx));
return;
}
inline size_t left (void)
{
return (const unsigned char *) data->d_buf + data->d_size - p;
}
while (left () >= 4)
{
uint32_t len;
memcpy (&len, p, sizeof len);
if (len == 0)
ERROR (gettext ("\
section [%2d] '%s': offset %zu: zero length field in attribute section\n"),
idx, section_name (ebl, idx), pos (p));
if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
CONVERT (len);
if (len > left ())
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: invalid length in attribute section\n"),
idx, section_name (ebl, idx), pos (p));
break;
}
const unsigned char *name = p + sizeof len;
p += len;
unsigned const char *q = memchr (name, '\0', len);
if (q == NULL)
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: unterminated vendor name string\n"),
idx, section_name (ebl, idx), pos (p));
continue;
}
++q;
if (q - name == sizeof "gnu" && !memcmp (name, "gnu", sizeof "gnu"))
while (q < p)
{
unsigned const char *chunk = q;
unsigned int subsection_tag;
get_uleb128 (subsection_tag, q);
if (q >= p)
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"),
idx, section_name (ebl, idx), pos (chunk));
break;
}
uint32_t subsection_len;
if (p - q < (ptrdiff_t) sizeof subsection_len)
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: truncated attribute section\n"),
idx, section_name (ebl, idx), pos (q));
break;
}
memcpy (&subsection_len, q, sizeof subsection_len);
if (subsection_len == 0)
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"),
idx, section_name (ebl, idx), pos (q));
q += sizeof subsection_len;
continue;
}
if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
CONVERT (subsection_len);
if (p - chunk < subsection_len)
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"),
idx, section_name (ebl, idx), pos (q));
break;
}
const unsigned char *subsection_end = chunk + subsection_len;
chunk = q;
q = subsection_end;
if (subsection_tag != 1) /* Tag_File */
ERROR (gettext ("\
section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"),
idx, section_name (ebl, idx), pos (chunk), subsection_tag);
else
{
chunk += sizeof subsection_len;
while (chunk < q)
{
unsigned int tag;
get_uleb128 (tag, chunk);
uint64_t value = 0;
const unsigned char *r = chunk;
if (tag == 32 || (tag & 1) == 0)
{
get_uleb128 (value, r);
if (r > q)
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"),
idx, section_name (ebl, idx), pos (chunk));
break;
}
}
if (tag == 32 || (tag & 1) != 0)
{
r = memchr (r, '\0', q - r);
if (r == NULL)
{
ERROR (gettext ("\
section [%2d] '%s': offset %zu: unterminated string in attribute\n"),
idx, section_name (ebl, idx), pos (chunk));
break;
}
++r;
}
const char *tag_name = NULL;
const char *value_name = NULL;
if (!ebl_check_object_attribute (ebl, (const char *) name,
tag, value,
&tag_name, &value_name))
ERROR (gettext ("\
section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"),
idx, section_name (ebl, idx), pos (chunk), tag);
else if ((tag & 1) == 0 && value_name == NULL)
ERROR (gettext ("\
section [%2d] '%s': offset %zu: unrecognized %s attribute value %" PRIu64 "\n"),
idx, section_name (ebl, idx), pos (chunk),
tag_name, value);
chunk = r;
}
}
}
else
ERROR (gettext ("\
section [%2d] '%s': offset %zu: vendor '%s' unknown\n"),
idx, section_name (ebl, idx), pos (p), name);
}
if (left () != 0)
ERROR (gettext ("\
section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"),
idx, section_name (ebl, idx), pos (p));
}
static bool has_loadable_segment;
static bool has_interp_segment;
@@ -3150,7 +3343,8 @@ static const struct
/* The following are GNU extensions. */
{ ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 },
{ ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 },
{ ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 }
{ ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 },
{ ".gnu.attributes", 16, SHT_GNU_ATTRIBUTES, exact, 0, 0 },
};
#define nspecial_sections \
(sizeof (special_sections) / sizeof (special_sections[0]))
@@ -3365,6 +3559,7 @@ section [%2zu] '%s': size not multiple of entry size\n"),
ERROR (gettext ("cannot get section header\n"));
if (shdr->sh_type >= SHT_NUM
&& shdr->sh_type != SHT_GNU_ATTRIBUTES
&& shdr->sh_type != SHT_GNU_LIBLIST
&& shdr->sh_type != SHT_CHECKSUM
&& shdr->sh_type != SHT_GNU_verdef
@@ -3557,6 +3752,10 @@ section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
check_verdef (ebl, shdr, cnt);
break;
case SHT_GNU_ATTRIBUTES:
check_attributes (ebl, ehdr, shdr, cnt);
break;
default:
/* Nothing. */
break;
+200 -13
View File
@@ -1,5 +1,5 @@
/* Print information from ELF file in human-readable form.
Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007 Red Hat, Inc.
Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 1999.
@@ -52,6 +52,7 @@
#include <system.h>
#include "../libelf/libelfP.h"
#include "../libelf/common.h"
#include "../libebl/libeblP.h"
#include "../libdw/libdwP.h"
#include "../libdwfl/libdwflP.h"
@@ -221,6 +222,7 @@ static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
static void handle_hash (Ebl *ebl);
static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_liblist (Ebl *ebl);
static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
static void dump_data (Ebl *ebl);
static void dump_strings (Ebl *ebl);
static void print_strings (Ebl *ebl);
@@ -640,6 +642,8 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
print_symtab (ebl, SHT_SYMTAB);
if (print_arch)
print_liblist (ebl);
if (print_arch)
print_attributes (ebl, ehdr);
if (dump_data_sections != NULL)
dump_data (pure_ebl);
if (string_sections != NULL)
@@ -2777,6 +2781,166 @@ print_liblist (Ebl *ebl)
}
}
static void
print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
{
/* Find the object attributes sections. For this we have to search
through the section table. */
Elf_Scn *scn = NULL;
/* Get the section header string table index. */
size_t shstrndx;
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
{
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
if (shdr == NULL || shdr->sh_type != SHT_GNU_ATTRIBUTES)
continue;
printf (gettext ("\
\nObject attributes section [%2zu] '%s' of %" PRIu64
" bytes at offset %#0" PRIx64 ":\n"),
elf_ndxscn (scn),
elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
shdr->sh_size, shdr->sh_offset);
Elf_Data *data = elf_rawdata (scn, NULL);
if (data == NULL)
return;
const unsigned char *p = data->d_buf;
if (unlikely (*p++ != 'A'))
return;
fputs_unlocked (gettext (" Owner Size\n"), stdout);
inline size_t left (void)
{
return (const unsigned char *) data->d_buf + data->d_size - p;
}
while (left () >= 4)
{
uint32_t len;
memcpy (&len, p, sizeof len);
if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
CONVERT (len);
if (unlikely (len > left ()))
break;
const unsigned char *name = p + sizeof len;
p += len;
unsigned const char *q = memchr (name, '\0', len);
if (unlikely (q == NULL))
continue;
++q;
printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
if (q - name == sizeof "gnu"
&& !memcmp (name, "gnu", sizeof "gnu"))
while (q < p)
{
const unsigned char *const sub = q;
unsigned int subsection_tag;
get_uleb128 (subsection_tag, q);
if (unlikely (q >= p))
break;
uint32_t subsection_len;
if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
break;
memcpy (&subsection_len, q, sizeof subsection_len);
if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
CONVERT (subsection_len);
if (unlikely (p - sub < subsection_len))
break;
const unsigned char *r = q + sizeof subsection_len;
q = sub + subsection_len;
switch (subsection_tag)
{
default:
printf (gettext (" %-4u %12" PRIu32 "\n"),
subsection_tag, subsection_len);
break;
case 1: /* Tag_File */
printf (gettext (" File: %11" PRIu32 "\n"),
subsection_len);
while (r < q)
{
unsigned int tag;
get_uleb128 (tag, r);
if (unlikely (r >= q))
break;
uint64_t value = 0;
const char *string = NULL;
if (tag == 32 || (tag & 1) == 0)
{
get_uleb128 (value, r);
if (r > q)
break;
}
if (tag == 32 || (tag & 1) != 0)
{
r = memchr (r, '\0', q - r);
if (r == NULL)
break;
++r;
}
const char *tag_name = NULL;
const char *value_name = NULL;
ebl_check_object_attribute (ebl, (const char *) name,
tag, value,
&tag_name, &value_name);
if (tag_name != NULL)
{
if (tag == 32)
printf (gettext (" %s: %" PRId64 ", %s\n"),
tag_name, value, string);
else if (string == NULL && value_name == NULL)
printf (gettext (" %s: %" PRId64 "\n"),
tag_name, value);
else
printf (gettext (" %s: %s\n"),
tag_name, string ?: value_name);
}
else
{
assert (tag != 32);
if (string == NULL)
printf (gettext (" %u: %" PRId64 "\n"),
tag, value);
else
printf (gettext (" %u: %s\n"),
tag, string);
}
}
}
}
}
}
}
static char *
format_dwarf_addr (Dwfl_Module *dwflmod,
@@ -5426,7 +5590,7 @@ compare_core_item_groups (const void *a, const void *b)
}
static unsigned int
handle_core_items (Elf *core, const void *desc,
handle_core_items (Elf *core, const void *desc, size_t descsz,
const Ebl_Core_Item *items, size_t nitems)
{
if (nitems == 0)
@@ -5450,18 +5614,35 @@ handle_core_items (Elf *core, const void *desc,
/* Write out all the groups. */
unsigned int colno = 0;
for (size_t i = 0; i < ngroups; ++i)
{
for (const Ebl_Core_Item **item = groups[i];
(item < &sorted_items[nitems]
&& ((*item)->group == groups[i][0]->group
|| !strcmp ((*item)->group, groups[i][0]->group)));
++item)
colno = handle_core_item (core, *item, desc, colno);
/* Force a line break at the end of the group. */
colno = ITEM_WRAP_COLUMN;
do
{
for (size_t i = 0; i < ngroups; ++i)
{
for (const Ebl_Core_Item **item = groups[i];
(item < &sorted_items[nitems]
&& ((*item)->group == groups[i][0]->group
|| !strcmp ((*item)->group, groups[i][0]->group)));
++item)
colno = handle_core_item (core, *item, desc, colno);
/* Force a line break at the end of the group. */
colno = ITEM_WRAP_COLUMN;
}
if (descsz == 0)
break;
/* This set of items consumed a certain amount of the note's data.
If there is more data there, we have another unit of the same size.
Loop to print that out too. */
const Ebl_Core_Item *item = &items[nitems - 1];
size_t eltsz = item->offset + gelf_fsize (core, item->type,
item->count ?: 1, EV_CURRENT);
descsz -= eltsz;
desc += eltsz;
}
while (descsz > 0);
return colno;
}
@@ -5807,7 +5988,13 @@ handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const void *desc)
&regs_offset, &nregloc, &reglocs, &nitems, &items))
return;
unsigned int colno = handle_core_items (ebl->elf, desc, items, nitems);
/* Pass 0 for DESCSZ when there are registers in the note,
so that the ITEMS array does not describe the whole thing.
For non-register notes, the actual descsz might be a multiple
of the unit size, not just exactly the unit size. */
unsigned int colno = handle_core_items (ebl->elf, desc,
nregloc == 0 ? nhdr->n_descsz : 0,
items, nitems);
if (colno != 0)
putchar_unlocked ('\n');
+6
View File
@@ -1,3 +1,9 @@
2008-02-20 Roland McGrath <roland@redhat.com>
* testfile46.bz2: New data file.
* Makefile.am (EXTRA_DIST): Add it.
* run-elflint-test.sh: Test on it.
2008-02-01 Ulrich Drepper <drepper@redhat.com>
* Makefile.am: Hook up sha1-tst.c.
+2 -1
View File
@@ -136,7 +136,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
testfile38.bz2 testfile39.bz2 testfile40.bz2 testfile40.debug.bz2 \
testfile41.bz2 testfile42.bz2 testfile43.bz2 \
testfile44.S.bz2 testfile44.expect.bz2 run-disasm-x86.sh \
testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh
testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh \
testfile46.bz2
installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \
bindir=$(DESTDIR)$(bindir) \
+4 -1
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# Copyright (C) 2005, 2007 Red Hat, Inc.
# Copyright (C) 2005, 2007, 2008 Red Hat, Inc.
# This file is part of Red Hat elfutils.
# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
#
@@ -41,4 +41,7 @@ testrun ../src/elflint -q testfile33
testfiles testfile42
testrun ../src/elflint -q --gnu-ld testfile42
testfiles testfile47
testrun ../src/elflint -q testfile47
exit 0
Binary file not shown.