This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: [patch v6 2/5] x86* unwinder: backends/
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Fri, 18 Oct 2013 18:48:54 +0200
- Subject: Re: [patch v6 2/5] x86* unwinder: backends/
On Thu, 17 Oct 2013 15:02:41 +0200, Mark Wielaard wrote:
> > --- a/backends/i386_init.c
> > +++ b/backends/i386_init.c
> > + /* gcc/config/ #define DWARF_FRAME_REGISTERS. For i386 it is 17, why? */
> > + eh->frame_nregs = 9;
> > + HOOK (eh, set_initial_registers_tid);
>
> 9 looks like the right number.
> Did you figure out why gcc defines it differently?
> It looks like confusing with the full x86_64 register, which obviously
> has 8 more general purpose registers, that aren't available to i386
> processes.
I do not know the exact reason. Currently this #define is shared with x86_64
but I do not see why 32-bit i386 does not have it separate and different.
Also IIRC MS-Windows i386 ABI has more CFI saved registers but I am not sure.
> > +++ b/backends/i386_initreg.c
> > @@ -0,0 +1,80 @@
> > +/* Fetch process data from STATE->base->pid or STATE->base->core.
>
> Comment doesn't really describe what the file does.
Used:
/* Fetch live process registers from TID.
> > +# else /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
> > +# error
>
> Please make that error say something:
> #error Impossible, unreachable, arch should be i386 or x86_64.
# error "source file error, it cannot happen"
That line really cannot happen from external defines, it can happen only as
a bug of backends/i386_initreg.c .
> > +# endif /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
> > + return setfunc (0, 9, dwarf_regs, arg);
> > +#endif /* __i386__ || __x86_64__ */
> > + return true;
> > +}
>
> That last return statement also isn't reachable (there is a return false
> at the top, if that isn't reached then the return setfunc will be
> reached. So that should be either return false, an unreachable assert or
> just left out.
left out now.
> > +++ b/backends/x86_64_initreg.c
> > @@ -0,0 +1,73 @@
> > +/* Fetch live process Dwfl_Frame from PID.
>
> It isn't using Dwfl_Frame anymore.
Used:
/* Fetch live process registers from TID.
Thanks,
Jan
backends/
2013-10-18 Jan Kratochvil <jan.kratochvil@redhat.com>
Mark Wielaard <mjw@redhat.com>
* Makefile.am (i386_SRCS): Add i386_initreg.c.
(x86_64_SRCS): Add x86_64_initreg.c.
* i386_initreg.c: New file.
* i386_init.c (i386_init): Initialize frame_nregs and
set_initial_registers_tid.
* x86_64_initreg.c: New file.
* x86_64_init.c (x86_64_init): Initialize frame_nregs and
set_initial_registers_tid.
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 557ed87..5b5e067 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -50,7 +50,8 @@ libdw = ../libdw/libdw.so
endif
i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
- i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c
+ i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c \
+ i386_initreg.c
cpu_i386 = ../libcpu/libcpu_i386.a
libebl_i386_pic_a_SOURCES = $(i386_SRCS)
am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
@@ -60,7 +61,8 @@ libebl_sh_pic_a_SOURCES = $(sh_SRCS)
am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \
- x86_64_retval.c x86_64_regs.c i386_auxv.c x86_64_syscall.c
+ x86_64_retval.c x86_64_regs.c i386_auxv.c x86_64_syscall.c \
+ x86_64_initreg.c
cpu_x86_64 = ../libcpu/libcpu_x86_64.a
libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
diff --git a/backends/i386_init.c b/backends/i386_init.c
index cc9b2d7..1e0b486 100644
--- a/backends/i386_init.c
+++ b/backends/i386_init.c
@@ -1,5 +1,5 @@
/* Initialization of i386 specific backend library.
- Copyright (C) 2000-2009 Red Hat, Inc.
+ Copyright (C) 2000-2009, 2013 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
@@ -63,6 +63,9 @@ i386_init (elf, machine, eh, ehlen)
HOOK (eh, auxv_info);
HOOK (eh, disasm);
HOOK (eh, abi_cfi);
+ /* gcc/config/ #define DWARF_FRAME_REGISTERS. For i386 it is 17, why? */
+ eh->frame_nregs = 9;
+ HOOK (eh, set_initial_registers_tid);
return MODVERSION;
}
diff --git a/backends/i386_initreg.c b/backends/i386_initreg.c
new file mode 100644
index 0000000..7e5907e
--- /dev/null
+++ b/backends/i386_initreg.c
@@ -0,0 +1,79 @@
+/* Fetch live process registers from TID.
+ Copyright (C) 2013 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined __i386__ || defined __x86_64__
+# include <sys/types.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+bool
+i386_set_initial_registers_tid (pid_t tid,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
+{
+#if !defined __i386__ && !defined __x86_64__
+ return false;
+#else /* __i386__ || __x86_64__ */
+ struct user_regs_struct user_regs;
+ if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
+ return false;
+ Dwarf_Word dwarf_regs[9];
+# if defined __i386__
+ dwarf_regs[0] = user_regs.eax;
+ dwarf_regs[1] = user_regs.ecx;
+ dwarf_regs[2] = user_regs.edx;
+ dwarf_regs[3] = user_regs.ebx;
+ dwarf_regs[4] = user_regs.esp;
+ dwarf_regs[5] = user_regs.ebp;
+ dwarf_regs[6] = user_regs.esi;
+ dwarf_regs[7] = user_regs.edi;
+ dwarf_regs[8] = user_regs.eip;
+# elif defined __x86_64__
+ dwarf_regs[0] = user_regs.rax;
+ dwarf_regs[1] = user_regs.rcx;
+ dwarf_regs[2] = user_regs.rdx;
+ dwarf_regs[3] = user_regs.rbx;
+ dwarf_regs[4] = user_regs.rsp;
+ dwarf_regs[5] = user_regs.rbp;
+ dwarf_regs[6] = user_regs.rsi;
+ dwarf_regs[7] = user_regs.rdi;
+ dwarf_regs[8] = user_regs.rip;
+# else /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
+# error "source file error, it cannot happen"
+# endif /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
+ return setfunc (0, 9, dwarf_regs, arg);
+#endif /* __i386__ || __x86_64__ */
+}
diff --git a/backends/x86_64_init.c b/backends/x86_64_init.c
index 67a5880..b885558 100644
--- a/backends/x86_64_init.c
+++ b/backends/x86_64_init.c
@@ -1,5 +1,5 @@
/* Initialization of x86-64 specific backend library.
- Copyright (C) 2002-2009 Red Hat, Inc.
+ Copyright (C) 2002-2009, 2013 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -60,6 +60,9 @@ x86_64_init (elf, machine, eh, ehlen)
HOOK (eh, auxv_info);
HOOK (eh, disasm);
HOOK (eh, abi_cfi);
+ /* gcc/config/ #define DWARF_FRAME_REGISTERS. */
+ eh->frame_nregs = 17;
+ HOOK (eh, set_initial_registers_tid);
return MODVERSION;
}
diff --git a/backends/x86_64_initreg.c b/backends/x86_64_initreg.c
new file mode 100644
index 0000000..754b320
--- /dev/null
+++ b/backends/x86_64_initreg.c
@@ -0,0 +1,73 @@
+/* Fetch live process registers from TID.
+ Copyright (C) 2013 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#ifdef __x86_64__
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+bool
+x86_64_set_initial_registers_tid (pid_t tid,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
+{
+#ifndef __x86_64__
+ return false;
+#else /* __x86_64__ */
+ struct user_regs_struct user_regs;
+ if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
+ return false;
+ Dwarf_Word dwarf_regs[17];
+ dwarf_regs[0] = user_regs.rax;
+ dwarf_regs[1] = user_regs.rdx;
+ dwarf_regs[2] = user_regs.rcx;
+ dwarf_regs[3] = user_regs.rbx;
+ dwarf_regs[4] = user_regs.rsi;
+ dwarf_regs[5] = user_regs.rdi;
+ dwarf_regs[6] = user_regs.rbp;
+ dwarf_regs[7] = user_regs.rsp;
+ dwarf_regs[8] = user_regs.r8;
+ dwarf_regs[9] = user_regs.r9;
+ dwarf_regs[10] = user_regs.r10;
+ dwarf_regs[11] = user_regs.r11;
+ dwarf_regs[12] = user_regs.r12;
+ dwarf_regs[13] = user_regs.r13;
+ dwarf_regs[14] = user_regs.r14;
+ dwarf_regs[15] = user_regs.r15;
+ dwarf_regs[16] = user_regs.rip;
+ return setfunc (0, 17, dwarf_regs, arg);
+#endif /* __x86_64__ */
+}