]> sourceware.org Git - systemtap.git/blame - tapset/arm/registers.stp
PR10299: Basic documentation for the changes to embedded-C argument access.
[systemtap.git] / tapset / arm / registers.stp
CommitLineData
5a24160a
WC
1/* Dwarfless register access for arm */
2
3global _reg_offsets, _stp_regs_registered
4
5function _stp_register_regs() {
6
7 /* Same order as pt_regs */
8 _reg_offsets["r0"] = 0 _reg_offsets["a1"] = 0
9 _reg_offsets["r1"] = 4 _reg_offsets["a2"] = 4
10 _reg_offsets["r2"] = 8 _reg_offsets["a3"] = 8
11 _reg_offsets["r3"] = 12 _reg_offsets["a4"] = 12
12 _reg_offsets["r4"] = 16 _reg_offsets["v1"] = 16
13 _reg_offsets["r5"] = 20 _reg_offsets["v2"] = 20
14 _reg_offsets["r6"] = 24 _reg_offsets["v3"] = 24
15 _reg_offsets["r7"] = 28 _reg_offsets["v4"] = 28
16 _reg_offsets["r8"] = 32 _reg_offsets["v5"] = 32
17 _reg_offsets["r9"] = 36 _reg_offsets["v6"] = 36
18 _reg_offsets["r10"] = 40 _reg_offsets["v7"] = 40
19 _reg_offsets["fp"] = 44 _reg_offsets["v8"] = 44
20 _reg_offsets["ip"] = 48
21 _reg_offsets["sp"] = 52
22 _reg_offsets["lr"] = 56
23 _reg_offsets["pc"] = 60
24 _reg_offsets["cpsr"] = 64
25 _reg_offsets["orig_r0"] = 68
26
27 _stp_regs_registered = 1
28}
29
30function _stp_get_register_by_offset:long (offset:long) %{ /* pure */
31 long value;
d9aed31e 32 struct pt_regs *regs;
f52d32a9 33 if (CONTEXT->probe_flags & _STP_PROBE_STATE_USER_MODE) {
d9aed31e 34 regs = CONTEXT->uregs;
6c40239d
MW
35 } else {
36 regs = CONTEXT->kregs;
d9aed31e
MW
37 }
38 if (!regs) {
5a24160a
WC
39 CONTEXT->last_error = "No registers available in this context";
40 return;
41 }
42 if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(long)) {
43 snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
44 "Bad register offset: %lld", THIS->offset);
45 CONTEXT->last_error = CONTEXT->error_buffer;
46 return;
47 }
d9aed31e 48 memcpy(&value, ((char *)regs) + THIS->offset, sizeof(value));
5a24160a
WC
49 THIS->__retvalue = value;
50%}
51
92c25572
MW
52function _stp_probing_kernel:long () {
53 return !user_mode();
54}
5a24160a
WC
55
56/* Return the named register value as a signed value. */
57function register:long (name:string) {
58 if (!registers_valid()) {
59 error("cannot access CPU registers in this context")
60 return 0
61 }
62 if (!_stp_regs_registered)
63 _stp_register_regs()
64 offset = _reg_offsets[name]
65 if (offset == 0 && !(name in _reg_offsets)) {
66 error("Unknown register: " . name)
67 return 0
68 }
69 return _stp_get_register_by_offset(offset)
70}
71
72/*
73 * Return the named register value as an unsigned value. Specifically,
74 * don't sign-extend the register value when promoting it to 64 bits.
75 */
76function u_register:long (name:string) {
77 return register(name) & 0xffffffff;
78}
79
80/* Return the value of function arg #argnum (1=first arg) as a signed value.
81 *
82 * We don't yet support extracting arg #5 and beyond, which are passed
83 * on stack
84 */
85function _stp_arg:long (argnum:long) {
86 val = 0
87 if (argnum < 1 || argnum > 4) {
88 error(sprintf("Cannot access arg(%d)", argnum))
89 return 0
90 }
91
92 if (argnum == 1)
f52d32a9 93 val = register("r0")
5a24160a 94 else if (argnum == 2)
f52d32a9 95 val = register("r1")
5a24160a 96 else if (argnum == 3)
f52d32a9 97 val = register("r2")
5a24160a 98 else if (argnum == 4)
f52d32a9 99 val = register("r3")
5a24160a
WC
100
101 return val;
102}
103
104/* Return the value of function arg #argnum as a signed int. */
105function int_arg:long (argnum:long) {
106 return _stp_arg(argnum)
107}
108
109/* Return the value of function arg #argnum as an unsigned int. */
110function uint_arg:long (argnum:long) {
111 return _stp_arg(argnum) & 0xffffffff;
112}
113
114function long_arg:long (argnum:long) {
115 return int_arg(argnum)
116}
117
118function ulong_arg:long (argnum:long) {
119 return uint_arg(argnum)
120}
121
122function longlong_arg:long (argnum:long) {
123 /*
124 * TODO: If argnum == nr_regarg, gcc puts the whole 64-bit arg
125 * on the stack.
126 */
127 lowbits = uint_arg(argnum)
128 highbits = uint_arg(argnum+1)
129 return ((highbits << 32) | lowbits)
130}
131
132function ulonglong_arg:long (argnum:long) {
133 return longlong_arg(argnum)
134}
135
136function pointer_arg:long (argnum:long) {
137 return ulong_arg(argnum)
138}
139
140function s32_arg:long (argnum:long) {
141 return int_arg(argnum)
142}
143
144function u32_arg:long (argnum:long) {
145 return uint_arg(argnum)
146}
147
148function s64_arg:long (argnum:long) {
149 return longlong_arg(argnum)
150}
151
152function u64_arg:long (argnum:long) {
153 return ulonglong_arg(argnum)
154}
155
156function asmlinkage() %{ /* pure */ %}
157
158function fastcall() %{ /* pure */ %}
159
309d67d8 160function regparm(n:long) %{
5a24160a
WC
161 snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
162 "regparm is invalid on arm.");
163 CONTEXT->last_error = CONTEXT->error_buffer;
164%}
This page took 0.050466 seconds and 5 git commands to generate.