Mon May 22 15:12:54 2023 UTC ()
dtrace_fbt: Read and write instructions appropriately-endian on arm.

arm is a little more complicated because it has three cases:
- big-endian data, big-endian instructions
- big-endian data, little-endian instructions
- little-endian data, little-endian instructions


(riastradh)
diff -r1.1 -r1.2 src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c

cvs diff -r1.1 -r1.2 src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c (expand / switch to unified diff)

--- src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c 2018/05/28 23:47:39 1.1
+++ src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c 2023/05/22 15:12:54 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: fbt_isa.c,v 1.1 2018/05/28 23:47:39 chs Exp $ */ 1/* $NetBSD: fbt_isa.c,v 1.2 2023/05/22 15:12:54 riastradh Exp $ */
2 2
3/* 3/*
4 * CDDL HEADER START 4 * CDDL HEADER START
5 * 5 *
6 * The contents of this file are subject to the terms of the 6 * The contents of this file are subject to the terms of the
7 * Common Development and Distribution License (the "License"). 7 * Common Development and Distribution License (the "License").
8 * You may not use this file except in compliance with the License. 8 * You may not use this file except in compliance with the License.
9 * 9 *
10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 * or http://www.opensolaris.org/os/licensing. 11 * or http://www.opensolaris.org/os/licensing.
12 * See the License for the specific language governing permissions 12 * See the License for the specific language governing permissions
13 * and limitations under the License. 13 * and limitations under the License.
14 * 14 *
@@ -46,26 +46,46 @@ @@ -46,26 +46,46 @@
46#include <arm/frame.h> 46#include <arm/frame.h>
47#include <uvm/uvm_extern.h> 47#include <uvm/uvm_extern.h>
48 48
49#include "fbt.h" 49#include "fbt.h"
50 50
51#define FBT_PUSHM 0xe92d0000 51#define FBT_PUSHM 0xe92d0000
52#define FBT_POPM 0xe8bd0000 52#define FBT_POPM 0xe8bd0000
53#define FBT_JUMP 0xea000000 53#define FBT_JUMP 0xea000000
54#define FBT_SUBSP 0xe24dd000 54#define FBT_SUBSP 0xe24dd000
55 55
56#define FBT_ENTRY "entry" 56#define FBT_ENTRY "entry"
57#define FBT_RETURN "return" 57#define FBT_RETURN "return"
58 58
 59static uint32_t
 60ldinstr(const uint32_t *instr)
 61{
 62#ifdef _ARM_ARCH_BE8 /* big-endian data, big-endian instructions */
 63 return *instr;
 64#else /* little-endian instructions */
 65 return le32toh(*instr);
 66#endif
 67}
 68
 69static void
 70stinstr(uint32_t *instr, uint32_t val)
 71{
 72
 73#ifdef _ARM_ARCH_BE8 /* big-endian data, big-endian instructions */
 74 val = bswap32(val);
 75#endif
 76 ktext_write(instr, &val, sizeof(val)); /* write little-endian */
 77}
 78
59int 79int
60fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) 80fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
61{ 81{
62 solaris_cpu_t *cpu = &solaris_cpu[cpu_number()]; 82 solaris_cpu_t *cpu = &solaris_cpu[cpu_number()];
63 fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; 83 fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)];
64 register_t fifthparam; 84 register_t fifthparam;
65 85
66 for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { 86 for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
67 if ((uintptr_t)fbt->fbtp_patchpoint == addr) { 87 if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
68 if (fbt->fbtp_roffset == 0) { 88 if (fbt->fbtp_roffset == 0) {
69 /* Get 5th parameter from stack */ 89 /* Get 5th parameter from stack */
70 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); 90 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
71 fifthparam = *(register_t *)frame->tf_svc_sp; 91 fifthparam = *(register_t *)frame->tf_svc_sp;
@@ -88,93 +108,91 @@ fbt_invop(uintptr_t addr, struct trapfra @@ -88,93 +108,91 @@ fbt_invop(uintptr_t addr, struct trapfra
88 } 108 }
89 } 109 }
90 110
91 return (0); 111 return (0);
92} 112}
93 113
94 114
95void 115void
96fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val) 116fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val)
97{ 117{
98 dtrace_icookie_t c; 118 dtrace_icookie_t c;
99 119
100 c = dtrace_interrupt_disable(); 120 c = dtrace_interrupt_disable();
101 121 stinstr(fbt->fbtp_patchpoint, val);
102 ktext_write(fbt->fbtp_patchpoint, &val, sizeof (val)); 
103 
104 dtrace_interrupt_enable(c); 122 dtrace_interrupt_enable(c);
105} 123}
106 124
107#ifdef __FreeBSD__ 125#ifdef __FreeBSD__
108 126
109int 127int
110fbt_provide_module_function(linker_file_t lf, int symindx, 128fbt_provide_module_function(linker_file_t lf, int symindx,
111 linker_symval_t *symval, void *opaque) 129 linker_symval_t *symval, void *opaque)
112{ 130{
113 char *modname = opaque; 131 char *modname = opaque;
114 const char *name = symval->name; 132 const char *name = symval->name;
115 fbt_probe_t *fbt, *retfbt; 133 fbt_probe_t *fbt, *retfbt;
116 uint32_t *instr, *limit; 134 uint32_t *instr, *limit;
117 int popm; 135 int popm;
118 136
119 if (fbt_excluded(name)) 137 if (fbt_excluded(name))
120 return (0); 138 return (0);
121 139
122 instr = (uint32_t *)symval->value; 140 instr = (uint32_t *)symval->value;
123 limit = (uint32_t *)(symval->value + symval->size); 141 limit = (uint32_t *)(symval->value + symval->size);
124 142
125 /* 143 /*
126 * va_arg functions has first instruction of 144 * va_arg functions has first instruction of
127 * sub sp, sp, #? 145 * sub sp, sp, #?
128 */ 146 */
129 if ((*instr & 0xfffff000) == FBT_SUBSP) 147 if ((ldinstr(instr) & 0xfffff000) == FBT_SUBSP)
130 instr++; 148 instr++;
131 149
132 /* 150 /*
133 * check if insn is a pushm with LR 151 * check if insn is a pushm with LR
134 */ 152 */
135 if ((*instr & 0xffff0000) != FBT_PUSHM || 153 if ((ldinstr(instr) & 0xffff0000) != FBT_PUSHM ||
136 (*instr & (1 << LR)) == 0) 154 (ldinstr(instr) & (1 << LR)) == 0)
137 return (0); 155 return (0);
138 156
139 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); 157 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
140 fbt->fbtp_name = name; 158 fbt->fbtp_name = name;
141 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 159 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
142 name, FBT_ENTRY, 5, fbt); 160 name, FBT_ENTRY, 5, fbt);
143 fbt->fbtp_patchpoint = instr; 161 fbt->fbtp_patchpoint = instr;
144 fbt->fbtp_ctl = lf; 162 fbt->fbtp_ctl = lf;
145 fbt->fbtp_loadcnt = lf->loadcnt; 163 fbt->fbtp_loadcnt = lf->loadcnt;
146 fbt->fbtp_savedval = *instr; 164 fbt->fbtp_savedval = ldinstr(instr);
147 fbt->fbtp_patchval = FBT_BREAKPOINT; 165 fbt->fbtp_patchval = FBT_BREAKPOINT;
148 fbt->fbtp_rval = DTRACE_INVOP_PUSHM; 166 fbt->fbtp_rval = DTRACE_INVOP_PUSHM;
149 fbt->fbtp_symindx = symindx; 167 fbt->fbtp_symindx = symindx;
150 168
151 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; 169 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
152 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; 170 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
153 171
154 lf->fbt_nentries++; 172 lf->fbt_nentries++;
155 173
156 popm = FBT_POPM | ((*instr) & 0x3FFF) | 0x8000; 174 popm = FBT_POPM | (ldinstr(instr) & 0x3FFF) | 0x8000;
157 175
158 retfbt = NULL; 176 retfbt = NULL;
159again: 177again:
160 for (; instr < limit; instr++) { 178 for (; instr < limit; instr++) {
161 if (*instr == popm) 179 if (ldinstr(instr) == popm)
162 break; 180 break;
163 else if ((*instr & 0xff000000) == FBT_JUMP) { 181 else if ((ldinstr(instr) & 0xff000000) == FBT_JUMP) {
164 uint32_t *target, *start; 182 uint32_t *target, *start;
165 int offset; 183 int offset;
166 184
167 offset = (*instr & 0xffffff); 185 offset = (ldinstr(instr) & 0xffffff);
168 offset <<= 8; 186 offset <<= 8;
169 offset /= 64; 187 offset /= 64;
170 target = instr + (2 + offset); 188 target = instr + (2 + offset);
171 start = (uint32_t *)symval->value; 189 start = (uint32_t *)symval->value;
172 if (target >= limit || target < start) 190 if (target >= limit || target < start)
173 break; 191 break;
174 } 192 }
175 } 193 }
176 194
177 if (instr >= limit) 195 if (instr >= limit)
178 return (0); 196 return (0);
179 197
180 /* 198 /*
@@ -185,31 +203,31 @@ again: @@ -185,31 +203,31 @@ again:
185 if (retfbt == NULL) { 203 if (retfbt == NULL) {
186 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 204 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
187 name, FBT_RETURN, 5, fbt); 205 name, FBT_RETURN, 5, fbt);
188 } else { 206 } else {
189 retfbt->fbtp_next = fbt; 207 retfbt->fbtp_next = fbt;
190 fbt->fbtp_id = retfbt->fbtp_id; 208 fbt->fbtp_id = retfbt->fbtp_id;
191 } 209 }
192 retfbt = fbt; 210 retfbt = fbt;
193 211
194 fbt->fbtp_patchpoint = instr; 212 fbt->fbtp_patchpoint = instr;
195 fbt->fbtp_ctl = lf; 213 fbt->fbtp_ctl = lf;
196 fbt->fbtp_loadcnt = lf->loadcnt; 214 fbt->fbtp_loadcnt = lf->loadcnt;
197 fbt->fbtp_symindx = symindx; 215 fbt->fbtp_symindx = symindx;
198 if ((*instr & 0xff000000) == FBT_JUMP) 216 if ((ldinstr(instr) & 0xff000000) == FBT_JUMP)
199 fbt->fbtp_rval = DTRACE_INVOP_B; 217 fbt->fbtp_rval = DTRACE_INVOP_B;
200 else 218 else
201 fbt->fbtp_rval = DTRACE_INVOP_POPM; 219 fbt->fbtp_rval = DTRACE_INVOP_POPM;
202 fbt->fbtp_savedval = *instr; 220 fbt->fbtp_savedval = ldinstr(instr);
203 fbt->fbtp_patchval = FBT_BREAKPOINT; 221 fbt->fbtp_patchval = FBT_BREAKPOINT;
204 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; 222 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
205 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; 223 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
206 224
207 lf->fbt_nentries++; 225 lf->fbt_nentries++;
208 226
209 instr++; 227 instr++;
210 goto again; 228 goto again;
211} 229}
212 230
213#endif /* __FreeBSD_ */ 231#endif /* __FreeBSD_ */
214 232
215#ifdef __NetBSD__ 233#ifdef __NetBSD__
@@ -269,90 +287,99 @@ fbt_provide_module_cb(const char *name,  @@ -269,90 +287,99 @@ fbt_provide_module_cb(const char *name,
269 strcmp(name, "binuptime") == 0 || 287 strcmp(name, "binuptime") == 0 ||
270 strcmp(name, "nanouptime") == 0 || 288 strcmp(name, "nanouptime") == 0 ||
271 strcmp(name, "dosoftints") == 0 || 289 strcmp(name, "dosoftints") == 0 ||
272 strcmp(name, "fbt_emulate") == 0 || 290 strcmp(name, "fbt_emulate") == 0 ||
273 strcmp(name, "undefinedinstruction") == 0 || 291 strcmp(name, "undefinedinstruction") == 0 ||
274 strncmp(name, "dmt_", 4) == 0 /* omap */ || 292 strncmp(name, "dmt_", 4) == 0 /* omap */ ||
275 strncmp(name, "mvsoctmr_", 9) == 0 /* marvell */ ) { 293 strncmp(name, "mvsoctmr_", 9) == 0 /* marvell */ ) {
276 return 0; 294 return 0;
277 } 295 }
278 296
279 instr = (uint32_t *) value; 297 instr = (uint32_t *) value;
280 limit = (uint32_t *)((uintptr_t)value + symsize); 298 limit = (uint32_t *)((uintptr_t)value + symsize);
281 299
282 if (!FBT_MOV_IP_SP_P(*instr) 300 if (!FBT_MOV_IP_SP_P(ldinstr(instr))
283 && !FBT_BX_LR_P(*instr) 301 && !FBT_BX_LR_P(ldinstr(instr))
284 && !FBT_MOVW_P(*instr) 302 && !FBT_MOVW_P(ldinstr(instr))
285 && !FBT_MOV_IMM_P(*instr) 303 && !FBT_MOV_IMM_P(ldinstr(instr))
286 && !FBT_B_LABEL_P(*instr) 304 && !FBT_B_LABEL_P(ldinstr(instr))
287 && !FBT_LDR_IMM_P(*instr) 305 && !FBT_LDR_IMM_P(ldinstr(instr))
288 && !FBT_CMP_IMM_P(*instr) 306 && !FBT_CMP_IMM_P(ldinstr(instr))
289 && !FBT_PUSH_P(*instr) 307 && !FBT_PUSH_P(ldinstr(instr))
290 ) { 308 ) {
291 return 0; 309 return 0;
292 } 310 }
293 311
294 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); 312 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
295 fbt->fbtp_name = name; 313 fbt->fbtp_name = name;
296 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 314 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
297 name, FBT_ENTRY, 5, fbt); 315 name, FBT_ENTRY, 5, fbt);
298 fbt->fbtp_patchpoint = instr; 316 fbt->fbtp_patchpoint = instr;
299 fbt->fbtp_ctl = mod; 317 fbt->fbtp_ctl = mod;
300 /* fbt->fbtp_loadcnt = lf->loadcnt; */ 318 /* fbt->fbtp_loadcnt = lf->loadcnt; */
301 if (FBT_MOV_IP_SP_P(*instr)) 319 if (FBT_MOV_IP_SP_P(ldinstr(instr))) {
302 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_IP_SP); 320 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
303 else if (FBT_LDR_IMM_P(*instr)) 321 DTRACE_INVOP_MOV_IP_SP);
304 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_LDR_IMM); 322 } else if (FBT_LDR_IMM_P(ldinstr(instr))) {
305 else if (FBT_MOVW_P(*instr)) 323 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
306 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOVW); 324 DTRACE_INVOP_LDR_IMM);
307 else if (FBT_MOV_IMM_P(*instr)) 325 } else if (FBT_MOVW_P(ldinstr(instr))) {
308 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_IMM); 326 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), DTRACE_INVOP_MOVW);
309 else if (FBT_CMP_IMM_P(*instr)) 327 } else if (FBT_MOV_IMM_P(ldinstr(instr))) {
310 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_CMP_IMM); 328 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
311 else if (FBT_BX_LR_P(*instr)) 329 DTRACE_INVOP_MOV_IMM);
312 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_BX_LR); 330 } else if (FBT_CMP_IMM_P(ldinstr(instr))) {
313 else if (FBT_PUSH_P(*instr)) 331 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
314 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_PUSHM); 332 DTRACE_INVOP_CMP_IMM);
315 else if (FBT_B_LABEL_P(*instr)) 333 } else if (FBT_BX_LR_P(ldinstr(instr))) {
316 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_B); 334 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
317 else 335 DTRACE_INVOP_BX_LR);
 336 } else if (FBT_PUSH_P(ldinstr(instr))) {
 337 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
 338 DTRACE_INVOP_PUSHM);
 339 } else if (FBT_B_LABEL_P(ldinstr(instr))) {
 340 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
 341 DTRACE_INVOP_B);
 342 } else {
318 KASSERT(0); 343 KASSERT(0);
 344 }
319 345
320 KASSERTMSG((fbt->fbtp_rval >> 28) != 0, 346 KASSERTMSG((fbt->fbtp_rval >> 28) != 0,
321 "fbt %p insn 0x%x name %s rval 0x%08x", 347 "fbt %p insn 0x%x name %s rval 0x%08x",
322 fbt, *instr, name, fbt->fbtp_rval); 348 fbt, ldinstr(instr), name, fbt->fbtp_rval);
323 349
324 fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(*instr); 350 fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(ldinstr(instr));
325 fbt->fbtp_savedval = *instr; 351 fbt->fbtp_savedval = ldinstr(instr);
326 fbt->fbtp_symindx = symindx; 352 fbt->fbtp_symindx = symindx;
327 353
328 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; 354 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
329 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; 355 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
330 356
331 retfbt = NULL; 357 retfbt = NULL;
332 358
333 while (instr < limit) { 359 while (instr < limit) {
334 if (instr >= limit) 360 if (instr >= limit)
335 return (0); 361 return (0);
336 362
337 size = 1; 363 size = 1;
338 364
339 if (!FBT_BX_LR_P(*instr) 365 if (!FBT_BX_LR_P(ldinstr(instr))
340 && !FBT_MOV_PC_LR_P(*instr) 366 && !FBT_MOV_PC_LR_P(ldinstr(instr))
341 && !FBT_LDM_P(*instr) 367 && !FBT_LDM_P(ldinstr(instr))
342 && !FBT_LDMIB_P(*instr) 368 && !FBT_LDMIB_P(ldinstr(instr))
343 && !(was_ldm_lr && FBT_B_LABEL_P(*instr)) 369 && !(was_ldm_lr && FBT_B_LABEL_P(ldinstr(instr)))
344 ) { 370 ) {
345 if (FBT_LDM_LR_P(*instr) || FBT_LDMIB_LR_P(*instr)) 371 if (FBT_LDM_LR_P(ldinstr(instr)) ||
 372 FBT_LDMIB_LR_P(ldinstr(instr)))
346 was_ldm_lr = true; 373 was_ldm_lr = true;
347 else 374 else
348 was_ldm_lr = false; 375 was_ldm_lr = false;
349 instr += size; 376 instr += size;
350 continue; 377 continue;
351 } 378 }
352 379
353 /* 380 /*
354 * We have a winner! 381 * We have a winner!
355 */ 382 */
356 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); 383 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
357 fbt->fbtp_name = name; 384 fbt->fbtp_name = name;
358 385
@@ -360,44 +387,50 @@ fbt_provide_module_cb(const char *name,  @@ -360,44 +387,50 @@ fbt_provide_module_cb(const char *name,
360 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 387 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
361 name, FBT_RETURN, 5, fbt); 388 name, FBT_RETURN, 5, fbt);
362 } else { 389 } else {
363 retfbt->fbtp_next = fbt; 390 retfbt->fbtp_next = fbt;
364 fbt->fbtp_id = retfbt->fbtp_id; 391 fbt->fbtp_id = retfbt->fbtp_id;
365 } 392 }
366 393
367 retfbt = fbt; 394 retfbt = fbt;
368 fbt->fbtp_patchpoint = instr; 395 fbt->fbtp_patchpoint = instr;
369 fbt->fbtp_ctl = mod; 396 fbt->fbtp_ctl = mod;
370 /* fbt->fbtp_loadcnt = lf->loadcnt; */ 397 /* fbt->fbtp_loadcnt = lf->loadcnt; */
371 fbt->fbtp_symindx = symindx; 398 fbt->fbtp_symindx = symindx;
372 399
373 if (FBT_BX_LR_P(*instr)) 400 if (FBT_BX_LR_P(ldinstr(instr))) {
374 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_BX_LR); 401 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
375 else if (FBT_MOV_PC_LR_P(*instr)) 402 DTRACE_INVOP_BX_LR);
376 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_PC_LR); 403 } else if (FBT_MOV_PC_LR_P(ldinstr(instr))) {
377 else if (FBT_LDM_P(*instr)) 404 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
378 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_LDM); 405 DTRACE_INVOP_MOV_PC_LR);
379 else if (FBT_LDMIB_P(*instr)) 406 } else if (FBT_LDM_P(ldinstr(instr))) {
380 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_POPM); 407 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
381 else if (FBT_B_LABEL_P(*instr)) 408 DTRACE_INVOP_LDM);
382 fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_B); 409 } else if (FBT_LDMIB_P(ldinstr(instr))) {
383 else 410 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
 411 DTRACE_INVOP_POPM);
 412 } else if (FBT_B_LABEL_P(ldinstr(instr))) {
 413 fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr),
 414 DTRACE_INVOP_B);
 415 } else {
384 KASSERT(0); 416 KASSERT(0);
 417 }
385 418
386 KASSERTMSG((fbt->fbtp_rval >> 28) != 0, "fbt %p name %s rval 0x%08x", 419 KASSERTMSG((fbt->fbtp_rval >> 28) != 0, "fbt %p name %s rval 0x%08x",
387 fbt, name, fbt->fbtp_rval); 420 fbt, name, fbt->fbtp_rval);
388 421
389 fbt->fbtp_roffset = (uintptr_t)(instr - (uint32_t *) value); 422 fbt->fbtp_roffset = (uintptr_t)(instr - (uint32_t *) value);
390 fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(*instr); 423 fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(ldinstr(instr));
391 424
392 fbt->fbtp_savedval = *instr; 425 fbt->fbtp_savedval = ldinstr(instr);
393 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; 426 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
394 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; 427 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
395 428
396 instr += size; 429 instr += size;
397 was_ldm_lr = false; 430 was_ldm_lr = false;
398 } 431 }
399 432
400 return 0; 433 return 0;
401} 434}
402 435
403#endif /* __NetBSD__ */ 436#endif /* __NetBSD__ */