]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Make readelf -n check note name strings, handle "VMCOREINFO" flavor.
authorRoland McGrath <roland@redhat.com>
Tue, 5 Jan 2010 05:59:07 +0000 (21:59 -0800)
committerRoland McGrath <roland@redhat.com>
Tue, 5 Jan 2010 05:59:07 +0000 (21:59 -0800)
backends/ChangeLog
backends/i386_corenote.c
backends/linux-core-note.c
backends/x86_corenote.c
libebl/ChangeLog
libebl/ebl-hooks.h
libebl/eblcorenote.c
libebl/eblopenbackend.c
libebl/libebl.h
src/ChangeLog
src/readelf.c

index c7f6d3662d162feca5f4e2e77d07b00b7de91be8..69351b323df437e845cf2608f25eb8a863611491 100644 (file)
@@ -1,3 +1,12 @@
+2010-01-04  Roland McGrath  <roland@redhat.com>
+
+       * linux-core-note.c (vmcoreinfo_items): New static const variable.
+       (EBLHOOK(core_note)): Update arguments for new protocol.
+       Validate the name as "CORE" or "LINUX" for known n_type cases.
+       Handle name "VMCOREINFO" n_type=0 with vmcoreinfo_items.
+       * i386_corenote.c (EXTRA_NOTES): Update parameter usage.
+       * x86_corenote.c (EXTRA_NOTES_IOPERM): Likewise.
+
 2009-09-10  Mark Wielaard  <mjw@redhat.com>
 
        * sparc_retval.c: Fix license header.
index 89890252c0946064c67e69e02fe5e145f8dfacdc..40b6a24ec4d38d2868b75ee0b50a3cb7e574f0ef 100644 (file)
@@ -1,5 +1,5 @@
 /* i386 specific core note handling.
-   Copyright (C) 2007-2009 Red Hat, Inc.
+   Copyright (C) 2007-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -103,7 +103,8 @@ static const Ebl_Register_Location prxfpreg_regs[] =
 #define        EXTRA_NOTES \
   EXTRA_REGSET (NT_PRXFPREG, 512, prxfpreg_regs) \
   case NT_386_TLS: \
-    return tls_info (descsz, regs_offset, nregloc, reglocs, nitems, items); \
+    return tls_info (nhdr->n_descsz, regs_offset, nregloc, reglocs, \
+                    nitems, items);                                \
   EXTRA_NOTES_IOPERM
 
 static const Ebl_Core_Item tls_items[] =
index 7b1fc025aa6d177ee952d0823cc2826511a4c2a0..9d01219c7662e0ef4a61e07f284577eed5bc358d 100644 (file)
@@ -1,5 +1,5 @@
 /* Common core note type descriptions for Linux.
-   Copyright (C) 2007, 2008 Red Hat, Inc.
+   Copyright (C) 2007-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -23,6 +23,8 @@
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
+#include <string.h>
+
 /* The including CPU_corenote.c file provides prstatus_regs and
    defines macros ULONG, [PUG]ID_T, and ALIGN_*, TYPE_*.
 
@@ -163,23 +165,61 @@ static const Ebl_Core_Item prpsinfo_items[] =
     FIELD (command, CHAR, psargs, 's', .count = PRARGSZ),
   };
 
+static const Ebl_Core_Item vmcoreinfo_items[] =
+  {
+    {
+      .type = ELF_T_BYTE, .format = '\n'
+    }
+  };
+
 #undef FIELD
 
 int
-EBLHOOK(core_note) (n_type, descsz,
-                   regs_offset, nregloc, reglocs, nitems, items)
-     GElf_Word n_type;
-     GElf_Word descsz;
+EBLHOOK(core_note) (nhdr, name, regs_offset, nregloc, reglocs, nitems, items)
+     const GElf_Nhdr *nhdr;
+     const char *name;
      GElf_Word *regs_offset;
      size_t *nregloc;
      const Ebl_Register_Location **reglocs;
      size_t *nitems;
      const Ebl_Core_Item **items;
 {
-  switch (n_type)
+  switch (nhdr->n_namesz)
+    {
+    case sizeof "CORE" - 1:    /* Buggy old Linux kernels.  */
+      if (memcmp (name, "CORE", nhdr->n_namesz) == 0)
+       break;
+      return 0;
+
+    case sizeof "CORE":
+      if (memcmp (name, "CORE", nhdr->n_namesz) == 0)
+       break;
+      /* Buggy old Linux kernels didn't terminate "LINUX".
+         Fall through.  */
+
+    case sizeof "LINUX":
+      if (memcmp (name, "LINUX", nhdr->n_namesz) == 0)
+       break;
+      return 0;
+
+    case sizeof "VMCOREINFO":
+      if (nhdr->n_type != 0
+         || memcmp (name, "VMCOREINFO", sizeof "VMCOREINFO") != 0)
+       return 0;
+      *regs_offset = 0;
+      *nregloc = 0;
+      *nitems = 1;
+      *items = vmcoreinfo_items;
+      return 1;
+
+    default:
+      return 0;
+    }
+
+  switch (nhdr->n_type)
     {
     case NT_PRSTATUS:
-      if (descsz != sizeof (struct EBLHOOK(prstatus)))
+      if (nhdr->n_descsz != sizeof (struct EBLHOOK(prstatus)))
        return 0;
       *regs_offset = offsetof (struct EBLHOOK(prstatus), pr_reg);
       *nregloc = sizeof prstatus_regs / sizeof prstatus_regs[0];
@@ -189,7 +229,7 @@ EBLHOOK(core_note) (n_type, descsz,
       return 1;
 
     case NT_PRPSINFO:
-      if (descsz != sizeof (struct EBLHOOK(prpsinfo)))
+      if (nhdr->n_descsz != sizeof (struct EBLHOOK(prpsinfo)))
        return 0;
       *regs_offset = 0;
       *nregloc = 0;
@@ -200,7 +240,7 @@ EBLHOOK(core_note) (n_type, descsz,
 
 #define EXTRA_REGSET(type, size, table)                                              \
     case type:                                                               \
-      if (descsz != size)                                                    \
+      if (nhdr->n_descsz != size)                                            \
        return 0;                                                             \
       *regs_offset = 0;                                                              \
       *nregloc = sizeof table / sizeof table[0];                             \
index 7d5506769ae2a7f90d6e9dc82fc4dcfbf3d600dc..78849a666770765e01e25a1af919ab4ab8248ccd 100644 (file)
@@ -1,5 +1,5 @@
 /* x86-specific core note handling, pieces common to x86-64 and i386.
-   Copyright (C) 2005, 2008 Red Hat, Inc.
+   Copyright (C) 2005-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -25,7 +25,8 @@
 
 #define        EXTRA_NOTES_IOPERM \
   case NT_386_IOPERM: \
-    return ioperm_info (descsz, regs_offset, nregloc, reglocs, nitems, items);
+    return ioperm_info (nhdr->n_descsz, \
+                       regs_offset, nregloc, reglocs, nitems, items);
 
 static int
 ioperm_info (GElf_Word descsz, GElf_Word *regs_offset,
index c4411e701da39841f7de877499bb8aabd16b8a3b..aaa1c86d9557bd209c348ca938e35fdb75d98b70 100644 (file)
@@ -1,3 +1,11 @@
+2010-01-04  Roland McGrath  <roland@redhat.com>
+
+       * eblcorenote.c (ebl_core_note): Take GElf_Nhdr * and name data
+       pointer instead of only n_type and n_descsz.
+       * libebl.h: Update declaration.
+       * ebl-hooks.h: Update core_note hook signature.
+       * eblopenbackend.c (default_core_note): Likewise.
+
 2009-10-14  Roland McGrath  <roland@redhat.com>
 
        * eblobjnote.c (ebl_object_note): Clean up NT_GNU_GOLD_VERSION printing.
index d483f2a3ae6e81c51765715dc0e17473239da5b7..59e73c54e52400d3be8a648af8b043bb908a77fc 100644 (file)
@@ -1,5 +1,5 @@
 /* Backend hook signatures internal interface for libebl.
-   Copyright (C) 2000-2009 Red Hat, Inc.
+   Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -114,8 +114,8 @@ const char *EBLHOOK(core_note_type_name) (uint32_t, char *, size_t);
 const char *EBLHOOK(object_note_type_name) (uint32_t, char *, size_t);
 
 /* Describe core note format.  */
-int EBLHOOK(core_note) (GElf_Word, GElf_Word, GElf_Word *, size_t *,
-                       const Ebl_Register_Location **,
+int EBLHOOK(core_note) (const GElf_Nhdr *, const char *,
+                       GElf_Word *, size_t *, const Ebl_Register_Location **,
                        size_t *, const Ebl_Core_Item **);
 
 /* Handle object file note.  */
index 553d5ba933c34c87c0982c3417a9cdd29099c863..7549ca61d3be61ae9aa00ec9a9c420831cb430e9 100644 (file)
@@ -1,5 +1,5 @@
 /* Describe known core note formats.
-   Copyright (C) 2007 Red Hat, Inc.
+   Copyright (C) 2007, 2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
 
 
 int
-ebl_core_note (ebl, n_type, descsz,
+ebl_core_note (ebl, nhdr, name,
               regs_offset, nregloc, reglocs, nitems, items)
      Ebl *ebl;
-     GElf_Word n_type;
-     GElf_Word descsz;
+     const GElf_Nhdr *nhdr;
+     const char *name;
      GElf_Word *regs_offset;
      size_t *nregloc;
      const Ebl_Register_Location **reglocs;
      size_t *nitems;
      const Ebl_Core_Item **items;
 {
-  int result = ebl->core_note (n_type, descsz, regs_offset, nregloc, reglocs,
-                              nitems, items);
+  int result = ebl->core_note (nhdr, name,
+                              regs_offset, nregloc, reglocs, nitems, items);
   if (result == 0)
     {
       /* The machine specific function did not know this type.  */
@@ -81,7 +81,7 @@ ebl_core_note (ebl, n_type, descsz,
       *regs_offset = 0;
       *nregloc = 0;
       *reglocs = NULL;
-      switch (n_type)
+      switch (nhdr->n_type)
        {
 #define ITEMS(type, table)                             \
          case type:                                    \
index b1bad903d6072e8e507a2a85ed818ce677a7a0f6..edd8c4a756f4bc89d8cd894caaa8d4aff14c223f 100644 (file)
@@ -1,5 +1,5 @@
 /* Generate ELF backend handle.
-   Copyright (C) 2000-2009 Red Hat, Inc.
+   Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -186,7 +186,7 @@ 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 int default_core_note (GElf_Word n_type, GElf_Word descsz,
+static int default_core_note (const GElf_Nhdr *nhdr, const char *name,
                              GElf_Word *regs_offset, size_t *nregloc,
                              const Ebl_Register_Location **reglocs,
                              size_t *nitems, const Ebl_Core_Item **);
@@ -604,8 +604,8 @@ default_auxv_info (GElf_Xword a_type __attribute__ ((unused)),
 }
 
 static int
-default_core_note (GElf_Word n_type __attribute__ ((unused)),
-                  GElf_Word descsz __attribute__ ((unused)),
+default_core_note (const GElf_Nhdr *nhdr __attribute__ ((unused)),
+                  const char *name __attribute__ ((unused)),
                   GElf_Word *ro __attribute__ ((unused)),
                   size_t *nregloc  __attribute__ ((unused)),
                   const Ebl_Register_Location **reglocs
index 1a56b9663d85db4715e8d59ef9e5ec9776226b2d..c94ad78f2079fc93be750ea2c08293c2ebb8cda4 100644 (file)
@@ -1,5 +1,5 @@
 /* Interface for libebl.
-   Copyright (C) 2000, 2001-2009 Red Hat, Inc.
+   Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -379,13 +379,13 @@ typedef struct
   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,
+/* Describe the format of a core file note with the given header and NAME.
+   NAME is not guaranteed terminated, it's NHDR->n_namesz raw bytes.  */
+extern int ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name,
                          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);
+  __nonnull_attribute__ (1, 2, 3, 4, 5, 6, 7, 8);
 
 /* Describe the auxv type number.  */
 extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type,
index c03f0b455b946ff2ce4561b4adbf338a07d8bbaa..2e48a4e3008f5c920d2bd1f8a83928cdcc50707d 100644 (file)
@@ -1,5 +1,9 @@
 2010-01-04  Roland McGrath  <roland@redhat.com>
 
+       * readelf.c (handle_notes_data): Grab NT_AUXV only for name "CORE".
+       (handle_core_note): Pass NHDR and NAME to ebl_core_note.
+       (handle_core_item): Handle .format of '\n' as \n-separated strings.
+
        * readelf.c (implicit_debug_sections): New variable.
        (parse_opt): Set it instead of print_debug_sections for -a.
        OR them together for print_debug check.
index ffd7ff458247c142c6a9a48fb2908470cffcada7..2c263ec7af21c5f577edd9343b2ceae1836dfc16 100644 (file)
@@ -6643,11 +6643,11 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
          convsize = count * size;
          *repeated_size -= convsize;
        }
-      else
+      else if (item->count != 0 || item->format != '\n')
        *repeated_size -= size;
     }
 
-  desc = convert (core, item->type, count, data, desc + item->offset, convsize);
+  convert (core, item->type, count, data, desc + item->offset, convsize);
 
   Elf_Type type = item->type;
   if (type == ELF_T_ADDR)
@@ -6793,6 +6793,33 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
                               count, "%.*s", (int) count, value.Byte);
       break;
 
+    case '\n':
+      /* This is a list of strings separated by '\n'.  */
+      assert (item->count == 0);
+      assert (repeated_size != NULL);
+      assert (item->name == NULL);
+      if (unlikely (item->offset >= *repeated_size))
+       break;
+
+      const char *s = desc + item->offset;
+      size = *repeated_size - item->offset;
+      *repeated_size = 0;
+      while (size > 0)
+       {
+         const char *eol = memchr (s, '\n', size);
+         int len = size;
+         if (eol != NULL)
+           len = eol - s;
+         printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
+         if (eol == NULL)
+           break;
+         size -= eol + 1 - s;
+         s = eol + 1;
+       }
+
+      colno = ITEM_WRAP_COLUMN;
+      break;
+
     default:
       error (0, 0, "XXX not handling format '%c' for %s",
             item->format, item->name);
@@ -7237,7 +7264,8 @@ handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
 }
 
 static void
-handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const void *desc)
+handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
+                 const char *name, const void *desc)
 {
   GElf_Word regs_offset;
   size_t nregloc;
@@ -7245,7 +7273,7 @@ handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const void *desc)
   size_t nitems;
   const Ebl_Core_Item *items;
 
-  if (! ebl_core_note (ebl, nhdr->n_type, nhdr->n_descsz,
+  if (! ebl_core_note (ebl, nhdr, name,
                       &regs_offset, &nregloc, &reglocs, &nitems, &items))
     return;
 
@@ -7302,11 +7330,14 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
        {
          if (ehdr->e_type == ET_CORE)
            {
-             if (nhdr.n_type == NT_AUXV)
+             if (nhdr.n_type == NT_AUXV
+                 && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
+                     || (nhdr.n_namesz == 5 && name[4] == '\0'))
+                 && !memcmp (name, "CORE", 4))
                handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
                                  start + desc_offset);
              else
-               handle_core_note (ebl, &nhdr, desc);
+               handle_core_note (ebl, &nhdr, name, desc);
            }
          else
            ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);