summaryrefslogtreecommitdiff
path: root/libebl
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2007-08-23 08:10:54 +0000
committerRoland McGrath <roland@redhat.com>2007-08-23 08:10:54 +0000
commitcb6d865011ad98a8ac2018f072f396a2268739ca (patch)
treec497c4dacb592f9da5f5740a8b9fa8d362468079 /libebl
parent50c6a2f8b9621ae01c8943e80c39bc859c9d5c22 (diff)
downloadelfutils-cb6d865011ad98a8ac2018f072f396a2268739ca.tar.gz
readelf register printing sort order tweak
Diffstat (limited to 'libebl')
-rw-r--r--libebl/ChangeLog20
-rw-r--r--libebl/Makefile.am2
-rw-r--r--libebl/ebl-hooks.h9
-rw-r--r--libebl/eblauxvinfo.c121
-rw-r--r--libebl/eblcorenote.c207
-rw-r--r--libebl/eblopenbackend.c39
-rw-r--r--libebl/libebl.h41
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