This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Handling NT_SIGINFO, NT_FILE in core files
- From: Petr Machata <pmachata at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Thu, 26 Sep 2013 01:17:11 +0200
- Subject: Handling NT_SIGINFO, NT_FILE in core files
Hi there,
I noticed that newer kernels put NT_SIGINFO and NT_FILE core notes into
core dumps.
NT_SIGINFO is tricky as interpretation of fields further in the note
depends of those earlier in. I don't think our core note item mechanism
can handle this. Instead, I made them special, they are handled
similarly to how NT_AUXV is. The patch is attached below.
In reality, the libebl/eblcorenotetypename.c is split out into a
separate commit, and there are ChangeLog's. I thought this format might
make this easier to review. It's all on branch pmachata/NT_SIGINFO.
I haven't had a chance to look at NT_FILE yet, but I intend to.
OK for master?
Thanks,
PM
diff --git a/libebl/eblcorenotetypename.c b/libebl/eblcorenotetypename.c
index 21fff73..b6db6cd 100644
--- a/libebl/eblcorenotetypename.c
+++ b/libebl/eblcorenotetypename.c
@@ -1,5 +1,5 @@
/* Return note type name.
- Copyright (C) 2002, 2007, 2008, 2012 Red Hat, Inc.
+ Copyright (C) 2002, 2007, 2008, 2012, 2013 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -91,6 +91,11 @@ ebl_core_note_type_name (ebl, type, buf, len)
KNOWNSTYPE (S390_LAST_BREAK);
KNOWNSTYPE (S390_SYSTEM_CALL);
KNOWNSTYPE (ARM_VFP);
+ KNOWNSTYPE (ARM_TLS);
+ KNOWNSTYPE (ARM_HW_BREAK);
+ KNOWNSTYPE (ARM_HW_WATCH);
+ KNOWNSTYPE (SIGINFO);
+ KNOWNSTYPE (FILE);
#undef KNOWNSTYPE
default:
diff --git a/src/readelf.c b/src/readelf.c
index 119c100..199199a 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -42,6 +42,7 @@
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>
+#include <signal.h>
#include <system.h>
#include "../libelf/libelfP.h"
@@ -8617,6 +8618,93 @@ handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
}
static void
+handle_siginfo_note (__attribute__ ((unused)) Ebl *ebl,
+ Elf *core,
+ GElf_Word descsz,
+ GElf_Off desc_pos)
+{
+ if (descsz != 128)
+ return;
+
+ Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
+ const unsigned char *ptr = data->d_buf;
+ if (data == NULL)
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
+
+#define READ_INT \
+ ({ \
+ int val; \
+ ptr = convert (core, ELF_T_WORD, 1, &val, ptr, 4); \
+ val; \
+ })
+
+#define READ_ADDR \
+ ({ \
+ union \
+ { \
+ uint64_t u64; \
+ uint32_t u32; \
+ } u; \
+ ptr = convert (core, ELF_T_ADDR, 1, &u, ptr, sizeof u); \
+ if (gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT) == 4) \
+ u.u64 = u.u32; \
+ u.u64; \
+ })
+
+ /* Siginfo head is three ints: signal number, error number, origin
+ code. */
+ int si_signo = READ_INT;
+ int si_errno = READ_INT;
+ int si_code = READ_INT;
+
+ /* Next is a pointer-aligned union of structures. On 64-bit
+ machines, that implies a word of padding. */
+ if (gelf_getclass (core) == ELFCLASS64)
+ ptr += 4;
+
+ printf (" si_signo:%d, si_errno:%d, si_code:%d\n",
+ si_signo, si_errno, si_code);
+
+ if (si_code <= 0)
+ switch (si_code)
+ {
+ case SI_ASYNCIO:
+ case SI_MESGQ:
+ case SI_TIMER:
+ case SI_QUEUE:
+ default:
+ break;
+
+ case SI_USER:
+ {
+ int pid = READ_INT;
+ int uid = READ_INT;
+ printf (" sender_pid:%d, sender_uid:%d\n", pid, uid);
+ break;
+ }
+ }
+ else
+ switch (si_signo)
+ {
+ case SIGILL:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGBUS:
+ {
+ uint64_t addr = READ_ADDR;
+ printf (" sigfault.addr:%#" PRIx64 "\n", addr);
+ break;
+ }
+ default:
+ ;
+ }
+
+#undef READ_INT
+#undef READ_ADDR
+}
+
+static void
handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
const char *name, const void *desc)
{
@@ -8689,6 +8777,10 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
&& !memcmp (name, "CORE", 4))
handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
start + desc_offset);
+ else if (nhdr.n_type == NT_SIGINFO
+ && nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
+ handle_siginfo_note (ebl, ebl->elf, nhdr.n_descsz,
+ start + desc_offset);
else
handle_core_note (ebl, &nhdr, name, desc);
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 58db6c3..0024395 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -198,7 +198,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \
testfile65.bz2 testfile67.bz2 testfile68.bz2 \
testfile69.core.bz2 testfile69.so.bz2 \
- testfile70.core.bz2 testfile70.exec.bz2 \
+ testfile70.core.bz2 testfile70.exec.bz2 testfile71.bz2 \
run-dwfllines.sh run-dwfl-report-elf-align.sh \
testfile-dwfl-report-elf-align-shlib.so.bz2 \
testfilenolines.bz2 test-core-lib.so.bz2 test-core.core.bz2 \
diff --git a/tests/run-readelf-mixed-corenote.sh b/tests/run-readelf-mixed-corenote.sh
index 915bdeb..ab8a72f 100755
--- a/tests/run-readelf-mixed-corenote.sh
+++ b/tests/run-readelf-mixed-corenote.sh
@@ -1,5 +1,5 @@
#! /bin/sh
-# Copyright (C) 2012 Red Hat, Inc.
+# Copyright (C) 2012, 2013 Red Hat, Inc.
# This file is part of elfutils.
#
# This file is free software; you can redistribute it and/or modify
@@ -217,4 +217,57 @@ Note segment of 852 bytes at offset 0x94:
high_r15: 0x00000000
EOF
+testfiles testfile71
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile71 <<\EOF
+
+Note segment of 1476 bytes at offset 0x430:
+ Owner Data size Type
+ CORE 336 PRSTATUS
+ info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
+ sigpend: <>
+ sighold: <>
+ pid: 9664, ppid: 2868, pgrp: 9664, sid: 2868
+ utime: 0.000000, stime: 0.004000, cutime: 0.000000, cstime: 0.000000
+ orig_rax: -1, fpvalid: 0
+ r15: 0 r14: 0
+ r13: 140734971656848 r12: 4195328
+ rbp: 0x00007fff69fe39b0 rbx: 0
+ r11: 266286012928 r10: 140734971656256
+ r9: 0 r8: 266289790592
+ rax: 305419896 rcx: 4195584
+ rdx: 140734971656872 rsi: 140734971656856
+ rdi: 1 rip: 0x00000000004004f9
+ rflags: 0x0000000000010246 rsp: 0x00007fff69fe39b0
+ fs.base: 0x00007fa1c8933740 gs.base: 0x0000000000000000
+ cs: 0x0033 ss: 0x002b ds: 0x0000 es: 0x0000 fs: 0x0000 gs: 0x0000
+ CORE 136 PRPSINFO
+ state: 0, sname: R, zomb: 0, nice: 0, flag: 0x0000000000000200
+ uid: 1000, gid: 1000, pid: 9664, ppid: 2868, pgrp: 9664, sid: 2868
+ fname: a.out, psargs: ./a.out
+ CORE 128 SIGINFO
+ si_signo:11, si_errno:0, si_code:1
+ sigfault.addr:0x12345678
+ CORE 304 AUXV
+ SYSINFO_EHDR: 0x7fff69ffe000
+ HWCAP: 0xafebfbff <fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss tm pbe>
+ PAGESZ: 4096
+ CLKTCK: 100
+ PHDR: 0x400040
+ PHENT: 56
+ PHNUM: 9
+ BASE: 0
+ FLAGS: 0
+ ENTRY: 0x400400
+ UID: 1000
+ EUID: 1000
+ GID: 1000
+ EGID: 1000
+ SECURE: 0
+ RANDOM: 0x7fff69fe3d19
+ EXECFN: 0x7fff69fe4ff0
+ PLATFORM: 0x7fff69fe3d29
+ NULL
+ CORE 469 FILE
+EOF
+
exit 0
diff --git a/tests/testfile71.bz2 b/tests/testfile71.bz2
new file mode 100644
index 0000000..ce5b08f
Binary files /dev/null and b/tests/testfile71.bz2 differ