lkml.org 
[lkml]   [2003]   [Apr]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: unwinding for vsyscall code
Richard Henderson wrote:

> So you also need a
>
> 0x85 0x04 DW_CFA_offset %ebp -16
> [...]

Updated patch attached.

--
--------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat `--' drepper at redhat.com `---------------------------
--- linux-2.5/arch/i386/kernel/sysenter.c-eh 2003-04-13 15:32:51.000000000 -0700
+++ linux-2.5/arch/i386/kernel/sysenter.c 2003-04-13 15:30:22.000000000 -0700
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/gfp.h>
#include <linux/string.h>
+#include <linux/elf.h>

#include <asm/cpufeature.h>
#include <asm/msr.h>
@@ -52,11 +53,47 @@ void enable_sep_cpu(void *info)

static int __init sysenter_setup(void)
{
- static const char int80[] = {
+ static const char __initdata int80[] = {
0xcd, 0x80, /* int $0x80 */
0xc3 /* ret */
};
- static const char sysent[] = {
+ /* Unwind information for the int80 code. Keep track of
+ where the return address is stored. */
+ static const char __initdata int80_eh_frame[] = {
+ /* First the Common Information Entry (CIE): */
+ 0x14, 0x00, 0x00, 0x00, /* Length of the CIE */
+ 0x00, 0x00, 0x00, 0x00, /* CIE Identifier Tag */
+ 0x01, /* CIE Version */
+ 'z', 'R', 0x00, /* CIE Augmentation */
+ 0x01, /* CIE Code Alignment Factor */
+ 0x7c, /* CIE Data Alignment Factor */
+ 0x08, /* CIE RA Column */
+ 0x01, /* Augmentation size */
+ 0x1b, /* FDE Encoding (pcrel sdata4) */
+ 0x0c, /* DW_CFA_def_cfa */
+ 0x04,
+ 0x04,
+ 0x88, /* DW_CFA_offset, column 0x8 */
+ 0x01,
+ 0x00, /* padding */
+ 0x00,
+ /* Now the FDE which contains the instructions for the frame. */
+ 0x0a, 0x00, 0x00, 0x00, /* FDE Length */
+ 0x1c, 0x00, 0x00, 0x00, /* FDE CIE offset */
+ /* The PC-relative offset to the beginning of the code this
+ FDE covers. The computation below assumes that the offset
+ can be represented in one byte. Change if this is not true
+ anymore. The offset from the beginning of the .eh_frame
+ is represented by EH_FRAME_OFFSET. The word with the offset
+ starts at byte 0x20 of the .eh_frame. */
+ 0x100 - (EH_FRAME_OFFSET + 0x20),
+ 0xff, 0xff, 0xff, /* FDE initial location */
+ 3, /* FDE address range */
+ 0x00 /* Augmentation size */
+ /* The code does not change the stack pointer. We need not
+ record any operations. */
+ };
+ static const char __initdata sysent[] = {
0x51, /* push %ecx */
0x52, /* push %edx */
0x55, /* push %ebp */
@@ -76,13 +113,71 @@ static int __init sysenter_setup(void)
0x59, /* pop %ecx */
0xc3 /* ret */
};
- static const char sigreturn[] = {
+ /* Unwind information for the sysenter code. Keep track of
+ where the return address is stored. */
+ static const char __initdata sysent_eh_frame[] = {
+ /* First the Common Information Entry (CIE): */
+ 0x14, 0x00, 0x00, 0x00, /* Length of the CIE */
+ 0x00, 0x00, 0x00, 0x00, /* CIE Identifier Tag */
+ 0x01, /* CIE Version */
+ 'z', 'R', 0x00, /* CIE Augmentation */
+ 0x01, /* CIE Code Alignment Factor */
+ 0x7c, /* CIE Data Alignment Factor */
+ 0x08, /* CIE RA Column */
+ 0x01, /* Augmentation size */
+ 0x1b, /* FDE Encoding (pcrel sdata4) */
+ 0x0c, /* DW_CFA_def_cfa */
+ 0x04,
+ 0x04,
+ 0x88, /* DW_CFA_offset, column 0x8 */
+ 0x01,
+ 0x00, /* padding */
+ 0x00,
+ /* Now the FDE which contains the instructions for the frame. */
+ 0x22, 0x00, 0x00, 0x00, /* FDE Length */
+ 0x1c, 0x00, 0x00, 0x00, /* FDE CIE offset */
+ /* The PC-relative offset to the beginning of the code this
+ FDE covers. The computation below assumes that the offset
+ can be represented in one byte. Change if this is not true
+ anymore. The offset from the beginning of the .eh_frame
+ is represented by EH_FRAME_OFFSET. The word with the offset
+ starts at byte 0x20 of the .eh_frame. */
+ 0x100 - (EH_FRAME_OFFSET + 0x20),
+ 0xff, 0xff, 0xff, /* FDE initial location */
+ 0x14, 0x00, 0x00, 0x00, /* FDE address range */
+ 0x00, /* Augmentation size */
+ /* What follows are the instructions for the table generation.
+ We have to record all changes of the stack pointer and
+ callee-saved registers. */
+ 0x41, /* DW_CFA_advance_loc+1, push %ecx */
+ 0x0e, /* DW_CFA_def_cfa_offset */
+ 0x08, /* RA at offset 8 now */
+ 0x41, /* DW_CFA_advance_loc+1, push %edx */
+ 0x0e, /* DW_CFA_def_cfa_offset */
+ 0x0c, /* RA at offset 12 now */
+ 0x41, /* DW_CFA_advance_loc+1, push %ebp */
+ 0x0e, /* DW_CFA_def_cfa_offset */
+ 0x10, /* RA at offset 16 now */
+ 0x85, 0x04, /* DW_CFA_offset %ebp -16 */
+ /* Finally the epilogue. */
+ 0x4e, /* DW_CFA_advance_loc+14, pop %ebx */
+ 0x0e, /* DW_CFA_def_cfa_offset */
+ 0x12, /* RA at offset 12 now */
+ 0xc5, /* DW_CFA_restore %ebp */
+ 0x41, /* DW_CFA_advance_loc+1, pop %edx */
+ 0x0e, /* DW_CFA_def_cfa_offset */
+ 0x08, /* RA at offset 8 now */
+ 0x41, /* DW_CFA_advance_loc+1, pop %ecx */
+ 0x0e, /* DW_CFA_def_cfa_offset */
+ 0x04 /* RA at offset 4 now */
+ };
+ static const char __initdata sigreturn[] = {
/* 32: sigreturn point */
0x58, /* popl %eax */
0xb8, __NR_sigreturn, 0, 0, 0, /* movl $__NR_sigreturn, %eax */
0xcd, 0x80, /* int $0x80 */
};
- static const char rt_sigreturn[] = {
+ static const char __initdata rt_sigreturn[] = {
/* 64: rt_sigreturn point */
0xb8, __NR_rt_sigreturn, 0, 0, 0, /* movl $__NR_rt_sigreturn, %eax */
0xcd, 0x80, /* int $0x80 */
@@ -93,10 +188,14 @@ static int __init sysenter_setup(void)
memcpy((void *) page, int80, sizeof(int80));
memcpy((void *)(page + 32), sigreturn, sizeof(sigreturn));
memcpy((void *)(page + 64), rt_sigreturn, sizeof(rt_sigreturn));
+ memcpy((void *)(page + EH_FRAME_OFFSET), int80_eh_frame,
+ sizeof(int80_eh_frame));
if (!boot_cpu_has(X86_FEATURE_SEP))
return 0;

memcpy((void *) page, sysent, sizeof(sysent));
+ memcpy((void *)(page + EH_FRAME_OFFSET), sysent_eh_frame,
+ sizeof(sysent_eh_frame));
on_each_cpu(enable_sep_cpu, NULL, 1, 1);
return 0;
}
--- linux-2.5/include/asm-i386/elf.h-eh 2003-04-13 15:31:35.000000000 -0700
+++ linux-2.5/include/asm-i386/elf.h 2003-04-13 14:47:04.000000000 -0700
@@ -100,7 +100,8 @@ typedef struct user_fxsr_struct elf_fpxr
* Architecture-neutral AT_ values in 0-17, leave some room
* for more of them, start the x86-specific ones at 32.
*/
-#define AT_SYSINFO 32
+#define AT_SYSINFO 32
+#define AT_SYSINFO_EH_FRAME 33

#ifdef __KERNEL__
#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
@@ -118,9 +119,15 @@ extern void dump_smp_unlazy_fpu(void);
#define ELF_CORE_SYNC dump_smp_unlazy_fpu
#endif

-#define ARCH_DLINFO \
-do { \
- NEW_AUX_ENT(AT_SYSINFO, 0xffffe000); \
+/* Offset from the beginning of the page where the .eh_frame information
+ for the code in the vsyscall page starts. */
+#define EH_FRAME_OFFSET 96
+
+#define ARCH_DLINFO \
+do { \
+ NEW_AUX_ENT(AT_SYSINFO, 0xffffe000); \
+ NEW_AUX_ENT(AT_SYSINFO_EH_FRAME, \
+ 0xffffe000 + EH_FRAME_OFFSET); \
} while (0)

#endif[unhandled content-type:application/pgp-signature]
\
 
 \ /
  Last update: 2005-03-22 13:34    [W:1.098 / U:0.008 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site