+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.
/* 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
#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[] =
/* 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
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_*.
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];
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;
#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]; \
/* 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
#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,
+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.
/* 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
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. */
/* 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. */
*regs_offset = 0;
*nregloc = 0;
*reglocs = NULL;
- switch (n_type)
+ switch (nhdr->n_type)
{
#define ITEMS(type, table) \
case type: \
/* 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
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 **);
}
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
/* 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
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,
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.
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)
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);
}
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;
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,
®s_offset, &nregloc, ®locs, &nitems, &items))
return;
{
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);