summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKostik Belousov <kostik@sirion>2012-03-13 14:00:01 +0200
committerKostik Belousov <kostik@sirion>2012-03-13 14:00:01 +0200
commitdc9be1a97a7712b36533a9c362ecc3e6492fbc9b (patch)
tree0ea70177f7ddc888e3dbc3261044dd98db24bcf9 /src
parent1e6959a769fefbed6c9eb5d54d71cf5c02d962ed (diff)
downloadlibunwind-dc9be1a97a7712b36533a9c362ecc3e6492fbc9b.tar.gz
Implement register read for FreeBSD coredumps.
Rename _UCD_access_reg.c to _UCD_access_reg_linux.c, to have per-OS coredump register reader.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/coredump/_UCD_access_reg_freebsd.c118
-rw-r--r--src/coredump/_UCD_access_reg_linux.c (renamed from src/coredump/_UCD_access_reg.c)0
3 files changed, 120 insertions, 1 deletions
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
index 87156c9a..87156c9a 100644
--- a/src/coredump/_UCD_access_reg.c
+++ b/src/coredump/_UCD_access_reg_linux.c