]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf register printing sort order tweak
authorRoland McGrath <roland@redhat.com>
Thu, 23 Aug 2007 08:10:54 +0000 (08:10 +0000)
committerRoland McGrath <roland@redhat.com>
Thu, 23 Aug 2007 08:10:54 +0000 (08:10 +0000)
42 files changed:
backends/ChangeLog
backends/Makefile.am
backends/alpha_corenote.c [new file with mode: 0644]
backends/alpha_init.c
backends/i386_auxv.c [new file with mode: 0644]
backends/i386_corenote.c
backends/i386_init.c
backends/linux-core-note.c [new file with mode: 0644]
backends/ppc64_corenote.c [new file with mode: 0644]
backends/ppc64_init.c
backends/ppc_auxv.c [new file with mode: 0644]
backends/ppc_corenote.c [new file with mode: 0644]
backends/ppc_init.c
backends/ppc_symbol.c
backends/x86_64_corenote.c
backends/x86_64_init.c
backends/x86_64_regs.c
libebl/ChangeLog
libebl/Makefile.am
libebl/ebl-hooks.h
libebl/eblauxvinfo.c [new file with mode: 0644]
libebl/eblcorenote.c
libebl/eblopenbackend.c
libebl/libebl.h
libelf/ChangeLog
libelf/Makefile.am
libelf/abstract.h
libelf/exttypes.h
libelf/gelf.h
libelf/gelf_fsize.c
libelf/gelf_getauxv.c [new file with mode: 0644]
libelf/gelf_update_auxv.c [new file with mode: 0644]
libelf/gelf_xlate.c
libelf/gelf_xlate.h
libelf/libelf.h
libelf/libelf.map
src/ChangeLog
src/nm.c
src/readelf.c
src/unstrip.c
tests/ChangeLog
tests/run-allregs.sh

index 994aec07d4629246fc3430500cf7216ba00da628..159e6dc1773f6b2aca8b311c99a8716b02520359 100644 (file)
@@ -1,3 +1,46 @@
+2007-08-23  Roland McGrath  <roland@redhat.com>
+
+       * x86_64_regs.c (x86_64_register_info): Put %rflags in "integer" set.
+
+2007-08-22  Roland McGrath  <roland@redhat.com>
+
+       * linux-core-note.c (prstatus_items): Add .group initializers.
+       (prpsinfo_items): Likewise.
+       * x86_64_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise.
+       * i386_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise.
+       * ppc_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise.
+
+2007-08-20  Roland McGrath  <roland@redhat.com>
+
+       * ppc_symbol.c (ppc_check_special_symbol): For _GLOBAL_OFFSET_TABLE_
+       when DT_PPC_GOT is not found, anywhere in the section is valid.
+
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+       * i386_auxv.c: New file.
+       * Makefile.am (i386_SRCS, x86_64_SRCS): Add it.
+       * ppc_auxv.c: New file.
+       * Makefile.am (ppc_SRCS, ppc64_SRCS): Add it.
+       * i386_init.c (i386_init): Initialize auxv_info hook.
+       * x86_64_init.c (x86_64_init): Likewise.
+       * ppc_init.c (ppc_init): Likewise.
+       * ppc64_init.c (ppc64_init): Likewise.
+
+       * alpha_corenote.c: New file.
+       * Makefile.am (alpha_SRCS): Add it.
+       * alpha_init.c (alpha_init): Initialize core_note hook.
+
+       * ppc_corenote.c: New file.
+       * ppc64_corenote.c: New file.
+       * Makefile.am (ppc_SRCS, ppc64_SRCS): Add them.
+       * ppc_init.c (ppc_init): Initialize core_note hook.
+       * ppc64_init.c (ppc64_init): Likewise.
+
+       * linux-core-note.c: New file.
+       * Makefile.am (noinst_HEADERS): Add it.
+       * i386_corenote.c: Rewritten.
+       * x86_64_corenote.c: Likewise.
+
 2007-05-23  Roland McGrath  <roland@redhat.com>
 
        * alpha_regs.c (alpha_register_info): fp -> s6
index f7e1525d848363ea41375a481f311a7ecd15c3f7..84aa47852f1649df2a9c7be215a99f11ac42a559 100644 (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 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -70,7 +70,7 @@ libebl_%.map: Makefile
 
 
 i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c \
-           i386_retval.c i386_regs.c
+           i386_retval.c i386_regs.c i386_auxv.c
 libebl_i386_pic_a_SOURCES = $(i386_SRCS)
 am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
 
@@ -79,7 +79,7 @@ libebl_sh_pic_a_SOURCES = $(sh_SRCS)
 am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
 
 x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c \
-             x86_64_retval.c x86_64_regs.c
+             x86_64_retval.c x86_64_regs.c i386_auxv.c
 libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
 am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
 
@@ -87,7 +87,8 @@ ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c
 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_SRCS = alpha_init.c alpha_symbol.c alpha_retval.c alpha_regs.c \
+            alpha_corenote.c
 libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
 am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
 
@@ -99,11 +100,13 @@ sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c sparc_retval.c
 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_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c ppc_regs.c \
+          ppc_corenote.c ppc_auxv.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 ppc_regs.c
+ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
+            ppc64_corenote.c ppc_regs.c ppc_auxv.c
 libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
 am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
 
@@ -134,7 +137,7 @@ uninstall: uninstall-am
        done
        rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
 
-noinst_HEADERS = libebl_CPU.h common-reloc.c
+noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c
 EXTRA_DIST = $(foreach m,$(modules),$($(m)_SRCS)) $(modules:=_reloc.def)
 
 CLEANFILES = *.gcno *.gcda \
diff --git a/backends/alpha_corenote.c b/backends/alpha_corenote.c
new file mode 100644 (file)
index 0000000..dcc62e9
--- /dev/null
@@ -0,0 +1,67 @@
+/* PowerPC specific core note handling.
+   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.
+
+   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 <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND        alpha_
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    { .offset = 0, .regno = 0, .count = 31, .bits = 64 }, /* r0-r30 */
+    { .offset = 32 * 8, .regno = 64, .count = 1, .bits = 64 }, /* pc */
+    { .offset = 33 * 8, .regno = 66, .count = 1, .bits = 64 }, /* unique */
+  };
+#define PRSTATUS_REGS_SIZE     (33 * 8)
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 32, .count = 32, .bits = 64 }, /* f0-f30, fpcr */
+  };
+#define FPREGSET_SIZE          (32 * 8)
+
+#define ULONG                  uint64_t
+#define ALIGN_ULONG            8
+#define TYPE_ULONG             ELF_T_XWORD
+#define TYPE_LONG              ELF_T_SXWORD
+#define PID_T                  int32_t
+#define        UID_T                   uint32_t
+#define        GID_T                   uint32_t
+#define ALIGN_PID_T            4
+#define ALIGN_UID_T            4
+#define ALIGN_GID_T            4
+#define TYPE_PID_T             ELF_T_SWORD
+#define TYPE_UID_T             ELF_T_WORD
+#define TYPE_GID_T             ELF_T_WORD
+
+#include "linux-core-note.c"
index ba5ca12fcf03e84f9af4e600466a6ef81160ff2f..794d412a8efe187731cda9071e928a50ca60786e 100644 (file)
@@ -54,8 +54,9 @@ alpha_init (elf, machine, eh, ehlen)
   HOOK (eh, dynamic_tag_check);
   HOOK (eh, reloc_simple_type);
   HOOK (eh, return_value_location);
-  HOOK (eh, register_info);
   HOOK (eh, machine_section_flag_check);
+  HOOK (eh, register_info);
+  HOOK (eh, core_note);
   eh->sysvhash_entrysize = sizeof (Elf64_Xword);
 
   return MODVERSION;
diff --git a/backends/i386_auxv.c b/backends/i386_auxv.c
new file mode 100644 (file)
index 0000000..5f7b15e
--- /dev/null
@@ -0,0 +1,49 @@
+/* i386 specific auxv handling.
+   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.
+
+   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 i386_
+#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"
+    "fpu\0" "vme\0" "de\0" "pse\0" "tsc\0" "msr\0" "pae\0" "mce\0"
+    "cx8\0" "apic\0" "10\0" "sep\0" "mtrr\0" "pge\0" "mca\0" "cmov\0"
+    "pat\0" "pse36\0" "pn\0" "clflush\0" "20\0" "dts\0" "acpi\0" "mmx\0"
+    "fxsr\0" "sse\0" "sse2\0" "ss\0" "ht\0" "tm\0" "ia64\0" "pbe\0" "\0";
+  return 1;
+}
+
+__typeof (i386_auxv_info) x86_64_auxv_info
+                         __attribute__ ((alias ("i386_auxv_info")));
index c9d3e5fb2108c99c64bd303396c6b59638959558..cc72a45f67365a45fa7454a24e4b65a30c2e59ec 100644 (file)
@@ -1,7 +1,6 @@
 /* i386 specific core note handling.
-   Copyright (C) 2002, 2005 Red Hat, Inc.
+   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
 #include "libebl_CPU.h"
 
 
-/* We cannot include <sys/procfs.h> since the definition would be for
-   the host platform and not always x86 as required here.  */
-struct elf_prstatus
+static const Ebl_Register_Location prstatus_regs[] =
   {
-    struct
-    {
-      int32_t si_signo;                        /* Signal number.  */
-      int32_t si_code;                 /* Extra code.  */
-      int32_t si_errno;                        /* Errno.  */
-    } pr_info;                         /* Info associated with signal.  */
-    int16_t pr_cursig;                 /* Current signal.  */
-    uint32_t pr_sigpend;               /* Set of pending signals.  */
-    uint32_t pr_sighold;               /* Set of held signals.  */
-    int32_t pr_pid;
-    int32_t pr_ppid;
-    int32_t pr_pgrp;
-    int32_t pr_sid;
-    struct i386_timeval
-    {
-      int32_t tv_sec;
-      int32_t tv_usec;
-    } pr_utime;                                /* User time.  */
-    struct i386_timeval pr_stime;      /* System time.  */
-    struct i386_timeval pr_cutime;     /* Cumulative user time.  */
-    struct i386_timeval pr_cstime;     /* Cumulative system time.  */
-    uint32_t pr_reg[17];               /* GP registers.  */
-    int32_t pr_fpvalid;                        /* True if math copro being used.  */
+#define GR(at, n, dwreg)                                               \
+    { .offset = at * 4, .regno = dwreg, .count = n, .bits = 32 }
+#define SR(at, n, dwreg)                                               \
+    { .offset = at * 4, .regno = dwreg, .count = n, .bits = 16, .pad = 2 }
+
+    GR (0, 1, 3),              /* %ebx */
+    GR (1, 2, 1),              /* %ecx-%edx */
+    GR (3, 2, 6),              /* %esi-%edi */
+    GR (5, 1, 5),              /* %ebp */
+    GR (6, 1, 0),              /* %eax */
+    SR (7, 1, 43),             /* %ds */
+    SR (8, 1, 40),             /* %es */
+    SR (9, 1, 44),             /* %fs */
+    SR (10, 1, 45),            /* %gs */
+    /*  11, 1,                    orig_eax */
+    GR (12, 1, 8),             /* %eip */
+    SR (13, 1, 41),            /* %cs */
+    GR (14, 1, 9),             /* eflags */
+    GR (15, 1, 4),             /* %esp */
+    SR (16, 1, 42),            /* %ss */
+
+#undef GR
+#undef SR
   };
-
-
-struct elf_prpsinfo
+#define PRSTATUS_REGS_SIZE     (17 * 4)
+
+#define        ULONG                   uint32_t
+#define PID_T                  int32_t
+#define        UID_T                   uint16_t
+#define        GID_T                   uint16_t
+#define ALIGN_ULONG            4
+#define ALIGN_PID_T            4
+#define ALIGN_UID_T            2
+#define ALIGN_GID_T            2
+#define TYPE_ULONG             ELF_T_WORD
+#define TYPE_PID_T             ELF_T_SWORD
+#define TYPE_UID_T             ELF_T_HALF
+#define TYPE_GID_T             ELF_T_HALF
+
+#define PRSTATUS_REGSET_ITEMS                                                \
+  {                                                                          \
+    .name = "orig_eax", .type = ELF_T_SWORD, .format = 'd',                  \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 11),        \
+    .group = "register"                                                              \
+  }
+
+static const Ebl_Register_Location fpregset_regs[] =
   {
-    char pr_state;                     /* Numeric process state.  */
-    char pr_sname;                     /* Char for pr_state.  */
-    char pr_zomb;                      /* Zombie.  */
-    char pr_nice;                      /* Nice val.  */
-    uint32_t pr_flag;                  /* Flags.  */
-    uint16_t pr_uid;
-    uint16_t pr_gid;
-    int32_t pr_pid;
-    int32_t pr_ppid;
-    int32_t pr_pgrp;
-    int32_t pr_sid;
-    /* Lots missing */
-    char pr_fname[16];                 /* Filename of executable.  */
-    char pr_psargs[80];                        /* Initial part of arg list.  */
+    { .offset = 0, .regno = 37, .count = 2, .bits = 32 }, /* fctrl-fstat */
+    { .offset = 7 * 4, .regno = 11, .count = 8, .bits = 80 }, /* stN */
   };
+#define FPREGSET_SIZE  108
 
+static const Ebl_Register_Location prxfpreg_regs[] =
+  {
+    { .offset = 0, .regno = 37, .count = 2, .bits = 16 }, /* fctrl-fstat */
+    { .offset = 24, .regno = 39, .count = 1, .bits = 32 }, /* mxcsr */
+    { .offset = 32, .regno = 11, .count = 8, .bits = 80, .pad = 6 }, /* stN */
+    { .offset = 32 + 128, .regno = 21, .count = 8, .bits = 128 }, /* xmm */
+  };
+#define PRXFPREG_SIZE  512
 
-bool
-i386_core_note (name, type, descsz, desc)
-     const char *name __attribute__ ((unused));
-     uint32_t type;
-     uint32_t descsz;
-     const char *desc;
-{
-  bool result = false;
-
-  switch (type)
-    {
-    case NT_PRSTATUS:
-      if (descsz < sizeof (struct elf_prstatus))
-       /* Not enough data.  */
-       break;
-
-      struct elf_prstatus *stat = (struct elf_prstatus *) desc;
-
-      printf ("    SIGINFO:  signo: %" PRId32 ", code = %" PRId32
-             ", errno = %" PRId32 "\n"
-             "    signal: %" PRId16 ", pending: %08" PRIx32
-             ", holding: %8" PRIx32 "\n"
-             "    pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
-             ", sid = %"  PRId32 "\n"
-             "     utime: %6" PRId32 ".%06" PRId32
-             "s,  stime: %6" PRId32 ".%06" PRId32 "s\n"
-             "    cutime: %6" PRId32 ".%06" PRId32
-             "s, cstime: %6" PRId32 ".%06" PRId32 "s\n"
-             "    eax: %08" PRIx32 "  ebx: %08" PRIx32 "  ecx: %08" PRIx32
-             "  edx: %08" PRIx32 "\n"
-             "    esi: %08" PRIx32 "  edi: %08" PRIx32 "  ebp: %08" PRIx32
-             "  esp: %08" PRIx32 "\n"
-             "    eip: %08" PRIx32 "  eflags: %08" PRIx32
-             "  original eax: %08" PRIx32 "\n"
-             "    cs: %04" PRIx32 "  ds: %04" PRIx32 "  es: %04" PRIx32
-             "  fs: %04" PRIx32 "  gs: %04" PRIx32 "  ss: %04" PRIx32 "\n\n",
-             stat->pr_info.si_signo,
-             stat->pr_info.si_code,
-             stat->pr_info.si_errno,
-             stat->pr_cursig,
-             stat->pr_sigpend, stat->pr_sighold,
-             stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
-             stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
-             stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
-             stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
-             stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
-             stat->pr_reg[6], stat->pr_reg[0], stat->pr_reg[1],
-             stat->pr_reg[2], stat->pr_reg[3], stat->pr_reg[4],
-             stat->pr_reg[5], stat->pr_reg[15], stat->pr_reg[12],
-             stat->pr_reg[14], stat->pr_reg[11], stat->pr_reg[13] & 0xffff,
-             stat->pr_reg[7] & 0xffff, stat->pr_reg[8] & 0xffff,
-             stat->pr_reg[9] & 0xffff, stat->pr_reg[10] & 0xffff,
-             stat->pr_reg[16]);
-
-      /* We handled this entry.  */
-      result = true;
-      break;
-
-    case NT_PRPSINFO:
-      if (descsz < sizeof (struct elf_prpsinfo))
-       /* Not enough data.  */
-       break;
-
-      struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
-
-      printf ("    state: %c (%hhd),  zombie: %hhd,  nice: %hhd\n"
-             "    flags: %08" PRIx32 ",  uid: %" PRId16 ",  gid: %" PRId16"\n"
-             "    pid: %" PRId32 ",  ppid: %" PRId32 ",  pgrp: %" PRId32
-             ",  sid: %" PRId32 "\n"
-             "    fname: %.16s\n"
-             "     args: %.80s\n\n",
-             info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
-             info->pr_flag, info->pr_uid, info->pr_gid,
-             info->pr_pid, info->pr_ppid, info->pr_pgrp, info->pr_sid,
-             info->pr_fname, info->pr_psargs);
-
-      /* We handled this entry.  */
-      result = true;
-      break;
-
-    default:
-      break;
-    }
-
-  return result;
-}
+#include "linux-core-note.c"
index 9f240075f392f74f5ccde34e413bd13aad3cebb0..f25e1eb99b9859d5b6bd2657ca3728debf1dab47 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of i386 specific backend library.
-   Copyright (C) 2000, 2001, 2002, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -56,6 +56,7 @@ i386_init (elf, machine, eh, ehlen)
   HOOK (eh, debugscn_p);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, auxv_info);
 
   return MODVERSION;
 }
diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c
new file mode 100644 (file)
index 0000000..0913cc9
--- /dev/null
@@ -0,0 +1,218 @@
+/* Common core note type descriptions for Linux.
+   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.
+
+   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>.  */
+
+/* The including CPU_corenote.c file provides prstatus_regs and
+   defines macros ULONG, [PUG]ID_T, and ALIGN_*, TYPE_*.
+
+   Here we describe the common layout used in <linux/elfcore.h>.  */
+
+#define        CHAR                    int8_t
+#define        ALIGN_CHAR              1
+#define        TYPE_CHAR               ELF_T_BYTE
+#define        SHORT                   uint16_t
+#define ALIGN_SHORT            2
+#define TYPE_SHORT             ELF_T_HALF
+#define        INT                     int32_t
+#define ALIGN_INT              4
+#define TYPE_INT               ELF_T_SWORD
+
+#define FIELD(type, name) type name __attribute__ ((aligned (ALIGN_##type)))
+
+struct EBLHOOK(siginfo)
+{
+  FIELD (INT, si_signo);
+  FIELD (INT, si_code);
+  FIELD (INT, si_errno);
+};
+
+struct EBLHOOK(timeval)
+{
+  FIELD (ULONG, tv_sec);
+  FIELD (ULONG, tv_usec);
+};
+
+struct EBLHOOK(prstatus)
+{
+  struct EBLHOOK(siginfo) pr_info;
+  FIELD (SHORT, pr_cursig);
+  FIELD (ULONG, pr_sigpend);
+  FIELD (ULONG, pr_sighold);
+  FIELD (PID_T, pr_pid);
+  FIELD (PID_T, pr_ppid);
+  FIELD (PID_T, pr_pgrp);
+  FIELD (PID_T, pr_sid);
+  struct EBLHOOK(timeval) pr_utime;
+  struct EBLHOOK(timeval) pr_stime;
+  struct EBLHOOK(timeval) pr_cutime;
+  struct EBLHOOK(timeval) pr_cstime;
+  FIELD (ULONG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (ULONG)]);
+  FIELD (INT, pr_fpvalid);
+};
+
+#define        FNAMESZ 16
+#define        PRARGSZ 80
+
+struct EBLHOOK(prpsinfo)
+{
+  FIELD (CHAR, pr_state);
+  FIELD (CHAR, pr_sname);
+  FIELD (CHAR, pr_zomb);
+  FIELD (CHAR, pr_nice);
+  FIELD (ULONG, pr_flag);
+  FIELD (UID_T, pr_uid);
+  FIELD (GID_T, pr_gid);
+  FIELD (PID_T, pr_pid);
+  FIELD (PID_T, pr_ppid);
+  FIELD (PID_T, pr_pgrp);
+  FIELD (PID_T, pr_sid);
+  FIELD (CHAR, pr_fname[FNAMESZ]);
+  FIELD (CHAR, pr_psargs[PRARGSZ]);
+};
+
+#undef FIELD
+
+#define FIELD(igroup, itype, item, fmt, ...)                   \
+    {                                                          \
+      .name = #item,                                           \
+      .group = #igroup,                                        \
+      .offset = offsetof (struct EBLHOOK(prstatus), pr_##item),        \
+      .type = TYPE_##itype,                                    \
+      .format = fmt,                                           \
+      __VA_ARGS__                                              \
+    }
+
+static const Ebl_Core_Item prstatus_items[] =
+  {
+    FIELD (signal, INT, info.si_signo, 'd'),
+    FIELD (signal, INT, info.si_code, 'd'),
+    FIELD (signal, INT, info.si_errno, 'd'),
+    FIELD (signal, SHORT, cursig, 'd'),
+    FIELD (signal, ULONG, sigpend, 'b'),
+    FIELD (signal, ULONG, sighold, 'b'),
+    FIELD (identity, PID_T, pid, 'd', .thread_identifier = true),
+    FIELD (identity, PID_T, ppid, 'd'),
+    FIELD (identity, PID_T, pgrp, 'd'),
+    FIELD (identity, PID_T, sid, 'd'),
+    FIELD (time, ULONG, utime, 'T', .count = 2),
+    FIELD (time, ULONG, stime, 'T', .count = 2),
+    FIELD (time, ULONG, cutime, 'T', .count = 2),
+    FIELD (time, ULONG, cstime, 'T', .count = 2),
+#ifdef PRSTATUS_REGSET_ITEMS
+    PRSTATUS_REGSET_ITEMS,
+#endif
+    FIELD (register, INT, fpvalid, 'd'),
+  };
+
+#undef FIELD
+
+#define FIELD(igroup, itype, item, fmt, ...)                   \
+    {                                                          \
+      .name = #item,                                           \
+      .group = #igroup,                                        \
+      .offset = offsetof (struct EBLHOOK(prpsinfo), pr_##item),        \
+      .type = TYPE_##itype,                                    \
+      .format = fmt,                                           \
+      __VA_ARGS__                                              \
+    }
+
+static const Ebl_Core_Item prpsinfo_items[] =
+  {
+    FIELD (state, CHAR, state, 'd'),
+    FIELD (state, CHAR, sname, 'c'),
+    FIELD (state, CHAR, zomb, 'd'),
+    FIELD (state, CHAR, nice, 'd'),
+    FIELD (state, ULONG, flag, 'x'),
+    FIELD (identity, UID_T, uid, 'd'),
+    FIELD (identity, GID_T, gid, 'd'),
+    FIELD (identity, PID_T, pid, 'd'),
+    FIELD (identity, PID_T, ppid, 'd'),
+    FIELD (identity, PID_T, pgrp, 'd'),
+    FIELD (identity, PID_T, sid, 'd'),
+    FIELD (command, CHAR, fname, 's', .count = FNAMESZ),
+    FIELD (command, CHAR, psargs, 's', .count = PRARGSZ),
+  };
+
+#undef FIELD
+
+int
+EBLHOOK(core_note) (n_type, descsz,
+                   regs_offset, nregloc, reglocs, nitems, items)
+     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;
+{
+  switch (n_type)
+    {
+    case NT_PRSTATUS:
+      if (descsz != sizeof (struct EBLHOOK(prstatus)))
+       return 0;
+      *regs_offset = offsetof (struct EBLHOOK(prstatus), pr_reg);
+      *nregloc = sizeof prstatus_regs / sizeof prstatus_regs[0];
+      *reglocs = prstatus_regs;
+      *nitems = sizeof prstatus_items / sizeof prstatus_items[0];
+      *items = prstatus_items;
+      return 1;
+
+    case NT_PRPSINFO:
+      if (descsz != sizeof (struct EBLHOOK(prpsinfo)))
+       return 0;
+      *regs_offset = 0;
+      *nregloc = 0;
+      *reglocs = NULL;
+      *nitems = sizeof prpsinfo_items / sizeof prpsinfo_items[0];
+      *items = prpsinfo_items;
+      return 1;
+
+#ifdef FPREGSET_SIZE
+    case NT_FPREGSET:
+      if (descsz != FPREGSET_SIZE)
+       return 0;
+      *regs_offset = 0;
+      *nregloc = sizeof fpregset_regs / sizeof fpregset_regs[0];
+      *reglocs = fpregset_regs;
+      *nitems = 0;
+      *items = NULL;
+      return 1;
+#endif
+
+#ifdef PRXFPREG_SIZE
+    case NT_PRXFPREG:
+      if (descsz != PRXFPREG_SIZE)
+       return 0;
+      *regs_offset = 0;
+      *nregloc = sizeof prxfpreg_regs / sizeof prxfpreg_regs[0];
+      *reglocs = prxfpreg_regs;
+      *nitems = 0;
+      *items = NULL;
+      return 1;
+#endif
+    }
+
+  return 0;
+}
diff --git a/backends/ppc64_corenote.c b/backends/ppc64_corenote.c
new file mode 100644 (file)
index 0000000..9d6a6a4
--- /dev/null
@@ -0,0 +1,2 @@
+#define BITS 64
+#include "ppc_corenote.c"
index 8cd75357d6508e836f7b46d450d3a48671bfa184..02a592fd99704a8b0c580a9e7c588674bcf5f0a6 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of PPC64 specific backend library.
-   Copyright (C) 2004, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -58,6 +58,8 @@ ppc64_init (elf, machine, eh, ehlen)
   HOOK (eh, bss_plt_p);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, core_note);
+  HOOK (eh, auxv_info);
 
   return MODVERSION;
 }
diff --git a/backends/ppc_auxv.c b/backends/ppc_auxv.c
new file mode 100644 (file)
index 0000000..1c0a5cf
--- /dev/null
@@ -0,0 +1,52 @@
+/* i386 specific auxv handling.
+   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.
+
+   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 ppc_
+#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"
+    "ppcle\0" "truele\0" "3\0" "4\0" "5\0" "6\0" "7\0" "8\0" "9\0"
+    "power6x\0" "dfp\0" "pa6t\0" "arch_2_05\0"
+    "ic_snoop\0" "smt\0" "booke\0" "cellbe\0"
+    "power5+\0" "power5\0" "power4\0" "notb\0"
+    "efpdouble\0" "efpsingle\0" "spe\0" "ucache\0"
+    "4xxmac\0" "mmu\0" "fpu\0" "altivec\0"
+    "ppc601\0" "ppc64\0" "ppc32\0" "\0";
+  return 1;
+}
+
+__typeof (ppc_auxv_info) ppc64_auxv_info
+                        __attribute__ ((alias ("ppc_auxv_info")));
diff --git a/backends/ppc_corenote.c b/backends/ppc_corenote.c
new file mode 100644 (file)
index 0000000..e9ff124
--- /dev/null
@@ -0,0 +1,102 @@
+/* PowerPC specific core note handling.
+   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.
+
+   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 <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#ifndef BITS
+# define BITS          32
+# define BACKEND       ppc_
+#else
+# define BITS          64
+# define BACKEND       ppc64_
+#endif
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+#define GR(at, n, dwreg)                                               \
+    { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = BITS }
+
+    GR (0, 32, 0),             /* r0-r31 */
+    /* 32, 1,                     nip */
+    GR (33, 1, 66),            /* msr */
+    /* 34, 1,                     orig_gpr3 */
+    GR (35, 1, 109),           /* ctr */
+    GR (36, 1, 108),           /* lr */
+    GR (37, 1, 101),           /* xer */
+    GR (38, 1, 64),            /* cr */
+    GR (39, 1, 100),           /* mq */
+    /*  40, 1,                    trap */
+    GR (41, 1, 119),           /* dar */
+    GR (42, 1, 118),           /* dsisr */
+
+#undef GR
+  };
+#define PRSTATUS_REGS_SIZE     (BITS / 8 * 48)
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 32, .count = 32, .bits = 64 }, /* f0-f31 */
+    { .offset = 32 * 8 + 4, .regno = 65, .count = 1, .bits = 32 } /* fpscr */
+  };
+#define FPREGSET_SIZE          (33 * 8)
+
+#if BITS == 32
+# define ULONG                 uint32_t
+# define ALIGN_ULONG           4
+# define TYPE_ULONG            ELF_T_WORD
+# define TYPE_LONG             ELF_T_SWORD
+#else
+# define ULONG                 uint64_t
+# define ALIGN_ULONG           8
+# define TYPE_ULONG            ELF_T_XWORD
+# define TYPE_LONG             ELF_T_SXWORD
+#endif
+#define PID_T                  int32_t
+#define        UID_T                   uint32_t
+#define        GID_T                   uint32_t
+#define ALIGN_PID_T            4
+#define ALIGN_UID_T            4
+#define ALIGN_GID_T            4
+#define TYPE_PID_T             ELF_T_SWORD
+#define TYPE_UID_T             ELF_T_WORD
+#define TYPE_GID_T             ELF_T_WORD
+
+#define PRSTATUS_REGSET_ITEMS                                                \
+  {                                                                          \
+    .name = "orig_gpr3", .type = TYPE_LONG, .format = 'd',                   \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 34),        \
+    .group = "register"                                                              \
+  }
+
+#include "linux-core-note.c"
index 1dfd5ec9bfebcebf6c95ef8bdda8ed6ce50db3d9..7edc8faddfc44e0d113fcd94685efca3628dcc7e 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of PPC specific backend library.
-   Copyright (C) 2004, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -57,6 +57,8 @@ ppc_init (elf, machine, eh, ehlen)
   HOOK (eh, bss_plt_p);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, core_note);
+  HOOK (eh, auxv_info);
 
   return MODVERSION;
 }
index 8a1950c01acce53b7f689ef05a13c70eca851c61..9540a3e9cf52d71e3227e663c3da553b30805107 100644 (file)
@@ -1,5 +1,5 @@
 /* PPC specific symbolic name handling.
-   Copyright (C) 2004, 2005 Red Hat, Inc.
+   Copyright (C) 2004, 2005, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -122,10 +122,13 @@ ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym,
 
   if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
     {
+      /* In -msecure-plt mode, DT_PPC_GOT is present and must match.  */
       GElf_Addr gotaddr;
       if (find_dyn_got (elf, ehdr, &gotaddr))
        return sym->st_value == gotaddr;
-      return sym->st_value == destshdr->sh_addr + 4;
+
+      /* In -mbss-plt mode, any place in the section is valid.  */
+      return true;
     }
 
   const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
index 1a37c07b079d9894e755af99330b4f0cf28fcbc0..c2bc72e9c72898b437e7ed696331822aca170bcd 100644 (file)
@@ -1,7 +1,6 @@
 /* x86-64 specific core note handling.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
-   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
 
    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
 #include "libebl_CPU.h"
 
 
-/* We cannot include <sys/procfs.h> since the definition would be for
-   the host platform and not always x86-64 as required here.  */
-struct elf_prstatus
+static const Ebl_Register_Location prstatus_regs[] =
   {
-    struct
-    {
-      int32_t si_signo;                        /* Signal number.  */
-      int32_t si_code;                 /* Extra code.  */
-      int32_t si_errno;                        /* Errno.  */
-    } pr_info;                         /* Info associated with signal.  */
-    int16_t pr_cursig;                 /* Current signal.  */
-    uint64_t pr_sigpend;               /* Set of pending signals.  */
-    uint64_t pr_sighold;               /* Set of held signals.  */
-    int32_t pr_pid;
-    int32_t pr_ppid;
-    int32_t pr_pgrp;
-    int32_t pr_sid;
-    struct x86_64_timeval
-    {
-      int64_t tv_sec;
-      int32_t tv_usec;
-    } pr_utime;                                /* User time.  */
-    struct x86_64_timeval pr_stime;    /* System time.  */
-    struct x86_64_timeval pr_cutime;   /* Cumulative user time.  */
-    struct x86_64_timeval pr_cstime;   /* Cumulative system time.  */
-    uint64_t pr_reg[27];       /* GP registers.  */
-    int32_t pr_fpvalid;                        /* True if math copro being used.  */
+#define GR(at, n, dwreg)                                               \
+    { .offset = at * 8, .regno = dwreg, .count = n, .bits = 64 }
+#define SR(at, n, dwreg)                                               \
+    { .offset = at * 8, .regno = dwreg, .count = n, .bits = 16, .pad = 6 }
+
+    GR (0, 1, 15),             /* %r15 */
+    GR (1, 1, 14),             /* %r14 */
+    GR (2, 1, 13),             /* %r13 */
+    GR (3, 1, 12),             /* %r12 */
+    GR (4, 1, 6),              /* %rbp */
+    GR (5, 1, 3),              /* %rbx */
+    GR (6, 1, 11),             /* %r11 */
+    GR (7, 1, 10),             /* %r10 */
+    GR (8, 1, 9),              /* %r9 */
+    GR (9, 1, 8),              /* %r8 */
+    GR (10,1, 0),              /* %rax */
+    GR (11,1, 2),              /* %rcx */
+    GR (12,1, 1),              /* %rdx */
+    GR (13,2, 4),              /* %rsi-%rdi */
+    /*  15,1,                      orig_rax */
+    GR (16,1, 16),             /* %rip */
+    SR (17,1, 51),             /* %cs */
+    GR (18,1, 49),             /* %rFLAGS */
+    GR (19,1, 7),              /* %rsp */
+    SR (20,1, 52),             /* %ss */
+    GR (21,2, 58),             /* %fs.base-%gs.base */
+    SR (23,1, 53),             /* %ds */
+    SR (24,1, 50),             /* %es */
+    SR (25,2, 54),             /* %fs-%gs */
+
+#undef GR
+#undef SR
   };
-
-
-struct elf_prpsinfo
+#define PRSTATUS_REGS_SIZE     (27 * 8)
+
+#define        ULONG                   uint64_t
+#define PID_T                  int32_t
+#define        UID_T                   uint32_t
+#define        GID_T                   uint32_t
+#define ALIGN_ULONG            8
+#define ALIGN_PID_T            4
+#define ALIGN_UID_T            4
+#define ALIGN_GID_T            4
+#define TYPE_ULONG             ELF_T_XWORD
+#define TYPE_PID_T             ELF_T_SWORD
+#define TYPE_UID_T             ELF_T_SWORD
+#define TYPE_GID_T             ELF_T_SWORD
+
+#define PRSTATUS_REGSET_ITEMS                                                \
+  {                                                                          \
+    .name = "orig_rax", .type = ELF_T_SXWORD, .format = 'd',                 \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (8 * 15),        \
+    .group = "register"                                                              \
+  }
+
+static const Ebl_Register_Location fpregset_regs[] =
   {
-    char pr_state;                     /* Numeric process state.  */
-    char pr_sname;                     /* Char for pr_state.  */
-    char pr_zomb;                      /* Zombie.  */
-    char pr_nice;                      /* Nice val.  */
-    uint64_t pr_flag;                  /* Flags.  */
-    uint32_t pr_uid;
-    uint32_t pr_gid;
-    int32_t pr_pid;
-    int32_t pr_ppid;
-    int32_t pr_pgrp;
-    int32_t pr_sid;
-    /* Lots missing */
-    char pr_fname[16];                 /* Filename of executable.  */
-    char pr_psargs[80];                        /* Initial part of arg list.  */
+    { .offset = 0, .regno = 65, .count = 2, .bits = 16 }, /* fcw-fsw */
+    { .offset = 24, .regno = 64, .count = 1, .bits = 32 }, /* mxcsr */
+    { .offset = 32, .regno = 33, .count = 8, .bits = 80, .pad = 6 }, /* stN */
+    { .offset = 32 + 128, .regno = 17, .count = 16, .bits = 128 }, /* xmm */
   };
+#define FPREGSET_SIZE  512
 
-
-bool
-x86_64_core_note (name, type, descsz, desc)
-     const char *name __attribute__ ((unused));
-     uint32_t type;
-     uint32_t descsz;
-     const char *desc;
-{
-  bool result = false;
-
-  switch (type)
-    {
-    case NT_PRSTATUS:
-      if (descsz < sizeof (struct elf_prstatus))
-       /* Not enough data.  */
-       break;
-
-      struct elf_prstatus *stat = (struct elf_prstatus *) desc;
-
-      printf ("    SIGINFO:  signo: %" PRId32 ", code = %" PRId32
-             ", errno = %" PRId32 "\n"
-             "    signal: %" PRId16 ", pending: %#08" PRIx64 ", holding: %#08"
-             PRIx64 "\n"
-             "    pid: %" PRId32 ", ppid = %" PRId32 ", pgrp = %" PRId32
-             ", sid = %" PRId32 "\n"
-             "     utime: %6" PRId64 ".%06" PRId32
-             "s,  stime: %6" PRId64 ".%06" PRId32 "s\n"
-             "    cutime: %6" PRId64 ".%06" PRId32
-             "s, cstime: %6" PRId64 ".%06" PRId32 "s\n"
-             "    rax: %016" PRIx64 "  rbx: %016" PRIx64 "\n"
-             "    rcx: %016" PRIx64 "  rdx: %016" PRIx64 "\n"
-             "    rsi: %016" PRIx64 "  rdi: %016" PRIx64 "\n"
-             "    rbp: %016" PRIx64 "  rsp: %016" PRIx64 "\n"
-             "    r8:  %016" PRIx64 "  r9:  %016" PRIx64 "\n"
-             "    r10: %016" PRIx64 "  r11: %016" PRIx64 "\n"
-             "    r12: %016" PRIx64 "  r13: %016" PRIx64 "\n"
-             "    r14: %016" PRIx64 "  r15: %016" PRIx64 "\n"
-             "    rip: %016" PRIx64 "  eflags: %08" PRIx64 "\n"
-             "    original rax: %016" PRIx64 "\n"
-             "    cs: %04" PRIx64 "  ds: %04" PRIx64 "  es: %04" PRIx64
-             "  ss: %04" PRIx64 "\n"
-             "    fs: %04" PRIx64 "  fs_base: %016" PRIx64
-             "  gs: %04" PRIx64 "  gs_base: %016" PRIx64 "\n\n",
-             stat->pr_info. si_signo,
-             stat->pr_info. si_code,
-             stat->pr_info. si_errno,
-             stat->pr_cursig,
-             stat->pr_sigpend, stat->pr_sighold,
-             stat->pr_pid, stat->pr_ppid, stat->pr_pgrp, stat->pr_sid,
-             stat->pr_utime.tv_sec, stat->pr_utime.tv_usec,
-             stat->pr_stime.tv_sec, stat->pr_stime.tv_usec,
-             stat->pr_cutime.tv_sec, stat->pr_cutime.tv_usec,
-             stat->pr_cstime.tv_sec, stat->pr_cstime.tv_usec,
-             stat->pr_reg[10], stat->pr_reg[5], stat->pr_reg[11],
-             stat->pr_reg[12], stat->pr_reg[13], stat->pr_reg[14],
-             stat->pr_reg[4], stat->pr_reg[10], stat->pr_reg[9],
-             stat->pr_reg[7], stat->pr_reg[6], stat->pr_reg[5],
-             stat->pr_reg[3], stat->pr_reg[2], stat->pr_reg[1],
-             stat->pr_reg[0], stat->pr_reg[16], stat->pr_reg[18],
-             stat->pr_reg[15], stat->pr_reg[17], stat->pr_reg[23],
-             stat->pr_reg[24], stat->pr_reg[20],
-             stat->pr_reg[25], stat->pr_reg[21],
-             stat->pr_reg[26], stat->pr_reg[22]);
-
-      /* We handled this entry.  */
-      result = true;
-      break;
-
-    case NT_PRPSINFO:
-      if (descsz < sizeof (struct elf_prpsinfo))
-       /* Not enough data.  */
-       break;
-
-      struct elf_prpsinfo *info = (struct elf_prpsinfo *) desc;
-
-      printf ("    state: %c (%hhd),  zombie: %hhd,  nice: %hhd\n"
-             "    flags: %08" PRIx64 "  uid: %" PRIu32 "  gid: %" PRIu32 "\n"
-             "    pid: %" PRId32 "  ppid: %" PRId32 "  pgrp: %" PRId32
-             "  sid: %" PRId32 "\n"
-             "    fname: %.16s\n"
-             "     args: %.80s\n\n",
-             info->pr_sname, info->pr_state, info->pr_zomb, info->pr_nice,
-             info->pr_flag, info->pr_uid, info->pr_gid,
-             info->pr_pid, info->pr_ppid, info->pr_pgrp, info->pr_sid,
-             info->pr_fname, info->pr_psargs);
-
-      /* We handled this entry.  */
-      result = true;
-      break;
-
-    default:
-      break;
-    }
-
-  return result;
-}
+#include "linux-core-note.c"
index 476f4ed279fd726ab35c7d3752159529737e221b..b1764832e0f75b4b864671a964d638973e15f401 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of x86-64 specific backend library.
-   Copyright (C) 2002, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2002, 2005, 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -35,8 +35,6 @@
 /* This defines the common reloc hooks based on x86_64_reloc.def.  */
 #include "common-reloc.c"
 
-
-
 const char *
 x86_64_init (elf, machine, eh, ehlen)
      Elf *elf __attribute__ ((unused));
@@ -55,6 +53,7 @@ x86_64_init (elf, machine, eh, ehlen)
   HOOK (eh, core_note);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
+  HOOK (eh, auxv_info);
 
   return MODVERSION;
 }
index cfa405080a19fa52d56a613baf3646a5c7cfbccc..8eb0d33f56d79e0c49793f7c9875e7dc92e0532d 100644 (file)
@@ -156,6 +156,7 @@ x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
       return stpcpy (&name[1], "s.base") + 1 - name;
 
     case 49:
+      *setname = "integer";
       return stpcpy (name, "rflags") + 1 - name;
     case 62:
       return stpcpy (name, "tr") + 1 - name;
index a48f8e33305ddf63b4f3f699e3ace0e33fe5eabd..c93e70474e1c8d3ad6638b274b62c71f75fa6fdb 100644 (file)
@@ -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
index 741e5eee3bd9669ad7d50f40cd927e09809ab394..993800ca6898460eff8938f31637e499284a8a43 100644 (file)
@@ -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)
 
index 5344df094b2f9b5f3b4edc8042705ecac9cb92e3..d466a1f3ba7952801e1ad2d92f9365004e053cf8 100644 (file)
@@ -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 (file)
index 0000000..54583f9
--- /dev/null
@@ -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;
+}
index 9eb355f841ff33e730614216c7bd67cb94e062e1..553d5ba933c34c87c0982c3417a9cdd29099c863 100644 (file)
@@ -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
 #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;
 }
index 5b1a7193aa623d82306cf7ab57568a4d249325be..63e64a10e5da3854fcc3d21bc294d24c702a9e03 100644 (file)
@@ -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)),
@@ -575,15 +601,6 @@ default_object_note_type_name (uint32_t ignore __attribute__ ((unused)),
   return NULL;
 }
 
-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)),
index 1465fb1aad70a51bd7fa36e920f96067af3441d4..7e29168d210e371aead2dd1bd6222c79958302ed 100644 (file)
@@ -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
index a26728cdff767172cc4bd34ef64737ed60576b71..4962c30aa4c0328c4a6b363f9200d1d4fa57012a 100644 (file)
@@ -1,3 +1,19 @@
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+       * gelf_update_auxv.c: New file.
+       * gelf_getauxv.c: New file.
+       * Makefile.am (libelf_a_SOURCES): Add them.
+       * gelf.h: Declare gelf_getauxv, gelf_update_auxv.
+       * libelf.map (ELFUTILS_1.3): New set, inherits fom ELFUTILS_1.2.
+       Export gelf_getauxv, gelf_update_auxv.
+
+       * libelf.h (Elf_Type): Add ELF_T_AUXV.
+       * abstract.h: Add auxv_t entries.
+       * exttypes.h: Likewise.
+       * gelf_xlate.h: Likewise.
+       * gelf_xlate.c (__elf_xfctstom): Add ELF_T_AUXV entries.
+       * gelf_fsize.c (__libelf_type_sizes): Likewise.
+
 2007-08-12  Roland McGrath  <roland@redhat.com>
 
        * elf32_updatefile.c (compare_sections): Sort secondarily on sh_size,
index b93f49c63d1231d36f729d2ae8d5c7b1803edc6b..3e8322e94145ef43037c545053ba486e9f44d18f 100644 (file)
@@ -83,6 +83,7 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
                   gelf_getdyn.c gelf_update_dyn.c \
                   gelf_getmove.c gelf_update_move.c \
                   gelf_getsyminfo.c gelf_update_syminfo.c \
+                  gelf_getauxv.c gelf_update_auxv.c \
                   gelf_xlatetof.c gelf_xlatetom.c \
                   nlist.c \
                   gelf_getsymshndx.c gelf_update_symshndx.c \
index 3c6250d04aa450a8607eb030a17da583b67b7c86..e359f96b78b4e9944ecf6d88e5bb42700ea78dd1 100644 (file)
@@ -1,5 +1,5 @@
 /* Abstract description of component ELF types.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -314,3 +314,20 @@ END (Bits, Ext##Lib)
   Lib (32, Ext)
 #define Lib64(Ext) \
   Lib (64, Ext)
+
+#define auxv_t32(Ext) \
+START (32, auxv_t, Ext##auxv_t)                                                      \
+  TYPE_NAME (ElfW2(32, Ext##Word), a_type)                                   \
+  TYPE_EXTRA (union {)                                                       \
+  TYPE_EXTRA (ElfW2(32, Ext##Word) a_val;)                                   \
+  TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);)              \
+  TYPE_EXTRA (} a_un;)                                                       \
+END (32, Ext##auxv_t)
+#define auxv_t64(Ext) \
+START (64, auxv_t, Ext##auxv_t)                                                      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), a_type)                                  \
+  TYPE_EXTRA (union {)                                                       \
+  TYPE_EXTRA (ElfW2(64, Ext##Xword) a_val;)                                  \
+  TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);)              \
+  TYPE_EXTRA (} a_un;)                                                       \
+END (64, Ext##auxv_t)
index 1dff8ce36faae42bcf2bdbaa900be665c08f59c2..3bb90c3ade237cb1bb591bd811dd06d176a5043c 100644 (file)
@@ -1,5 +1,5 @@
 /* External ELF types.
-   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -94,6 +94,7 @@ Verneed32 (Ext_);
 Vernaux32 (Ext_);
 Syminfo32 (Ext_);
 Move32 (Ext_);
+auxv_t32 (Ext_);
 
 Ehdr64 (Ext_);
 Phdr64 (Ext_);
@@ -109,6 +110,7 @@ Verneed64 (Ext_);
 Vernaux64 (Ext_);
 Syminfo64 (Ext_);
 Move64 (Ext_);
+auxv_t64 (Ext_);
 
 #undef START
 #undef END
index 2ef256ccbf1156f0e89d392aff3c668e7907d7aa..b985c1c0c3d3531a744c69a66c0713fa712933ae 100644 (file)
@@ -1,5 +1,5 @@
 /* This file defines generic ELF types, structures, and macros.
-   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 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
@@ -327,6 +327,14 @@ extern int gelf_update_verdaux (Elf_Data *__data, int __offset,
                                GElf_Verdaux *__src);
 
 
+/* Get auxv entry at the given index.  */
+extern GElf_auxv_t *gelf_getauxv (Elf_Data *__data, int __ndx,
+                                 GElf_auxv_t *__dst);
+
+/* Update auxv entry at the given index.  */
+extern int gelf_update_auxv (Elf_Data *__data, int __ndx, GElf_auxv_t *__src);
+
+
 /* Retrieve uninterpreted chunk of the file contents.  */
 extern char *gelf_rawchunk (Elf *__elf, GElf_Off __offset, GElf_Word __size);
 
index a8c368c38a70e165c8f928371153796f51135294..98197e0f3983427e5c5d3f6ac001e391c0526e02 100644 (file)
@@ -1,5 +1,5 @@
 /* Return the size of an object file type.
-   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -86,7 +86,8 @@ const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
       [ELF_T_VNAUX]    = sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)),            \
       [ELF_T_NHDR]     = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)),               \
       [ELF_T_SYMINFO]  = sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)),            \
-      [ELF_T_MOVE]     = sizeof (ElfW2(LIBELFBITS, Ext_Move))
+      [ELF_T_MOVE]     = sizeof (ElfW2(LIBELFBITS, Ext_Move)),               \
+      [ELF_T_AUXV]     = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t))
       TYPE_SIZES (32)
     },
     [ELFCLASS64 - 1] = {
diff --git a/libelf/gelf_getauxv.c b/libelf/gelf_getauxv.c
new file mode 100644 (file)
index 0000000..036bdcc
--- /dev/null
@@ -0,0 +1,130 @@
+/* Get information from auxiliary vector at the given index.
+   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 <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_auxv_t *
+gelf_getauxv (data, ndx, dst)
+     Elf_Data *data;
+     int ndx;
+     GElf_auxv_t *dst;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  GElf_auxv_t *result = NULL;
+  Elf *elf;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  elf = data_scn->s->elf;
+
+  rwlock_rdlock (elf->lock);
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_auxv_t *src;
+
+      /* Here it gets a bit more complicated.  The format of the vector
+        entries has to be converted.  The user better have provided a
+        buffer where we can store the information.  While copying the data
+        we convert the format.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
+       {
+         __libelf_seterrno (ELF_E_INVALID_INDEX);
+         goto out;
+       }
+
+      src = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+        not.  There are zero- and sign-extensions going on.  */
+      dst->a_type = src->a_type;
+      dst->a_un.a_val = src->a_un.a_val;
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t));
+
+      /* The data is already in the correct form.  Just make sure the
+        index is OK.  */
+      if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size))
+       {
+         __libelf_seterrno (ELF_E_INVALID_INDEX);
+         goto out;
+       }
+
+      *dst = ((GElf_auxv_t *) data_scn->d.d_buf)[ndx];
+    }
+
+  result = dst;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/libelf/gelf_update_auxv.c b/libelf/gelf_update_auxv.c
new file mode 100644 (file)
index 0000000..b294ead
--- /dev/null
@@ -0,0 +1,135 @@
+/* Update information in dynamic table at the given index.
+   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 <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_auxv (data, ndx, src)
+     Elf_Data *data;
+     int ndx;
+     GElf_auxv_t *src;
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_auxv_t *auxv;
+
+      /* There is the possibility that the values in the input are
+        too large.  */
+      if (unlikely (src->a_type > 0xffffffffll)
+         || unlikely (src->a_un.a_val > 0xffffffffull))
+       {
+         __libelf_seterrno (ELF_E_INVALID_DATA);
+         goto out;
+       }
+
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
+       {
+         __libelf_seterrno (ELF_E_INVALID_INDEX);
+         goto out;
+       }
+
+      auxv = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
+
+      auxv->a_type = src->a_type;
+      auxv->a_un.a_val = src->a_un.a_val;
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_auxv_t) > data_scn->d.d_size))
+       {
+         __libelf_seterrno (ELF_E_INVALID_INDEX);
+         goto out;
+       }
+
+      ((Elf64_auxv_t *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
index f1bbdf3a771f8441f7ae671acde777c779e6f328..080474fdca2d24565d23a493fc551a62eb842ee3 100644 (file)
@@ -1,5 +1,5 @@
 /* Transformation functions for ELF data types.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -216,7 +216,8 @@ const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
        [ELF_T_NHDR]    = ElfW2(Bits, cvt_Nhdr),                              \
        [ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),                           \
        [ELF_T_MOVE]    = ElfW2(Bits, cvt_Move),                              \
-       [ELF_T_LIB]     = ElfW2(Bits, cvt_Lib)
+       [ELF_T_LIB]     = ElfW2(Bits, cvt_Lib),                               \
+       [ELF_T_AUXV]    = ElfW2(Bits, cvt_auxv_t)
         define_xfcts (32),
        [ELF_T_GNUHASH] = Elf32_cvt_Word
       },
index eec47ee68c4dbfd9f321253de09869dd276bf316..e7659f12ad86ea812c3d9d57d23c12da264e7164 100644 (file)
@@ -1,5 +1,5 @@
 /* Helper file for type conversion function generation.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -70,6 +70,7 @@ TYPE (Dyn, LIBELFBITS)
 TYPE (Syminfo, LIBELFBITS)
 TYPE (Move, LIBELFBITS)
 TYPE (Lib, LIBELFBITS)
+TYPE (auxv_t, LIBELFBITS)
 
 
 /* Prepare for the next round.  */
index 2f58e4c4e4a04d0434604d438490ffc112ea6f22..a5d744cf35a9a29be9bbbdb03f61628f9292c8db 100644 (file)
@@ -1,5 +1,5 @@
 /* Interface for libelf.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2006, 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
@@ -83,6 +83,7 @@ typedef enum
   ELF_T_MOVE,                  /* Elf32_Move, Elf64_Move, ... */
   ELF_T_LIB,                   /* Elf32_Lib, Elf64_Lib, ... */
   ELF_T_GNUHASH,               /* GNU-style hash section.  */
+  ELF_T_AUXV,                  /* Elf32_auxv_t, Elf64_auxv_t, ... */
   /* Keep this the last entry.  */
   ELF_T_NUM
 } Elf_Type;
index 9549c3176c220cee7840a0af21fb2d3d4485ae03..bc597c6fee377e23d1b3d9861018f4f74345f3aa 100644 (file)
@@ -117,3 +117,9 @@ ELFUTILS_1.2 {
   global:
     elf_gnu_hash;
 } ELFUTILS_1.1.1;
+
+ELFUTILS_1.3 {
+  global:
+    gelf_getauxv;
+    gelf_update_auxv;
+};
index 77c9838100e875faa06bb00ee8365aa11265f1a8..2c51f472bfd8bf1602b214045e4e05498db095de 100644 (file)
@@ -1,3 +1,49 @@
+2007-08-23  Roland McGrath  <roland@redhat.com>
+
+       * readelf.c (printf_with_wrap): Function removed.
+       (REGISTER_WRAP_COLUMN): New macro.
+       (handle_core_register): Use print_core_item instead.
+       (struct register_info): New type.
+       (compare_registers, compare_register_sets): New functions.
+       (register_bitpos, compare_sets_by_info): New functions.
+       (handle_core_registers): Use those to segregate and sort registers
+       for display.
+
+       * readelf.c (ITEM_WRAP_COLUMN): New macro.
+       (print_core_item): New function.
+       (handle_core_item): Use it instead of printf_with_wrap.
+       (compare_core_items, compare_core_item_groups): New functions.
+       (handle_core_items): Use them.  Sort by group and force line breaks
+       between groups.
+
+       * readelf.c (handle_core_registers, handle_core_items): New functions,
+       broken out of ...
+       (handle_core_note): ... here.   Call them.
+
+2007-08-22  Roland McGrath  <roland@redhat.com>
+
+       * unstrip.c (new_shstrtab): New function, broken out of ...
+       (copy_elided_sections): ... here.
+
+2007-08-20  Roland McGrath  <roland@redhat.com>
+
+       Avoid local function trampolines in nm binary.
+       * nm.c (sort_by_address): Move to a static function instead of local
+       inside show_symbols.
+       (sort_by_name_strtab): New static variable.
+       (sort_by_name): Use it.  Move to a static function instead of local
+       inside show_symbols.
+       (show_symbols): Set sort_by_name_strtab.
+
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+       * readelf.c (handle_auxv_note): New function.
+       (handle_notes): Call it.
+
+       * readelf.c (printf_with_wrap, convert): New functions.
+       (handle_core_item, (handle_core_register): New functions.
+       (handle_notes): Call those with details from ebl_core_note.
+
 2007-08-12  Roland McGrath  <roland@redhat.com>
 
        * elflint.c (check_note): Accept type 0 with name "Linux".
index d79b00582e1ea0dc911eb399afe66c76f2072b99..48f08aca84bf482c745ec47abe54791806acd36b 100644 (file)
--- a/src/nm.c
+++ b/src/nm.c
@@ -938,34 +938,39 @@ show_symbols_posix (Elf *elf, GElf_Word strndx, const char *prefix,
 /* Maximum size of memory we allocate on the stack.  */
 #define MAX_STACK_ALLOC        65536
 
-static void
-show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
-             GElf_Shdr *shdr, const char *prefix, const char *fname,
-             const char *fullname)
+static int
+sort_by_address (const void *p1, const void *p2)
 {
-  int sort_by_name (const void *p1, const void *p2)
-    {
-      GElf_SymX *s1 = (GElf_SymX *) p1;
-      GElf_SymX *s2 = (GElf_SymX *) p2;
-      int result;
+  GElf_SymX *s1 = (GElf_SymX *) p1;
+  GElf_SymX *s2 = (GElf_SymX *) p2;
 
-      result = strcmp (elf_strptr (ebl->elf, shdr->sh_link, s1->sym.st_name),
-                      elf_strptr (ebl->elf, shdr->sh_link, s2->sym.st_name));
+  int result = (s1->sym.st_value < s2->sym.st_value
+               ? -1 : (s1->sym.st_value == s2->sym.st_value ? 0 : 1));
 
-      return reverse_sort ? -result : result;
-    }
+  return reverse_sort ? -result : result;
+}
 
-  int sort_by_address (const void *p1, const void *p2)
-    {
-      GElf_SymX *s1 = (GElf_SymX *) p1;
-      GElf_SymX *s2 = (GElf_SymX *) p2;
+static Elf_Data *sort_by_name_strtab;
+
+static int
+sort_by_name (const void *p1, const void *p2)
+{
+  GElf_SymX *s1 = (GElf_SymX *) p1;
+  GElf_SymX *s2 = (GElf_SymX *) p2;
 
-      int result = (s1->sym.st_value < s2->sym.st_value
-                   ? -1 : (s1->sym.st_value == s2->sym.st_value ? 0 : 1));
+  const char *n1 = sort_by_name_strtab->d_buf + s1->sym.st_name;
+  const char *n2 = sort_by_name_strtab->d_buf + s2->sym.st_name;
 
-      return reverse_sort ? -result : result;
-    }
+  int result = strcmp (n1, n2);
+
+  return reverse_sort ? -result : result;
+}
 
+static void
+show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
+             GElf_Shdr *shdr, const char *prefix, const char *fname,
+             const char *fullname)
+{
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
@@ -1142,7 +1147,11 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
 
   /* Sort the entries according to the users wishes.  */
   if (sort == sort_name)
-    qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_name);
+    {
+      sort_by_name_strtab = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link),
+                                        NULL);
+      qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_name);
+    }
   else if (sort == sort_numeric)
     qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_address);
 
index e8b0bb4a7f9464dec529d283e10f25a685d84fb7..747309597f9dcdda82ee3930417cb572b1de871e 100644 (file)
@@ -41,6 +41,7 @@
 #include <libdw.h>
 #include <libintl.h>
 #include <locale.h>
+#include <stdarg.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
@@ -4949,6 +4950,621 @@ print_debug (Ebl *ebl, GElf_Ehdr *ehdr)
 }
 
 
+#define ITEM_INDENT            4
+#define ITEM_WRAP_COLUMN       150
+#define REGISTER_WRAP_COLUMN   75
+
+/* Print "NAME: FORMAT", wrapping when FORMAT_MAX chars of FORMAT would
+   make the line exceed ITEM_WRAP_COLUMN.  Unpadded numbers look better
+   for the core items.  But we do not want the line breaks to depend on
+   the particular values.  */
+static unsigned int
+__attribute__ ((format (printf, 7, 8)))
+print_core_item (unsigned int colno, char sep, unsigned int wrap,
+                size_t name_width, const char *name,
+                size_t format_max, const char *format, ...)
+{
+  size_t len = strlen (name);
+  if (name_width < len)
+    name_width = len;
+
+  size_t n = name_width + sizeof ": " - 1 + format_max;
+
+  if (colno == 0)
+    {
+      printf ("%*s", ITEM_INDENT, "");
+      colno = ITEM_INDENT + n;
+    }
+  else if (colno + 2 + n < wrap)
+    {
+      printf ("%c ", sep);
+      colno += 2 + n;
+    }
+  else
+    {
+      printf ("\n%*s", ITEM_INDENT, "");
+      colno = ITEM_INDENT + n;
+    }
+
+  printf ("%s: %*s", name, (int) (name_width - len), "");
+
+  va_list ap;
+  va_start (ap, format);
+  vprintf (format, ap);
+  va_end (ap);
+
+  return colno;
+}
+
+static const void *
+convert (Elf *core, Elf_Type type, uint_fast16_t count,
+        void *value, const void *data)
+{
+  Elf_Data valuedata =
+    {
+      .d_type = type,
+      .d_buf = value,
+      .d_size = gelf_fsize (core, type, count, EV_CURRENT),
+      .d_version = EV_CURRENT,
+    };
+  Elf_Data indata =
+    {
+      .d_type = type,
+      .d_buf = (void *) data,
+      .d_size = valuedata.d_size,
+      .d_version = EV_CURRENT,
+    };
+
+  Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
+                ? elf32_xlatetom : elf64_xlatetom)
+    (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
+  if (d == NULL)
+    error (EXIT_FAILURE, 0,
+          gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
+
+  return data + indata.d_size;
+}
+
+typedef uint8_t GElf_Byte;
+
+static unsigned int
+handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
+                 unsigned int colno)
+{
+  uint_fast16_t count = item->count ?: 1;
+
+#define TYPES                                                                \
+  DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8, 4);                         \
+  DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16, 6);                       \
+  DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32, 11);                              \
+  DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32, 11);                        \
+  DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64, 20);                   \
+  DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64, 20)
+
+#define DO_TYPE(NAME, Name, hex, dec, max) GElf_##Name Name[count]
+  union { TYPES; } value;
+#undef DO_TYPE
+
+  desc = convert (core, item->type, count, &value, desc + item->offset);
+
+  switch (item->format)
+    {
+    case 'd':
+      assert (count == 1);
+      switch (item->type)
+       {
+#define DO_TYPE(NAME, Name, hex, dec, max)                                   \
+         case ELF_T_##NAME:                                                  \
+           colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN,            \
+                                    0, item->name, max, dec, value.Name[0]); \
+           break
+         TYPES;
+#undef DO_TYPE
+       default:
+         abort ();
+       }
+      break;
+
+    case 'x':
+      assert (count == 1);
+      switch (item->type)
+       {
+#define DO_TYPE(NAME, Name, hex, dec, max)                                   \
+         case ELF_T_##NAME:                                                  \
+           colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN,            \
+                                    0, item->name, max, hex, value.Name[0]); \
+           break
+         TYPES;
+#undef DO_TYPE
+       default:
+         abort ();
+       }
+      break;
+
+    case 'b':
+      assert (count == 1);
+      Dwarf_Word bits = 0;
+      Dwarf_Word bit = 0;
+      switch (item->type)
+       {
+#define DO_TYPE(NAME, Name, hex, dec, max)                             \
+         case ELF_T_##NAME:                                                  \
+           bits = value.Name[0];                                             \
+           bit = (Dwarf_Word) 1 << ((sizeof value.Name[0] * 8) - 1);         \
+           break
+         TYPES;
+#undef DO_TYPE
+       default:
+         abort ();
+       }
+      char printed[sizeof (Dwarf_Word) * 8 + 1];
+      int i = 0;
+      while (bit != 0)
+       {
+         printed[i++] = (bits & bit) ? '1' : '0';
+         bit >>= 1;
+       }
+      colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
+                              sizeof printed - 1, "%.*s", i, printed);
+      break;
+
+    case 'T':
+      assert (count == 2);
+      Dwarf_Word sec;
+      Dwarf_Word usec;
+      size_t maxfmt = 7;
+      switch (item->type)
+       {
+#define DO_TYPE(NAME, Name, hex, dec, max)                                   \
+         case ELF_T_##NAME:                                                  \
+           sec = value.Name[0];                                              \
+           usec = value.Name[1];                                             \
+           maxfmt += max;                                                    \
+           break
+         TYPES;
+#undef DO_TYPE
+       default:
+         abort ();
+       }
+      colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
+                              maxfmt, "%" PRIu64 ".%.6" PRIu64, sec, usec);
+      break;
+
+    case 'c':
+      assert (count == 1);
+      colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
+                              1, "%c", value.Byte[0]);
+      break;
+
+    case 's':
+      colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name,
+                              count, "%.*s", (int) count, value.Byte);
+      break;
+
+    default:
+      error (0, 0, "XXX not handling format '%c' for %s",
+            item->format, item->name);
+      break;
+    }
+
+#undef TYPES
+
+  return colno;
+}
+
+
+/* Sort items by group, and by layout offset within each group.  */
+static int
+compare_core_items (const void *a, const void *b)
+{
+  const Ebl_Core_Item *const *p1 = a;
+  const Ebl_Core_Item *const *p2 = b;
+  const Ebl_Core_Item *item1 = *p1;
+  const Ebl_Core_Item *item2 = *p2;
+
+  return ((item1->group == item2->group ? 0
+          : strcmp (item1->group, item2->group))
+         ?: (int) item1->offset - (int) item2->offset);
+}
+
+/* Sort item groups by layout offset of the first item in the group.  */
+static int
+compare_core_item_groups (const void *a, const void *b)
+{
+  const Ebl_Core_Item *const *const *p1 = a;
+  const Ebl_Core_Item *const *const *p2 = b;
+  const Ebl_Core_Item *const *group1 = *p1;
+  const Ebl_Core_Item *const *group2 = *p2;
+  const Ebl_Core_Item *item1 = *group1;
+  const Ebl_Core_Item *item2 = *group2;
+
+  return (int) item1->offset - (int) item2->offset;
+}
+
+static unsigned int
+handle_core_items (Elf *core, const void *desc,
+                  const Ebl_Core_Item *items, size_t nitems)
+{
+  if (nitems == 0)
+    return 0;
+
+  /* Sort to collect the groups together.  */
+  const Ebl_Core_Item *sorted_items[nitems];
+  for (size_t i = 0; i < nitems; ++i)
+    sorted_items[i] = &items[i];
+  qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
+
+  /* Collect the unique groups and sort them.  */
+  const Ebl_Core_Item **groups[nitems];
+  groups[0] = &sorted_items[0];
+  size_t ngroups = 1;
+  for (size_t i = 1; i < nitems; ++i)
+    if (sorted_items[i]->group != sorted_items[i - 1]->group
+       && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
+      groups[ngroups++] = &sorted_items[i];
+  qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
+
+  /* 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;
+    }
+
+  return colno;
+}
+
+static unsigned int
+handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
+                     unsigned int colno)
+{
+  desc += regloc->offset;
+
+  abort ();                    /* XXX */
+  return colno;
+}
+
+
+static unsigned int
+handle_core_register (Ebl *ebl, Elf *core, int maxregname,
+                     const Ebl_Register_Location *regloc, const void *desc,
+                     unsigned int colno)
+{
+  if (regloc->bits % 8 != 0)
+    return handle_bit_registers (regloc, desc, colno);
+
+  desc += regloc->offset;
+
+  for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
+    {
+      const char *pfx;
+      const char *set;
+      char name[16];
+      int bits;
+      int type;
+      ssize_t n = ebl_register_info (ebl, reg, name, sizeof name,
+                                    &pfx, &set, &bits, &type);
+      if (n <= 0)
+       error (EXIT_FAILURE, 0,
+              gettext ("unable to handle register number %d"),
+              regloc->regno);
+
+#define TYPES                                                                \
+      BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8, 4);                          \
+      BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16, 6);                       \
+      BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32, 11);                    \
+      BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64, 20)
+
+#define BITS(bits, xtype, sfmt, ufmt, max)                             \
+      uint##bits##_t b##bits; int##bits##_t b##bits##s
+      union { TYPES; uint64_t b128[2]; } value;
+#undef BITS
+
+      switch (type)
+       {
+       case DW_ATE_unsigned:
+       case DW_ATE_signed:
+       case DW_ATE_address:
+         switch (bits)
+           {
+#define BITS(bits, xtype, sfmt, ufmt, max)                                   \
+           case bits:                                                        \
+             desc = convert (core, ELF_T_##xtype, 1, &value, desc);          \
+             if (type == DW_ATE_signed)                                      \
+               colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,    \
+                                        maxregname, name,                    \
+                                        max, sfmt, value.b##bits##s);        \
+             else                                                            \
+               colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,    \
+                                        maxregname, name,                    \
+                                        max, ufmt, value.b##bits);           \
+             break
+
+           TYPES;
+
+           case 128:
+             assert (type == DW_ATE_unsigned);
+             desc = convert (core, ELF_T_XWORD, 2, &value, desc);
+             int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
+             colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,
+                                      maxregname, name,
+                                      34, "0x%.16" PRIx64 "%.16" PRIx64,
+                                      value.b128[!be], value.b128[be]);
+             break;
+
+           default:
+             abort ();
+#undef BITS
+           }
+         break;
+
+       default:
+         /* Print each byte in hex, the whole thing in native byte order.  */
+         assert (bits % 8 == 0);
+         const uint8_t *bytes = desc;
+         desc += bits / 8;
+         char hex[bits / 4 + 1];
+         hex[bits / 4] = '\0';
+         int incr = 1;
+         if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
+           {
+             bytes += bits / 8 - 1;
+             incr = -1;
+           }
+         size_t idx = 0;
+         for (char *h = hex; bits > 0; bits -= 8, idx += incr)
+           {
+             *h++ = "0123456789abcdef"[bytes[idx] >> 4];
+             *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
+           }
+         colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN,
+                                  maxregname, name,
+                                  2 + sizeof hex - 1, "0x%s", hex);
+         break;
+       }
+      desc += regloc->pad;
+
+#undef TYPES
+    }
+
+  return colno;
+}
+
+
+struct register_info
+{
+  const Ebl_Register_Location *regloc;
+  const char *set;
+  char name[16];
+  Dwarf_Half regno;
+  uint8_t bits;
+  uint8_t type;
+};
+
+static int
+register_bitpos (const struct register_info *r)
+{
+  return (r->regloc->offset * 8
+         + ((r->regno - r->regloc->regno)
+            * (r->regloc->bits + r->regloc->pad * 8)));
+}
+
+static int
+compare_sets_by_info (const struct register_info *r1,
+                     const struct register_info *r2)
+{
+  return ((int) r2->bits - (int) r1->bits
+         ?: register_bitpos (r1) - register_bitpos (r2));
+}
+
+/* Sort registers by set, and by size and layout offset within each set.  */
+static int
+compare_registers (const void *a, const void *b)
+{
+  const struct register_info *r1 = a;
+  const struct register_info *r2 = b;
+
+  /* Unused elements sort last.  */
+  if (r1->regloc == NULL)
+    return r2->regloc == NULL ? 0 : 1;
+  if (r2->regloc == NULL)
+    return -1;
+
+  return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
+         ?: compare_sets_by_info (r1, r2));
+}
+
+/* Sort register sets by layout offset of the first register in the set.  */
+static int
+compare_register_sets (const void *a, const void *b)
+{
+  const struct register_info *const *p1 = a;
+  const struct register_info *const *p2 = b;
+  return compare_sets_by_info (*p1, *p2);
+}
+
+static unsigned int
+handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
+                      const Ebl_Register_Location *reglocs, size_t nregloc)
+{
+  if (nregloc == 0)
+    return 0;
+
+  ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
+  if (maxnreg <= 0)
+    error (EXIT_FAILURE, 0,
+          gettext ("cannot register info: %s"), elf_errmsg (-1));
+
+  struct register_info regs[maxnreg];
+  memset (regs, 0, sizeof regs);
+
+  /* Sort to collect the sets together.  */
+  int maxreg = 0;
+  for (size_t i = 0; i < nregloc; ++i)
+    for (int reg = reglocs[i].regno;
+        reg < reglocs[i].regno + reglocs[i].count;
+        ++reg)
+      {
+       assert (reg < maxnreg);
+       if (reg > maxreg)
+         maxreg = reg;
+       struct register_info *info = &regs[reg];
+
+       const char *pfx;
+       int bits;
+       int type;
+       ssize_t n = ebl_register_info (ebl, reg, info->name, sizeof info->name,
+                                      &pfx, &info->set, &bits, &type);
+       if (n <= 0)
+         error (EXIT_FAILURE, 0,
+                gettext ("cannot register info: %s"), elf_errmsg (-1));
+
+       info->regloc = &reglocs[i];
+       info->regno = reg;
+       info->bits = bits;
+       info->type = type;
+      }
+  qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
+
+  /* Collect the unique sets and sort them.  */
+  inline bool same_set (const struct register_info *a,
+                       const struct register_info *b)
+  {
+    return (a < &regs[maxnreg] && a->regloc != NULL
+           && b < &regs[maxnreg] && b->regloc != NULL
+           && a->bits == b->bits
+           && (a->set == b->set || !strcmp (a->set, b->set)));
+  }
+  struct register_info *sets[maxreg + 1];
+  sets[0] = &regs[0];
+  size_t nsets = 1;
+  for (int i = 1; i <= maxreg; ++i)
+    if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
+      sets[nsets++] = &regs[i];
+  qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
+
+  /* Write out all the sets.  */
+  unsigned int colno = 0;
+  for (size_t i = 0; i < nsets; ++i)
+    {
+      /* Find the longest name of a register in this set.  */
+      size_t maxname = 0;
+      const struct register_info *end;
+      for (end = sets[i]; same_set (sets[i], end); ++end)
+       {
+         size_t len = strlen (end->name);
+         if (len > maxname)
+           maxname = len;
+       }
+
+      for (const struct register_info *reg = sets[i];
+          reg < end;
+          reg += reg->regloc->count ?: 1)
+       colno = handle_core_register (ebl, core, maxname,
+                                     reg->regloc, desc, colno);
+
+      /* Force a line break at the end of the group.  */
+      colno = REGISTER_WRAP_COLUMN;
+    }
+
+  return colno;
+}
+
+static void
+handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, const void *desc)
+{
+  const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
+  for (size_t i = 0; i < nauxv; ++i)
+    {
+      const GElf_auxv_t *av = (const GElf_auxv_t *) desc + i;
+
+      const char *name;
+      const char *fmt;
+      if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
+       {
+         /* Unknown type.  */
+         if (av->a_un.a_val == 0)
+           printf ("    %" PRIu64 "\n", av->a_type);
+         else
+           printf ("    %" PRIu64 ": %#" PRIx64 "\n",
+                   av->a_type, av->a_un.a_val);
+       }
+      else
+       switch (fmt[0])
+         {
+         case '\0':            /* Normally zero.  */
+           if (av->a_un.a_val == 0)
+             {
+               printf ("    %s\n", name);
+               break;
+             }
+           /* Fall through */
+         case 'x':             /* hex */
+         case 'p':             /* address */
+         case 's':             /* address of string */
+           printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
+           break;
+         case 'u':
+           printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
+           break;
+         case 'd':
+           printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
+           break;
+
+         case 'b':
+           printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
+           GElf_Xword bit = 1;
+           const char *pfx = "<";
+           for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
+             {
+               if (av->a_un.a_val & bit)
+                 {
+                   printf ("%s%s", pfx, p);
+                   pfx = " ";
+                 }
+               bit <<= 1;
+             }
+           printf (">\n");
+           break;
+
+         default:
+           abort ();
+         }
+    }
+}
+
+static void
+handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const void *desc)
+{
+  GElf_Word regs_offset;
+  size_t nregloc;
+  const Ebl_Register_Location *reglocs;
+  size_t nitems;
+  const Ebl_Core_Item *items;
+
+  if (! ebl_core_note (ebl, nhdr->n_type, nhdr->n_descsz,
+                      &regs_offset, &nregloc, &reglocs, &nitems, &items))
+    return;
+
+  unsigned int colno = handle_core_items (ebl->elf, desc, items, nitems);
+  if (colno != 0)
+    putchar_unlocked ('\n');
+
+  colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
+                                reglocs, nregloc);
+  if (colno != 0)
+    putchar_unlocked ('\n');
+}
+
+
 static void
 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
 {
@@ -4998,18 +5614,13 @@ handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
       size_t idx = 0;
       while (idx < phdr->p_filesz)
        {
-         /* XXX Handle 64-bit note section entries correctly.  */
-         struct
-         {
-           uint32_t namesz;
-           uint32_t descsz;
-           uint32_t type;
-           char name[0];
-         } *noteentry = (__typeof (noteentry)) (notemem + idx);
+         const GElf_Nhdr *nhdr = (const GElf_Nhdr *) (notemem + idx);
+         const char *name = (const char *) (nhdr + 1);
+         const void *desc = &name[ALIGNED_LEN (nhdr->n_namesz)];
 
          if (idx + 12 > phdr->p_filesz
-             || (idx + 12 + ALIGNED_LEN (noteentry->namesz)
-                 + ALIGNED_LEN (noteentry->descsz) > phdr->p_filesz))
+             || (idx + 12 + ALIGNED_LEN (nhdr->n_namesz)
+                 + ALIGNED_LEN (nhdr->n_descsz) > phdr->p_filesz))
            /* This entry isn't completely contained in the note
               section.  Ignore it.  */
            break;
@@ -5017,32 +5628,34 @@ handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
          char buf[100];
          char buf2[100];
          printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
-                 (int) noteentry->namesz, noteentry->name,
-                 noteentry->descsz,
+                 (int) nhdr->n_namesz, name,
+                 nhdr->n_descsz,
                  ehdr->e_type == ET_CORE
-                 ? ebl_core_note_type_name (ebl, noteentry->type,
+                 ? ebl_core_note_type_name (ebl, nhdr->n_type,
                                             buf, sizeof (buf))
-                 : ebl_object_note_type_name (ebl, noteentry->type,
+                 : ebl_object_note_type_name (ebl, nhdr->n_type,
                                               buf2, sizeof (buf2)));
 
          /* Filter out invalid entries.  */
-         if (memchr (noteentry->name, '\0', noteentry->namesz) != NULL
+         if (memchr (name, '\0', nhdr->n_namesz) != NULL
              /* XXX For now help broken Linux kernels.  */
              || 1)
            {
              if (ehdr->e_type == ET_CORE)
-               ebl_core_note (ebl, noteentry->name, noteentry->type,
-                              noteentry->descsz,
-                              &noteentry->name[ALIGNED_LEN (noteentry->namesz)]);
+               {
+                 if (nhdr->n_type == NT_AUXV)
+                   handle_auxv_note (ebl, ebl->elf, nhdr->n_descsz, desc);
+                 else
+                   handle_core_note (ebl, nhdr, desc);
+               }
              else
-               ebl_object_note (ebl, noteentry->name, noteentry->type,
-                                noteentry->descsz,
-                                &noteentry->name[ALIGNED_LEN (noteentry->namesz)]);
+               ebl_object_note (ebl, name, nhdr->n_type,
+                                nhdr->n_descsz, desc);
            }
 
          /* Move to the next entry.  */
-         idx += (12 + ALIGNED_LEN (noteentry->namesz)
-                 + ALIGNED_LEN (noteentry->descsz));
+         idx += (12 + ALIGNED_LEN (nhdr->n_namesz)
+                 + ALIGNED_LEN (nhdr->n_descsz));
        }
 
       gelf_freechunk (ebl->elf, notemem);
index c1d40f1ca60dc95f8de97cdce5e2ededffb7189e..a8c30022fc2c397e93ff88181ba2c0be1f12fd43 100644 (file)
@@ -1094,6 +1094,73 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
   return split_bss;
 }
 
+/* Create new .shstrtab contents, subroutine of copy_elided_sections.
+   This can't be open coded there and still use variable-length auto arrays,
+   since the end of our block would free other VLAs too.  */
+static Elf_Data *
+new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
+             Elf_Data *shstrtab, size_t unstripped_shstrndx,
+             struct section *sections, size_t stripped_shnum,
+             struct Ebl_Strtab *strtab)
+{
+  if (strtab == NULL)
+    return NULL;
+
+  struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1];
+  memset (unstripped_strent, 0, sizeof unstripped_strent);
+  for (struct section *sec = sections;
+       sec < &sections[stripped_shnum - 1];
+       ++sec)
+    if (sec->outscn != NULL)
+      {
+       if (sec->strent == NULL)
+         {
+           sec->strent = ebl_strtabadd (strtab, sec->name, 0);
+           ELF_CHECK (sec->strent != NULL,
+                      _("cannot add section name to string table: %s"));
+         }
+       unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent;
+      }
+
+  /* Add names of sections we aren't touching.  */
+  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
+    if (unstripped_strent[i] == NULL)
+      {
+       Elf_Scn *scn = elf_getscn (unstripped, i + 1);
+       GElf_Shdr shdr_mem;
+       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+       const char *name = get_section_name (i + 1, shdr, shstrtab);
+       unstripped_strent[i] = ebl_strtabadd (strtab, name, 0);
+       ELF_CHECK (unstripped_strent[i] != NULL,
+                  _("cannot add section name to string table: %s"));
+      }
+    else
+      unstripped_strent[i] = NULL;
+
+  /* Now finalize the string table so we can get offsets.  */
+  Elf_Data *strtab_data = elf_getdata (elf_getscn (unstripped,
+                                                  unstripped_shstrndx), NULL);
+  ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
+            _("cannot update section header string table data: %s"));
+  ebl_strtabfinalize (strtab, strtab_data);
+
+  /* Update the sh_name fields of sections we aren't modifying later.  */
+  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
+    if (unstripped_strent[i] != NULL)
+      {
+       Elf_Scn *scn = elf_getscn (unstripped, i + 1);
+       GElf_Shdr shdr_mem;
+       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+       shdr->sh_name = ebl_strtaboffset (unstripped_strent[i]);
+       if (i + 1 == unstripped_shstrndx)
+         shdr->sh_size = strtab_data->d_size;
+       ELF_CHECK (gelf_update_shdr (scn, shdr),
+                  _("cannot update section header: %s"));
+      }
+
+  return strtab_data;
+}
+
 /* Fill in any SHT_NOBITS sections in UNSTRIPPED by
    copying their contents and sh_type from STRIPPED.  */
 static void
@@ -1310,63 +1377,11 @@ copy_elided_sections (Elf *unstripped, Elf *stripped,
       ndx_section[secndx - 1] = elf_ndxscn (sec->outscn);
     }
 
-  Elf_Data *strtab_data = NULL;
-  if (strtab != NULL)
-    {
-      /* We added some sections, so we need a new shstrtab.  */
-
-      struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1];
-      memset (unstripped_strent, 0, sizeof unstripped_strent);
-      for (struct section *sec = sections;
-          sec < &sections[stripped_shnum - 1];
-          ++sec)
-       if (sec->outscn != NULL)
-         {
-           if (sec->strent == NULL)
-             {
-               sec->strent = ebl_strtabadd (strtab, sec->name, 0);
-               ELF_CHECK (sec->strent != NULL,
-                          _("cannot add section name to string table: %s"));
-             }
-           unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent;
-         }
-
-      /* Add names of sections we aren't touching.  */
-      for (size_t i = 0; i < unstripped_shnum - 1; ++i)
-       if (unstripped_strent[i] == NULL)
-         {
-           scn = elf_getscn (unstripped, i + 1);
-           GElf_Shdr shdr_mem;
-           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
-           const char *name = get_section_name (i + 1, shdr, shstrtab);
-           unstripped_strent[i] = ebl_strtabadd (strtab, name, 0);
-           ELF_CHECK (unstripped_strent[i] != NULL,
-                      _("cannot add section name to string table: %s"));
-         }
-       else
-         unstripped_strent[i] = NULL;
-
-      /* Now finalize the string table so we can get offsets.  */
-      strtab_data = elf_getdata (elf_getscn (unstripped, unstripped_shstrndx),
-                                NULL);
-      ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
-                _("cannot update section header string table data: %s"));
-      ebl_strtabfinalize (strtab, strtab_data);
-
-      /* Update the sh_name fields of sections we aren't modifying later.  */
-      for (size_t i = 0; i < unstripped_shnum - 1; ++i)
-       if (unstripped_strent[i] != NULL)
-         {
-           scn = elf_getscn (unstripped, i + 1);
-           GElf_Shdr shdr_mem;
-           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
-           shdr->sh_name = ebl_strtaboffset (unstripped_strent[i]);
-           if (i + 1 == unstripped_shstrndx)
-             shdr->sh_size = strtab_data->d_size;
-           ELF_CHECK (gelf_update_shdr (scn, shdr),
-                      _("cannot update section header: %s"));
-         }
-    }
+  /* We added some sections, so we need a new shstrtab.  */
+  Elf_Data *strtab_data = new_shstrtab (unstripped, unstripped_shnum,
+                                       shstrtab, unstripped_shstrndx,
+                                       sections, stripped_shnum,
+                                       strtab);
 
   /* Get the updated section count.  */
   ELF_CHECK (elf_getshnum (unstripped, &unstripped_shnum) == 0,
index cc7e0727995519f08be024e869232f4ff3357be9..adfcb2c7557733726ed7f6785feb54f6eb527de8 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-23  Roland McGrath  <roland@redhat.com>
+
+       * run-allregs.sh: Update expected x86-64 output for %rflags.
+
 2007-08-12  Roland McGrath  <roland@redhat.com>
 
        * run-strip-test7.sh: New file.
index 74f9738006a26d3202b00f8b4e76fe4641a34958..c7f46b0b9a7acc582227bbcf922704fcda1bfc1b 100755 (executable)
@@ -106,6 +106,7 @@ integer registers:
         14: %r14 (r14), signed 64 bits
         15: %r15 (r15), signed 64 bits
         16: %rip (rip), address 64 bits
+        49: %rflags (rflags), unsigned 64 bits
 MMX registers:
         41: %mm0 (mm0), unsigned 64 bits
         42: %mm1 (mm1), unsigned 64 bits
@@ -133,7 +134,6 @@ SSE registers:
         31: %xmm14 (xmm14), unsigned 128 bits
         32: %xmm15 (xmm15), unsigned 128 bits
 control registers:
-        49: %rflags (rflags), unsigned 64 bits
         62: %tr (tr), unsigned 64 bits
         63: %ldtr (ldtr), unsigned 64 bits
         64: %mxcsr (mxcsr), unsigned 64 bits