From dc9be1a97a7712b36533a9c362ecc3e6492fbc9b Mon Sep 17 00:00:00 2001 From: Kostik Belousov Date: Tue, 13 Mar 2012 14:00:01 +0200 Subject: [PATCH] Implement register read for FreeBSD coredumps. Rename _UCD_access_reg.c to _UCD_access_reg_linux.c, to have per-OS coredump register reader. --- src/Makefile.am | 3 +- src/coredump/_UCD_access_reg_freebsd.c | 118 ++++++++++++++++++ ...D_access_reg.c => _UCD_access_reg_linux.c} | 0 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/coredump/_UCD_access_reg_freebsd.c rename src/coredump/{_UCD_access_reg.c => _UCD_access_reg_linux.c} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 80642ff8..11c7b499 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,7 +31,6 @@ libunwind_coredump_a_SOURCES = \ coredump/_UCD_accessors.c \ coredump/_UCD_create.c \ coredump/_UCD_destroy.c \ - coredump/_UCD_access_reg.c \ coredump/_UCD_access_mem.c \ coredump/_UCD_elf_map_image.c \ coredump/_UCD_find_proc_info.c \ @@ -366,6 +365,7 @@ if OS_LINUX libunwind_la_SOURCES_x86_os_local = x86/Los-linux.c libunwind_la_SOURCES_x86_64_os = x86_64/Gos-linux.c libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c + libunwind_coredump_a_SOURCES += coredump/_UCD_access_reg_linux.c endif if OS_HPUX @@ -381,6 +381,7 @@ if OS_FREEBSD libunwind_la_SOURCES_x86_os_local = x86/Los-freebsd.c libunwind_la_SOURCES_x86_64_os = x86_64/Gos-freebsd.c libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-freebsd.c + libunwind_coredump_a_SOURCES += coredump/_UCD_access_reg_freebsd.c endif if ARCH_ARM diff --git a/src/coredump/_UCD_access_reg_freebsd.c b/src/coredump/_UCD_access_reg_freebsd.c new file mode 100644 index 00000000..d5b4e74f --- /dev/null +++ b/src/coredump/_UCD_access_reg_freebsd.c @@ -0,0 +1,118 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" + +#include "_UCD_internal.h" + +int +_UCD_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, unw_word_t *valp, + int write, void *arg) +{ + if (write) + { + Debug(0, "%s: write is not supported\n", __func__); + return -UNW_EINVAL; + } + + struct UCD_info *ui = arg; + +#if defined(UNW_TARGET_X86) + switch (regnum) { + case UNW_X86_EAX: + *valp = ui->prstatus->pr_reg.r_eax; + break; + case UNW_X86_EDX: + *valp = ui->prstatus->pr_reg.r_edx; + break; + case UNW_X86_ECX: + *valp = ui->prstatus->pr_reg.r_ecx; + break; + case UNW_X86_EBX: + *valp = ui->prstatus->pr_reg.r_ebx; + break; + case UNW_X86_ESI: + *valp = ui->prstatus->pr_reg.r_esi; + break; + case UNW_X86_EDI: + *valp = ui->prstatus->pr_reg.r_edi; + break; + case UNW_X86_EBP: + *valp = ui->prstatus->pr_reg.r_ebp; + break; + case UNW_X86_ESP: + *valp = ui->prstatus->pr_reg.r_esp; + break; + case UNW_X86_EIP: + *valp = ui->prstatus->pr_reg.r_eip; + break; + case UNW_X86_EFLAGS: + *valp = ui->prstatus->pr_reg.r_eflags; + break; + case UNW_X86_TRAPNO: + *valp = ui->prstatus->pr_reg.r_trapno; + break; + default: + Debug(0, "%s: bad regnum:%d\n", __func__, regnum); + return -UNW_EINVAL; + }; +#elif defined(UNW_TARGET_X86_64) + switch (regnum) { + case UNW_X86_64_RAX: + *valp = ui->prstatus->pr_reg.r_rax; + break; + case UNW_X86_64_RDX: + *valp = ui->prstatus->pr_reg.r_rdx; + break; + case UNW_X86_64_RCX: + *valp = ui->prstatus->pr_reg.r_rcx; + break; + case UNW_X86_64_RBX: + *valp = ui->prstatus->pr_reg.r_rbx; + break; + case UNW_X86_64_RSI: + *valp = ui->prstatus->pr_reg.r_rsi; + break; + case UNW_X86_64_RDI: + *valp = ui->prstatus->pr_reg.r_rdi; + break; + case UNW_X86_64_RBP: + *valp = ui->prstatus->pr_reg.r_rbp; + break; + case UNW_X86_64_RSP: + *valp = ui->prstatus->pr_reg.r_rsp; + break; + case UNW_X86_64_RIP: + *valp = ui->prstatus->pr_reg.r_rip; + break; + default: + Debug(0, "%s: bad regnum:%d\n", __func__, regnum); + return -UNW_EINVAL; + }; +#else +#error Port me +#endif + + return 0; +} diff --git a/src/coredump/_UCD_access_reg.c b/src/coredump/_UCD_access_reg_linux.c similarity index 100% rename from src/coredump/_UCD_access_reg.c rename to src/coredump/_UCD_access_reg_linux.c