diff options
author | Roland McGrath <roland@redhat.com> | 2007-08-23 08:10:54 +0000 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2007-08-23 08:10:54 +0000 |
commit | cb6d865011ad98a8ac2018f072f396a2268739ca (patch) | |
tree | c497c4dacb592f9da5f5740a8b9fa8d362468079 /libebl | |
parent | 50c6a2f8b9621ae01c8943e80c39bc859c9d5c22 (diff) | |
download | elfutils-cb6d865011ad98a8ac2018f072f396a2268739ca.tar.gz |
readelf register printing sort order tweak
Diffstat (limited to 'libebl')
-rw-r--r-- | libebl/ChangeLog | 20 | ||||
-rw-r--r-- | libebl/Makefile.am | 2 | ||||
-rw-r--r-- | libebl/ebl-hooks.h | 9 | ||||
-rw-r--r-- | libebl/eblauxvinfo.c | 121 | ||||
-rw-r--r-- | libebl/eblcorenote.c | 207 | ||||
-rw-r--r-- | libebl/eblopenbackend.c | 39 | ||||
-rw-r--r-- | libebl/libebl.h | 41 |
7 files changed, 254 insertions, 185 deletions
diff --git a/libebl/ChangeLog b/libebl/ChangeLog index a48f8e33..c93e7047 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,23 @@ +2007-08-22 Roland McGrath <roland@redhat.com> + + * libebl.h (Ebl_Core_Item): New member `group'. + +2007-08-19 Roland McGrath <roland@redhat.com> + + * ebl-hooks.h: Add new hook auxv_info. + * eblopenbackend.c (default_auxv_info): New function. + (fill_defaults): Initialize auxv_info hook. + * eblauxvinfo.c : New file. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h: Declare ebl_auxv_info. + + * eblcorenote.c: Rewritten with new signature. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h (Ebl_Register_Location, Ebl_Core_Item): New types. + (ebl_core_note_info): Completely revamp signature. + * ebl-hooks.h: Update decl. + * eblopenbackend.c (default_core_note): Update signature. + 2007-07-09 Roland McGrath <roland@redhat.com> * eblobjnotetypename.c (ebl_object_note_type_name): Handle diff --git a/libebl/Makefile.am b/libebl/Makefile.am index 741e5eee..993800ca 100644 --- a/libebl/Makefile.am +++ b/libebl/Makefile.am @@ -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 + eblsysvhashentrysize.c eblauxvinfo.c libebl_a_SOURCES = $(gen_SOURCES) diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index 5344df09..d466a1f3 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -107,12 +107,17 @@ const char *EBLHOOK(core_note_type_name) (uint32_t, char *, size_t); /* Name of a note entry type for object files. */ const char *EBLHOOK(object_note_type_name) (uint32_t, char *, size_t); -/* Handle core note. */ -bool EBLHOOK(core_note) (const char *, uint32_t, uint32_t, const char *); +/* Describe core note format. */ +int EBLHOOK(core_note) (GElf_Word, GElf_Word, GElf_Word *, size_t *, + const Ebl_Register_Location **, + size_t *, const Ebl_Core_Item **); /* Handle object file note. */ bool EBLHOOK(object_note) (const char *, uint32_t, uint32_t, const char *); +/* Describe auxv element type. */ +int EBLHOOK(auxv_info) (GElf_Xword, const char **, const char **); + /* Check section name for being that of a debug informatino section. */ bool EBLHOOK(debugscn_p) (const char *); diff --git a/libebl/eblauxvinfo.c b/libebl/eblauxvinfo.c new file mode 100644 index 00000000..54583f9f --- /dev/null +++ b/libebl/eblauxvinfo.c @@ -0,0 +1,121 @@ +/* Describe known auxv types. + Copyright (C) 2007 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 <assert.h> +#include <byteswap.h> +#include <endian.h> +#include <inttypes.h> +#include <stdio.h> +#include <stddef.h> +#include <libeblP.h> + +#define AUXV_TYPES \ + TYPE (NULL, "") \ + TYPE (IGNORE, "") \ + TYPE (EXECFD, "d") \ + TYPE (PHDR, "p") \ + TYPE (PHENT, "u") \ + TYPE (PHNUM, "u") \ + TYPE (PAGESZ, "u") \ + TYPE (BASE, "p") \ + TYPE (FLAGS, "x") \ + TYPE (ENTRY, "p") \ + TYPE (NOTELF, "") \ + TYPE (UID, "u") \ + TYPE (EUID, "u") \ + TYPE (GID, "u") \ + TYPE (EGID, "u") \ + TYPE (CLKTCK, "u") \ + TYPE (PLATFORM, "s") \ + TYPE (HWCAP, "x") \ + TYPE (FPUCW, "x") \ + TYPE (DCACHEBSIZE, "d") \ + TYPE (ICACHEBSIZE, "d") \ + TYPE (UCACHEBSIZE, "d") \ + TYPE (IGNOREPPC, "") \ + TYPE (SECURE, "u") \ + TYPE (SYSINFO, "p") \ + TYPE (SYSINFO_EHDR, "p") \ + TYPE (L1I_CACHESHAPE, "d") \ + TYPE (L1D_CACHESHAPE, "d") \ + TYPE (L2_CACHESHAPE, "d") \ + TYPE (L3_CACHESHAPE, "d") + +static const struct +{ + const char *name, *format; +} auxv_types[] = + { +#define TYPE(name, fmt) [AT_##name] = { #name, fmt }, + AUXV_TYPES +#undef TYPE + }; +#define nauxv_types (sizeof auxv_types / sizeof auxv_types[0]) + +int +ebl_auxv_info (ebl, a_type, name, format) + Ebl *ebl; + GElf_Xword a_type; + const char **name; + const char **format; +{ + int result = ebl->auxv_info (a_type, name, format); + if (result == 0 && a_type < nauxv_types) + { + /* The machine specific function did not know this type. */ + *name = auxv_types[a_type].name; + *format = auxv_types[a_type].format; + result = 1; + } + return result; +} diff --git a/libebl/eblcorenote.c b/libebl/eblcorenote.c index 9eb355f8..553d5ba9 100644 --- a/libebl/eblcorenote.c +++ b/libebl/eblcorenote.c @@ -1,7 +1,6 @@ -/* Print contents of core note. - Copyright (C) 2002, 2004, 2005, 2007 Red Hat, Inc. +/* Describe known core note formats. + Copyright (C) 2007 Red Hat, Inc. This file is part of Red Hat elfutils. - Written by Ulrich Drepper <drepper@redhat.com>, 2002. 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 @@ -61,174 +60,48 @@ #include <libeblP.h> -void -ebl_core_note (ebl, name, type, descsz, desc) +int +ebl_core_note (ebl, n_type, descsz, + regs_offset, nregloc, reglocs, nitems, items) Ebl *ebl; - const char *name; - uint32_t type; - uint32_t descsz; - const char *desc; + GElf_Word n_type; + GElf_Word descsz; + GElf_Word *regs_offset; + size_t *nregloc; + const Ebl_Register_Location **reglocs; + size_t *nitems; + const Ebl_Core_Item **items; { - GElf_Ehdr ehdr_mem; - GElf_Ehdr *ehdr = gelf_getehdr (ebl->elf, &ehdr_mem); - assert (ehdr != NULL); - int class = ehdr->e_ident[EI_CLASS]; - int endian = ehdr->e_ident[EI_DATA]; - - if (! ebl->core_note (name, type, descsz, desc)) - /* The machine specific function did not know this type. */ - switch (type) - { - case NT_PLATFORM: - printf (gettext (" Platform: %.*s\n"), (int) descsz, desc); - break; - - case NT_AUXV: - ; - size_t elsize = (class == ELFCLASS32 - ? sizeof (Elf32_auxv_t) : sizeof (Elf64_auxv_t)); - - for (size_t cnt = 0; (cnt + 1) * elsize <= descsz; ++cnt) - { - uintmax_t atype; - uintmax_t val; - - if (class == ELFCLASS32) - { - Elf32_auxv_t *auxv = &((Elf32_auxv_t *) desc)[cnt]; - - if ((endian == ELFDATA2LSB && __BYTE_ORDER == __LITTLE_ENDIAN) - || (endian == ELFDATA2MSB && __BYTE_ORDER == __BIG_ENDIAN)) - { - atype = auxv->a_type; - val = auxv->a_un.a_val; - } - else - { - atype = bswap_32 (auxv->a_type); - val = bswap_32 (auxv->a_un.a_val); - } - } - else - { - Elf64_auxv_t *auxv = &((Elf64_auxv_t *) desc)[cnt]; - - if ((endian == ELFDATA2LSB && __BYTE_ORDER == __LITTLE_ENDIAN) - || (endian == ELFDATA2MSB && __BYTE_ORDER == __BIG_ENDIAN)) - { - atype = auxv->a_type; - val = auxv->a_un.a_val; - } - else - { - atype = bswap_64 (auxv->a_type); - val = bswap_64 (auxv->a_un.a_val); - } - } - - /* XXX Do we need the auxiliary vector info anywhere - else? If yes, move code into a separate function. */ - const char *at; - - switch (atype) + int result = ebl->core_note (n_type, descsz, regs_offset, nregloc, reglocs, + nitems, items); + if (result == 0) + { + /* The machine specific function did not know this type. */ + + *regs_offset = 0; + *nregloc = 0; + *reglocs = NULL; + switch (n_type) + { +#define ITEMS(type, table) \ + case type: \ + *items = table; \ + *nitems = sizeof table / sizeof table[0]; \ + result = 1; \ + break + + static const Ebl_Core_Item platform[] = + { { -#define NEW_AT(name) case AT_##name: at = #name; break - NEW_AT (NULL); - NEW_AT (IGNORE); - NEW_AT (EXECFD); - NEW_AT (PHDR); - NEW_AT (PHENT); - NEW_AT (PHNUM); - NEW_AT (PAGESZ); - NEW_AT (BASE); - NEW_AT (FLAGS); - NEW_AT (ENTRY); - NEW_AT (NOTELF); - NEW_AT (UID); - NEW_AT (EUID); - NEW_AT (GID); - NEW_AT (EGID); - NEW_AT (CLKTCK); - NEW_AT (PLATFORM); - NEW_AT (HWCAP); - NEW_AT (FPUCW); - NEW_AT (DCACHEBSIZE); - NEW_AT (ICACHEBSIZE); - NEW_AT (UCACHEBSIZE); - NEW_AT (IGNOREPPC); - NEW_AT (SECURE); - NEW_AT (SYSINFO); - NEW_AT (SYSINFO_EHDR); - NEW_AT (L1I_CACHESHAPE); - NEW_AT (L1D_CACHESHAPE); - NEW_AT (L2_CACHESHAPE); - NEW_AT (L3_CACHESHAPE); - - default:; - static char buf[30]; - sprintf (buf, "%ju (AT_?""?""?)", atype); - at = buf; - break; - } - - switch (atype) - { - /* Decimal. */ - case AT_EXECFD: - case AT_PHENT: - case AT_PHNUM: - case AT_PAGESZ: - case AT_UID: - case AT_EUID: - case AT_GID: - case AT_EGID: - case AT_CLKTCK: - case AT_FPUCW: - case AT_DCACHEBSIZE: - case AT_ICACHEBSIZE: - case AT_UCACHEBSIZE: - case AT_SECURE: - case AT_L1I_CACHESHAPE: - case AT_L1D_CACHESHAPE: - case AT_L2_CACHESHAPE: - case AT_L3_CACHESHAPE: - printf (" %s: %jd\n", at, val); - break; - - /* Normally zero. */ - case AT_NULL: - case AT_IGNORE: - case AT_IGNOREPPC: - case AT_NOTELF: - default: - if (val == 0) - { - printf (" %s\n", at); - break; - } - /* Fall through. */ - - /* Hex. */ - case AT_PHDR: - case AT_BASE: - case AT_FLAGS: /* XXX Print flags? */ - case AT_ENTRY: - case AT_PLATFORM: /* XXX Get string? */ - case AT_HWCAP: /* XXX Print flags? */ - case AT_SYSINFO: - case AT_SYSINFO_EHDR: - printf (" %s: %#jx\n", at, val); - break; + .name = "Platform", + .type = ELF_T_BYTE, .count = 0, .format = 's' } + }; + ITEMS (NT_PLATFORM, platform); - if (atype == AT_NULL) - /* Reached the end. */ - break; - } - break; +#undef ITEMS + } + } - default: - /* Unknown type. */ - break; - } + return result; } diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index 5b1a7193..63e64a10 100644 --- a/libebl/eblopenbackend.c +++ b/libebl/eblopenbackend.c @@ -186,8 +186,12 @@ static const char *default_core_note_type_name (uint32_t, char *buf, size_t len); static const char *default_object_note_type_name (uint32_t, char *buf, size_t len); -static bool default_core_note (const char *name, uint32_t type, - uint32_t descsz, const char *desc); +static int default_core_note (GElf_Word n_type, GElf_Word descsz, + GElf_Word *regs_offset, size_t *nregloc, + const Ebl_Register_Location **reglocs, + size_t *nitems, const Ebl_Core_Item **); +static int default_auxv_info (GElf_Xword a_type, + const char **name, const char **format); static bool default_object_note (const char *name, uint32_t type, uint32_t descsz, const char *desc); static bool default_debugscn_p (const char *name); @@ -232,6 +236,7 @@ fill_defaults (Ebl *result) result->core_note_type_name = default_core_note_type_name; result->object_note_type_name = default_object_note_type_name; result->core_note = default_core_note; + result->auxv_info = default_auxv_info; result->object_note = default_object_note; result->debugscn_p = default_debugscn_p; result->copy_reloc_p = default_copy_reloc_p; @@ -567,6 +572,27 @@ default_core_note_type_name (uint32_t ignore __attribute__ ((unused)), return NULL; } +static int +default_auxv_info (GElf_Xword a_type __attribute__ ((unused)), + const char **name __attribute__ ((unused)), + const char **format __attribute__ ((unused))) +{ + return 0; +} + +static int +default_core_note (GElf_Word n_type __attribute__ ((unused)), + GElf_Word descsz __attribute__ ((unused)), + GElf_Word *ro __attribute__ ((unused)), + size_t *nregloc __attribute__ ((unused)), + const Ebl_Register_Location **reglocs + __attribute__ ((unused)), + size_t *nitems __attribute__ ((unused)), + const Ebl_Core_Item **items __attribute__ ((unused))) +{ + return 0; +} + static const char * default_object_note_type_name (uint32_t ignore __attribute__ ((unused)), char *buf __attribute__ ((unused)), @@ -576,15 +602,6 @@ default_object_note_type_name (uint32_t ignore __attribute__ ((unused)), } static bool -default_core_note (const char *name __attribute__ ((unused)), - uint32_t type __attribute__ ((unused)), - uint32_t descsz __attribute__ ((unused)), - const char *desc __attribute__ ((unused))) -{ - return NULL; -} - -static bool default_object_note (const char *name __attribute__ ((unused)), uint32_t type __attribute__ ((unused)), uint32_t descsz __attribute__ ((unused)), diff --git a/libebl/libebl.h b/libebl/libebl.h index 1465fb1a..7e29168d 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -178,10 +178,6 @@ extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf, extern const char *ebl_object_note_type_name (Ebl *ebl, uint32_t type, char *buf, size_t len); -/* Print information about core note if available. */ -extern void ebl_core_note (Ebl *ebl, const char *name, uint32_t type, - uint32_t descsz, const char *desc); - /* Print information about object note if available. */ extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type, uint32_t descsz, const char *desc); @@ -306,6 +302,43 @@ extern void ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data); /* Get offset in wide char string table for string associated with SE. */ extern size_t ebl_gstrtaboffset (struct Ebl_GStrent *se); + +/* Register map info. */ +typedef struct +{ + Dwarf_Half offset; /* Byte offset in register data block. */ + Dwarf_Half regno; /* DWARF register number. */ + uint8_t bits; /* Bits of data for one register. */ + uint8_t pad; /* Bytes of padding after register's data. */ + Dwarf_Half count; /* Consecutive register numbers here. */ +} Ebl_Register_Location; + +/* Non-register data items in core notes. */ +typedef struct +{ + const char *name; /* Printable identifier. */ + const char *group; /* Identifier for category of related items. */ + Dwarf_Half offset; /* Byte offset in note data. */ + Dwarf_Half count; + Elf_Type type; + char format; + bool thread_identifier; +} Ebl_Core_Item; + +/* Describe the format of a core file note with type field matching N_TYPE + and descriptor size matching DESCSZ. */ +extern int ebl_core_note (Ebl *ebl, GElf_Word n_type, GElf_Word descsz, + GElf_Word *regs_offset, size_t *nregloc, + const Ebl_Register_Location **reglocs, + size_t *nitems, const Ebl_Core_Item **items) + __nonnull_attribute__ (1, 4, 5, 6, 7, 8); + +/* Describe the auxv type number. */ +extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type, + const char **name, const char **format) + __nonnull_attribute__ (1, 3, 4); + + #ifdef __cplusplus } #endif |