diff options
author | Petr Machata <pmachata@redhat.com> | 2013-09-26 00:39:34 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2013-09-30 13:43:57 +0200 |
commit | ab22410aed2732016c598c47102d47df659ede0c (patch) | |
tree | b1c50ab75e8f9b3ee8a575fdd47a156bb37f8521 | |
parent | 74f9b7337562c06a93722ad757d258db8f082663 (diff) | |
download | elfutils-ab22410aed2732016c598c47102d47df659ede0c.tar.gz |
Show contents NT_SIGINFO core note in readelf
Signed-off-by: Petr Machata <pmachata@redhat.com>
-rw-r--r-- | src/ChangeLog | 6 | ||||
-rw-r--r-- | src/readelf.c | 103 | ||||
-rw-r--r-- | tests/ChangeLog | 6 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rwxr-xr-x | tests/run-readelf-mixed-corenote.sh | 59 | ||||
-rw-r--r-- | tests/testfile71.bz2 | bin | 0 -> 18164 bytes |
6 files changed, 174 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 6788087d..9d4c2e2c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2013-09-26 Petr Machata <pmachata@redhat.com> + + * readelf.c (handle_siginfo_note): New function. + (handle_notes_data): Call it to handle NT_SIGINFO notes. + (buf_read_int, buf_read_ulong, buf_has_data): New functions. + 2013-08-13 Mark Wielaard <mjw@redhat.com> * addr2line.c (options): Add "inlines", 'i'. diff --git a/src/readelf.c b/src/readelf.c index 119c1000..da3661c0 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" @@ -8616,6 +8617,104 @@ handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos) } } +static bool +buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz) +{ + return ptr < end && (size_t) (end - ptr) >= sz; +} + +static bool +buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end, + int *retp) +{ + if (! buf_has_data (*ptrp, end, 4)) + return false; + + *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4); + return true; +} + +static bool +buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end, + uint64_t *retp) +{ + size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT); + if (! buf_has_data (*ptrp, end, sz)) + return false; + + union + { + uint64_t u64; + uint32_t u32; + } u; + + *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sizeof u); + + if (sz == 4) + *retp = u.u32; + else + *retp = u.u64; + return true; +} + +static void +handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos) +{ + Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE); + if (data == NULL) + error (EXIT_FAILURE, 0, + gettext ("cannot convert core note data: %s"), elf_errmsg (-1)); + + unsigned char const *ptr = data->d_buf; + unsigned char const *const end = data->d_buf + data->d_size; + + /* Siginfo head is three ints: signal number, error number, origin + code. */ + int si_signo, si_errno, si_code; + if (! buf_read_int (core, &ptr, end, &si_signo) + || ! buf_read_int (core, &ptr, end, &si_errno) + || ! buf_read_int (core, &ptr, end, &si_code)) + { + fail: + printf (" Not enough data in NT_SIGINFO note.\n"); + return; + } + + /* 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_signo) + { + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGBUS: + { + uint64_t addr; + if (! buf_read_ulong (core, &ptr, end, &addr)) + goto fail; + printf (" fault address: %#" PRIx64 "\n", addr); + break; + } + default: + ; + } + else if (si_code == SI_USER) + { + int pid, uid; + if (! buf_read_int (core, &ptr, end, &pid) + || ! buf_read_int (core, &ptr, end, &uid)) + goto fail; + printf (" sender PID: %d, sender UID: %d\n", pid, uid); + } +} + static void handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name, const void *desc) @@ -8689,6 +8788,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->elf, nhdr.n_descsz, + start + desc_offset); else handle_core_note (ebl, &nhdr, name, desc); } diff --git a/tests/ChangeLog b/tests/ChangeLog index 34cffd42..7e716616 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2013-09-26 Petr Machata <pmachata@redhat.com> + + * Makefile.am (EXTRA_DIST): Add testfile71.bz2. + * run-readelf-mixed-corenote.sh: New test for this file. + * testfile71.bz2: New file. + 2013-09-20 Mark Wielaard <mjw@redhat.com> * allfcts.c (cb): Return DWARF_CB_ABORT. diff --git a/tests/Makefile.am b/tests/Makefile.am index 58db6c36..0024395d 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 915bdebd..8823c3ed 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,61 @@ Note segment of 852 bytes at offset 0x94: high_r15: 0x00000000 EOF +# To reproduce this core dump, do this on x86_64 machine with Linux +# 3.7 or later: +# $ gcc -x c <(echo 'int main () { return *(int *)0x12345678; }') +# $ ./a.out +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 + fault address: 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 Binary files differnew file mode 100644 index 00000000..ce5b08fe --- /dev/null +++ b/tests/testfile71.bz2 |