]> sourceware.org Git - systemtap.git/commitdiff
runtime: Fix synthesized regs on ix86
authorJosh Stone <jistone@redhat.com>
Sat, 26 Apr 2014 00:12:18 +0000 (17:12 -0700)
committerJosh Stone <jistone@redhat.com>
Sat, 26 Apr 2014 00:28:43 +0000 (17:28 -0700)
The ix86 register names and offsets in the inline asm of
arch_unw_init_frame_info are now fixed, including stapconf to deal with
fs/xfs/gs changes over time.

x86_64 is updated to match the same style of access.

buildrun.cxx
runtime/linux/autoconf-x86-fs.c [new file with mode: 0644]
runtime/linux/autoconf-x86-xfs.c [new file with mode: 0644]
runtime/unwind/i386.h
runtime/unwind/x86_64.h

index 22a7fcaac2fbfdd2454c9fac7498830674607d91..a2f2197e4609738b5fa19fd8c96b79ad67973b26 100644 (file)
@@ -329,6 +329,8 @@ compile_pass (systemtap_session& s)
   output_dual_exportconf(s, o, "alloc_vm_area", "free_vm_area", "STAPCONF_VM_AREA");
   output_autoconf(s, o, "autoconf-procfs-owner.c", "STAPCONF_PROCFS_OWNER", NULL);
   output_autoconf(s, o, "autoconf-alloc-percpu-align.c", "STAPCONF_ALLOC_PERCPU_ALIGN", NULL);
+  output_autoconf(s, o, "autoconf-x86-fs.c", "STAPCONF_X86_FS", NULL);
+  output_autoconf(s, o, "autoconf-x86-xfs.c", "STAPCONF_X86_XFS", NULL);
   output_autoconf(s, o, "autoconf-x86-gs.c", "STAPCONF_X86_GS", NULL);
   output_autoconf(s, o, "autoconf-grsecurity.c", "STAPCONF_GRSECURITY", NULL);
   output_autoconf(s, o, "autoconf-trace-printk.c", "STAPCONF_TRACE_PRINTK", NULL);
diff --git a/runtime/linux/autoconf-x86-fs.c b/runtime/linux/autoconf-x86-fs.c
new file mode 100644 (file)
index 0000000..2d58760
--- /dev/null
@@ -0,0 +1,5 @@
+#include <asm/ptrace.h>
+
+#if defined (__i386__)
+struct pt_regs regs = {.fs = 0x0};
+#endif
diff --git a/runtime/linux/autoconf-x86-xfs.c b/runtime/linux/autoconf-x86-xfs.c
new file mode 100644 (file)
index 0000000..0b83ece
--- /dev/null
@@ -0,0 +1,5 @@
+#include <asm/ptrace.h>
+
+#if defined (__i386__)
+struct pt_regs regs = {.xfs = 0x0};
+#endif
index 4107d0e112c0cecaddd0364bee298e87ab1b5b6d..8d2a8e1a838d2cc6716ba777c5d063fa165d5b24 100644 (file)
 #define user_mode_vm(regs)  user_mode(regs)
 #endif
 
-
 static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
                                             /*const*/ struct pt_regs *regs,
                                            int sanitize)
 {
         if (!regs) {
-               asm("lea (%%eip), %1 \n\t"
-                   "mov %%ebx, 0%0 \n\t"
-                   "mov %%ecx, 8%0 \n\t"
-                   "mov %%edx, 16%0 \n\t"
-                   "mov %%esi, 24%0 \n\t"
-                   "mov %%edi, 32%0 \n\t"
-                   "mov %%ebp, 40%0 \n\t"
-                   "mov %%eax, 48%0 \n\t"
-                   "mov %%xds, 56%0 \n\t"
-                   "mov %%xes, 60%0 \n\t"
-                   "mov %%xfs, 64%0 \n\t"
-                   "mov %%xgs, 68%0 \n\t"
-                   "mov %%orig_eax, 72%0 \n\t"
-                   "mov %%xcs, 88%0 \n\t"
-                   "mov %%eflags, 92%0 \n\t"
-                   "mov %%esp, 100%0 \n\t"
-                   "mov %%xss, 108%0 \n\t"
+               /* NB: This uses an "=m" output constraint to indicate we're
+                * writing all of info->regs, but then uses an "r" input
+                * pointer for the actual writes.  This is to be sure we have
+                * something we can offset properly.
+                * NB2: kernel pt_regs haven't always included fs and gs, which
+                * means the offsets of the fields after have changed over
+                * time.  We'll reconvene at orig_eax to fill the end.  */
+               asm("movl $1f, %1; 1: \n\t"
+                   "mov %%ebx, 0(%2) \n\t"
+                   "mov %%ecx, 4(%2) \n\t"
+                   "mov %%edx, 8(%2) \n\t"
+                   "mov %%esi, 12(%2) \n\t"
+                   "mov %%edi, 16(%2) \n\t"
+                   "mov %%ebp, 20(%2) \n\t"
+                   "mov %%eax, 24(%2) \n\t"
+                   "mov %%ds, 28(%2) \n\t"
+                   "mov %%es, 32(%2) \n\t"
+#if defined(STAPCONF_X86_XFS) || defined (STAPCONF_X86_FS)
+                   "mov %%fs, 36(%2) \n\t"
+#endif
+#ifdef STAPCONF_X86_GS
+                   "mov %%gs, 40(%2) \n\t"
+#endif
+                   /* "mov %%orig_eax, 0(%3) \n\t" */
+                   /* "mov %%eip, 4(%3) \n\t" */
+                   "mov %%cs, 8(%3) \n\t"
+                   /* "mov %%eflags, 12(%3) \n\t" */
+                   "mov %%esp, 16(%3) \n\t"
+                   "mov %%ss, 20(%3) \n\t"
+                   : "=m" (info->regs),
 #ifdef STAPCONF_X86_UNIREGS
-                   : "=m"(info->regs), "=r" (info->regs.ip));
+                     "=m" (info->regs.ip)
 #else
-                   : "=m"(info->regs), "=r" (info->regs.eip));
+                     "=m" (info->regs.eip)
 #endif /* STAPCONF_X86_UNIREGS */
+                   : "r"(&info->regs),
+#ifdef STAPCONF_X86_UNIREGS
+                     "r" (&info->regs.orig_ax)
+#else
+                     "r" (&info->regs.orig_eax)
+#endif /* STAPCONF_X86_UNIREGS */
+                   );
+
                return;
        }
 
index cad18e0f6bf77614cfe6ed2cfe626d85b01a6bb0..c5a561880aeccc2831ad710046580dfbeb161d60 100644 (file)
@@ -106,29 +106,40 @@ static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
                                            int sanitize)
 {
         if(regs == NULL){
-               asm("lea (%%rip), %1 \n\t"
-                   "mov %%r15, 0%0 \n\t"
-                   "mov %%r14, 8%0 \n\t"
-                   "mov %%r13, 16%0 \n\t"
-                   "mov %%r12, 24%0 \n\t"
-                   "mov %%rbp, 32%0 \n\t"
-                   "mov %%rbx, 40%0 \n\t"
-                   "mov %%r11, 48%0 \n\t"
-                   "mov %%r10, 56%0 \n\t"
-                   "mov %%r9, 64%0 \n\t"
-                   "mov %%r8, 72%0 \n\t"
-                   "mov %%rax, 80%0 \n\t"
-                   "mov %%rcx, 88%0 \n\t"
-                   "mov %%rdx, 96%0 \n\t"
-                   "mov %%rsi, 104%0 \n\t"
-                   "mov %%rdi, 112%0 \n\t"
-                   "mov %%cs, 136%0 \n\t"
-                   "mov %%rsp, 152%0 \n\t"
+               /* NB: This uses an "=m" output constraint to indicate we're
+                * writing all of info->regs, but then uses an "r" input
+                * pointer for the actual writes.  This is to be sure we have
+                * something we can offset properly.  */
+               asm("lea (%%rip), %1 \n\t"
+                   "mov %%r15,   0(%2) \n\t"
+                   "mov %%r14,   8(%2) \n\t"
+                   "mov %%r13,  16(%2) \n\t"
+                   "mov %%r12,  24(%2) \n\t"
+                   "mov %%rbp,  32(%2) \n\t"
+                   "mov %%rbx,  40(%2) \n\t"
+                   "mov %%r11,  48(%2) \n\t"
+                   "mov %%r10,  56(%2) \n\t"
+                   "mov %%r9,   64(%2) \n\t"
+                   "mov %%r8,   72(%2) \n\t"
+                   "mov %%rax,  80(%2) \n\t"
+                   "mov %%rcx,  88(%2) \n\t"
+                   "mov %%rdx,  96(%2) \n\t"
+                   "mov %%rsi, 104(%2) \n\t"
+                   "mov %%rdi, 112(%2) \n\t"
+                   /* "mov %%orig_rax, 120(%2) \n\t" */
+                   /* "mov %%rip, 128(%2) \n\t" */
+                   "mov %%cs, 136(%2) \n\t"
+                   /* "mov %%eflags, 144(%2) \n\t" */
+                   "mov %%rsp, 152(%2) \n\t"
+                   "mov %%ss, 160(%2) \n\t"
+                   : "=m" (info->regs),
 #ifdef STAPCONF_X86_UNIREGS
-                   : "=m"(info->regs), "=r" (info->regs.ip));
+                     "=r" (info->regs.ip)
 #else
-                   : "=m"(info->regs), "=r" (info->regs.rip));
+                     "=r" (info->regs.rip)
 #endif /* STAPCONF_X86_UNIREGS */
+                   : "r" (&info->regs)
+                   );
                return;
         }
 
This page took 0.188209 seconds and 5 git commands to generate.