File: x86_64.h

package info (click to toggle)
systemtap 2.6-0.2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 21,220 kB
  • ctags: 10,944
  • sloc: cpp: 53,239; ansic: 50,615; exp: 33,694; sh: 9,906; xml: 7,665; perl: 2,089; python: 1,534; tcl: 1,236; makefile: 797; java: 148; lisp: 104; awk: 94; asm: 91; sed: 16
file content (185 lines) | stat: -rw-r--r-- 5,443 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/* -*- linux-c -*-
 *
 * x86_64 dwarf unwinder header file
 * Copyright (C) 2008, 2010, 2011, 2014 Red Hat Inc.
 * Copyright (C) 2002-2006 Novell, Inc.
 * 
 * This file is part of systemtap, and is free software.  You can
 * redistribute it and/or modify it under the terms of the GNU General
 * Public License (GPL); either version 2, or (at your option) any
 * later version.
 */
#ifndef _STP_X86_64_UNWIND_H
#define _STP_X86_64_UNWIND_H

/*
 * Copyright (C) 2002-2006 Novell, Inc.
 *	Jan Beulich <jbeulich@novell.com>
 * This code is released under version 2 of the GNU GPL.
 */

#include <linux/sched.h>
#include <asm/ptrace.h>

/* these are simple for x86_64 */
#define _stp_get_unaligned(ptr) (*(ptr))

#ifdef STAPCONF_X86_UNIREGS
#define UNW_PC(frame)        (frame)->regs.ip
#define UNW_SP(frame)        (frame)->regs.sp
#else
#define UNW_PC(frame)        (frame)->regs.rip
#define UNW_SP(frame)        (frame)->regs.rsp
#endif /* STAPCONF_X86_UNIREGS */

/* Might need to account for the special exception and interrupt handling
   stacks here, since normally
	EXCEPTION_STACK_ORDER < THREAD_ORDER < IRQSTACK_ORDER,
   but the construct is needed only for getting across the stack switch to
   the interrupt stack - thus considering the IRQ stack itself is unnecessary,
   and the overhead of comparing against all exception handling stacks seems
   not desirable. */
#define STACK_LIMIT(ptr)     (((ptr) - 1) & ~(THREAD_SIZE - 1))

#ifdef STAPCONF_X86_UNIREGS
#define UNW_REGISTER_INFO \
	PTREGS_INFO(ax), \
	PTREGS_INFO(dx), \
	PTREGS_INFO(cx), \
	PTREGS_INFO(bx), \
	PTREGS_INFO(si), \
	PTREGS_INFO(di), \
	PTREGS_INFO(bp), \
	PTREGS_INFO(sp), \
	PTREGS_INFO(r8), \
	PTREGS_INFO(r9), \
	PTREGS_INFO(r10), \
	PTREGS_INFO(r11), \
	PTREGS_INFO(r12), \
	PTREGS_INFO(r13), \
	PTREGS_INFO(r14), \
	PTREGS_INFO(r15), \
	PTREGS_INFO(ip)	/* Note, placeholder for "fake" dwarf ret reg. */
#else
#define UNW_REGISTER_INFO \
	PTREGS_INFO(rax), \
	PTREGS_INFO(rdx), \
	PTREGS_INFO(rcx), \
	PTREGS_INFO(rbx), \
	PTREGS_INFO(rsi), \
	PTREGS_INFO(rdi), \
	PTREGS_INFO(rbp), \
	PTREGS_INFO(rsp), \
	PTREGS_INFO(r8), \
	PTREGS_INFO(r9), \
	PTREGS_INFO(r10), \
	PTREGS_INFO(r11), \
	PTREGS_INFO(r12), \
	PTREGS_INFO(r13), \
	PTREGS_INFO(r14), \
	PTREGS_INFO(r15), \
	PTREGS_INFO(rip) /* Note, placeholder for "fake" dwarf ret reg. */
#endif /* STAPCONF_X86_UNIREGS */

/* DWARF registers are ordered differently on 32-bit architectures*/
#define COMPAT_REG_MAP(r)					\
        ((r >= 9 && r <= 16) ? r /* r9 - r15  && ip/rip  */	\
         : (r == 0) ? r /* ax/rax */				\
         : (r == 1) ? 2 /* dx/rdx */				\
         : (r == 2) ? 1 /* cx/rcx */				\
         : (r == 3) ? r /* bx/rbx */				\
         : (r == 4) ? 7 /* sp/rsp */				\
         : (r == 5) ? 6 /* bp/rpp */				\
         : (r == 6) ? 4 /* si/rsi */				\
         : (r == 7) ? 5 /* di/rdi */				\
         : (r == 8) ? 16 /* ip/rip */				\
         : 9999)

#define UNW_PC_IDX 16
#define UNW_SP_IDX 7

#define UNW_NR_REAL_REGS 16
#define UNW_PC_FROM_RA 0 /* Because rip == return address column already. */

static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
                                            /*const*/ struct pt_regs *regs,
					    int sanitize)
{
        if(regs == NULL){
		/* 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
		      "=r" (info->regs.ip)
#else
		      "=r" (info->regs.rip)
#endif /* STAPCONF_X86_UNIREGS */
		    : "r" (&info->regs)
		    );
	        return;
        }

	if (&info->regs == regs) { /* happens when unwinding kernel->user */
		info->call_frame = 1;
		return;
	}

	memset(info, 0, sizeof(*info));
	if (sanitize) {
		info->regs.r11 = regs->r11;
		info->regs.r10 = regs->r10;
		info->regs.r9 = regs->r9;
		info->regs.r8 = regs->r8;
#ifdef STAPCONF_X86_UNIREGS
		info->regs.ax = regs->ax;
		info->regs.cx = regs->cx;
		info->regs.dx = regs->dx;
		info->regs.si = regs->si;
		info->regs.di = regs->di;
		info->regs.orig_ax = regs->orig_ax;
		info->regs.ip = regs->ip;
		info->regs.flags = regs->flags;
		info->regs.sp = regs->sp;
#else
		info->regs.rax = regs->rax;
		info->regs.rcx = regs->rcx;
		info->regs.rdx = regs->rdx;
		info->regs.rsi = regs->rsi;
		info->regs.rdi = regs->rdi;
		info->regs.orig_rax = regs->orig_rax;
		info->regs.rip = regs->rip;
		info->regs.eflags = regs->eflags;
		info->regs.rsp = regs->rsp;
#endif
		info->regs.cs = regs->cs;
		info->regs.ss = regs->ss;
	} else {
		info->regs = *regs;
	}
}

#endif /* _STP_X86_64_UNWIND_H */