1 /* libunwind - a platform-independent unwind library
2 Copyright (C) 2001-2002 Hewlett-Packard Co
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of libunwind.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
27 * Generic IA-64 unwind info decoder.
29 * This file is used both by the Linux kernel and objdump. Please keep
30 * the two copies of this file in sync.
32 * You need to customize the decoder by defining the following
33 * macros/constants before including this file:
36 * unw_word Unsigned integer type with at least 64 bits
50 * Decoder action macros:
51 * UNW_DEC_BAD_CODE(code)
52 * UNW_DEC_ABI(fmt,abi,context,arg)
53 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
54 * UNW_DEC_BR_MEM(fmt,brmask,arg)
55 * UNW_DEC_COPY_STATE(fmt,label,arg)
56 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
57 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
58 * UNW_DEC_FR_MEM(fmt,frmask,arg)
59 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
60 * UNW_DEC_GR_MEM(fmt,grmask,arg)
61 * UNW_DEC_LABEL_STATE(fmt,label,arg)
62 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
63 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
64 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
65 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
66 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
67 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
68 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
69 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
70 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
71 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
72 * UNW_DEC_REG_REG(fmt,src,dst,arg)
73 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
74 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
75 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
76 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
77 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
78 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
79 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
80 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
81 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
82 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
83 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
84 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
88 unw_decode_uleb128 (unsigned char **dpp
)
91 unw_word byte
, result
= 0;
92 unsigned char *bp
= *dpp
;
97 result
|= (byte
& 0x7f) << shift
;
98 if ((byte
& 0x80) == 0)
106 static unsigned char *
107 unw_decode_x1 (unsigned char *dp
, unsigned char code
, void *arg
)
109 unsigned char byte1
, abreg
;
113 t
= unw_decode_uleb128 (&dp
);
114 off
= unw_decode_uleb128 (&dp
);
115 abreg
= (byte1
& 0x7f);
117 UNW_DEC_SPILL_SPREL(X1
, t
, abreg
, off
, arg
);
119 UNW_DEC_SPILL_PSPREL(X1
, t
, abreg
, off
, arg
);
123 static unsigned char *
124 unw_decode_x2 (unsigned char *dp
, unsigned char code
, void *arg
)
126 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
129 byte1
= *dp
++; byte2
= *dp
++;
130 t
= unw_decode_uleb128 (&dp
);
131 abreg
= (byte1
& 0x7f);
133 x
= (byte1
>> 7) & 1;
134 if ((byte1
& 0x80) == 0 && ytreg
== 0)
135 UNW_DEC_RESTORE(X2
, t
, abreg
, arg
);
137 UNW_DEC_SPILL_REG(X2
, t
, abreg
, x
, ytreg
, arg
);
141 static unsigned char *
142 unw_decode_x3 (unsigned char *dp
, unsigned char code
, void *arg
)
144 unsigned char byte1
, byte2
, abreg
, qp
;
147 byte1
= *dp
++; byte2
= *dp
++;
148 t
= unw_decode_uleb128 (&dp
);
149 off
= unw_decode_uleb128 (&dp
);
152 abreg
= (byte2
& 0x7f);
155 UNW_DEC_SPILL_SPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
157 UNW_DEC_SPILL_PSPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
161 static unsigned char *
162 unw_decode_x4 (unsigned char *dp
, unsigned char code
, void *arg
)
164 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
167 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
168 t
= unw_decode_uleb128 (&dp
);
171 abreg
= (byte2
& 0x7f);
172 x
= (byte2
>> 7) & 1;
175 if ((byte2
& 0x80) == 0 && byte3
== 0)
176 UNW_DEC_RESTORE_P(X4
, qp
, t
, abreg
, arg
);
178 UNW_DEC_SPILL_REG_P(X4
, qp
, t
, abreg
, x
, ytreg
, arg
);
182 static inline unsigned char *
183 unw_decode_r1 (unsigned char *dp
, unsigned char code
, void *arg
)
185 int body
= (code
& 0x20) != 0;
188 rlen
= (code
& 0x1f);
189 UNW_DEC_PROLOGUE(R1
, body
, rlen
, arg
);
193 static inline unsigned char *
194 unw_decode_r2 (unsigned char *dp
, unsigned char code
, void *arg
)
196 unsigned char byte1
, mask
, grsave
;
201 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
202 grsave
= (byte1
& 0x7f);
203 rlen
= unw_decode_uleb128 (&dp
);
204 UNW_DEC_PROLOGUE_GR(R2
, rlen
, mask
, grsave
, arg
);
208 static inline unsigned char *
209 unw_decode_r3 (unsigned char *dp
, unsigned char code
, void *arg
)
213 rlen
= unw_decode_uleb128 (&dp
);
214 UNW_DEC_PROLOGUE(R3
, ((code
& 0x3) == 1), rlen
, arg
);
218 static inline unsigned char *
219 unw_decode_p1 (unsigned char *dp
, unsigned char code
, void *arg
)
221 unsigned char brmask
= (code
& 0x1f);
223 UNW_DEC_BR_MEM(P1
, brmask
, arg
);
227 static inline unsigned char *
228 unw_decode_p2_p5 (unsigned char *dp
, unsigned char code
, void *arg
)
230 if ((code
& 0x10) == 0)
232 unsigned char byte1
= *dp
++;
234 UNW_DEC_BR_GR(P2
, ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
235 (byte1
& 0x7f), arg
);
237 else if ((code
& 0x08) == 0)
239 unsigned char byte1
= *dp
++, r
, dst
;
241 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
242 dst
= (byte1
& 0x7f);
245 case 0: UNW_DEC_REG_GR(P3
, UNW_REG_PSP
, dst
, arg
); break;
246 case 1: UNW_DEC_REG_GR(P3
, UNW_REG_RP
, dst
, arg
); break;
247 case 2: UNW_DEC_REG_GR(P3
, UNW_REG_PFS
, dst
, arg
); break;
248 case 3: UNW_DEC_REG_GR(P3
, UNW_REG_PR
, dst
, arg
); break;
249 case 4: UNW_DEC_REG_GR(P3
, UNW_REG_UNAT
, dst
, arg
); break;
250 case 5: UNW_DEC_REG_GR(P3
, UNW_REG_LC
, dst
, arg
); break;
251 case 6: UNW_DEC_RP_BR(P3
, dst
, arg
); break;
252 case 7: UNW_DEC_REG_GR(P3
, UNW_REG_RNAT
, dst
, arg
); break;
253 case 8: UNW_DEC_REG_GR(P3
, UNW_REG_BSP
, dst
, arg
); break;
254 case 9: UNW_DEC_REG_GR(P3
, UNW_REG_BSPSTORE
, dst
, arg
); break;
255 case 10: UNW_DEC_REG_GR(P3
, UNW_REG_FPSR
, dst
, arg
); break;
256 case 11: UNW_DEC_PRIUNAT_GR(P3
, dst
, arg
); break;
257 default: UNW_DEC_BAD_CODE(r
); break;
260 else if ((code
& 0x7) == 0)
261 UNW_DEC_SPILL_MASK(P4
, dp
, arg
);
262 else if ((code
& 0x7) == 1)
264 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
266 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
267 grmask
= ((byte1
>> 4) & 0xf);
268 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
269 UNW_DEC_FRGR_MEM(P5
, grmask
, frmask
, arg
);
272 UNW_DEC_BAD_CODE(code
);
276 static inline unsigned char *
277 unw_decode_p6 (unsigned char *dp
, unsigned char code
, void *arg
)
279 int gregs
= (code
& 0x10) != 0;
280 unsigned char mask
= (code
& 0x0f);
283 UNW_DEC_GR_MEM(P6
, mask
, arg
);
285 UNW_DEC_FR_MEM(P6
, mask
, arg
);
289 static inline unsigned char *
290 unw_decode_p7_p10 (unsigned char *dp
, unsigned char code
, void *arg
)
292 unsigned char r
, byte1
, byte2
;
295 if ((code
& 0x10) == 0)
298 t
= unw_decode_uleb128 (&dp
);
302 size
= unw_decode_uleb128 (&dp
);
303 UNW_DEC_MEM_STACK_F(P7
, t
, size
, arg
);
306 case 1: UNW_DEC_MEM_STACK_V(P7
, t
, arg
); break;
307 case 2: UNW_DEC_SPILL_BASE(P7
, t
, arg
); break;
308 case 3: UNW_DEC_REG_SPREL(P7
, UNW_REG_PSP
, t
, arg
); break;
309 case 4: UNW_DEC_REG_WHEN(P7
, UNW_REG_RP
, t
, arg
); break;
310 case 5: UNW_DEC_REG_PSPREL(P7
, UNW_REG_RP
, t
, arg
); break;
311 case 6: UNW_DEC_REG_WHEN(P7
, UNW_REG_PFS
, t
, arg
); break;
312 case 7: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PFS
, t
, arg
); break;
313 case 8: UNW_DEC_REG_WHEN(P7
, UNW_REG_PR
, t
, arg
); break;
314 case 9: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PR
, t
, arg
); break;
315 case 10: UNW_DEC_REG_WHEN(P7
, UNW_REG_LC
, t
, arg
); break;
316 case 11: UNW_DEC_REG_PSPREL(P7
, UNW_REG_LC
, t
, arg
); break;
317 case 12: UNW_DEC_REG_WHEN(P7
, UNW_REG_UNAT
, t
, arg
); break;
318 case 13: UNW_DEC_REG_PSPREL(P7
, UNW_REG_UNAT
, t
, arg
); break;
319 case 14: UNW_DEC_REG_WHEN(P7
, UNW_REG_FPSR
, t
, arg
); break;
320 case 15: UNW_DEC_REG_PSPREL(P7
, UNW_REG_FPSR
, t
, arg
); break;
321 default: UNW_DEC_BAD_CODE(r
); break;
331 t
= unw_decode_uleb128 (&dp
);
334 case 1: UNW_DEC_REG_SPREL(P8
, UNW_REG_RP
, t
, arg
); break;
335 case 2: UNW_DEC_REG_SPREL(P8
, UNW_REG_PFS
, t
, arg
); break;
336 case 3: UNW_DEC_REG_SPREL(P8
, UNW_REG_PR
, t
, arg
); break;
337 case 4: UNW_DEC_REG_SPREL(P8
, UNW_REG_LC
, t
, arg
); break;
338 case 5: UNW_DEC_REG_SPREL(P8
, UNW_REG_UNAT
, t
, arg
); break;
339 case 6: UNW_DEC_REG_SPREL(P8
, UNW_REG_FPSR
, t
, arg
); break;
340 case 7: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSP
, t
, arg
); break;
341 case 8: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
342 case 9: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
343 case 10: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
344 case 11: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
345 case 12: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
346 case 13: UNW_DEC_REG_WHEN(P8
, UNW_REG_RNAT
, t
, arg
); break;
347 case 14: UNW_DEC_REG_PSPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
348 case 15: UNW_DEC_REG_SPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
349 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8
, t
, arg
); break;
350 case 17: UNW_DEC_PRIUNAT_PSPREL(P8
, t
, arg
); break;
351 case 18: UNW_DEC_PRIUNAT_SPREL(P8
, t
, arg
); break;
352 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8
, t
, arg
); break;
353 default: UNW_DEC_BAD_CODE(r
); break;
359 byte1
= *dp
++; byte2
= *dp
++;
360 UNW_DEC_GR_GR(P9
, (byte1
& 0xf), (byte2
& 0x7f), arg
);
364 byte1
= *dp
++; byte2
= *dp
++;
365 UNW_DEC_ABI(P10
, byte1
, byte2
, arg
);
369 return unw_decode_x1 (dp
, code
, arg
);
372 return unw_decode_x2 (dp
, code
, arg
);
375 return unw_decode_x3 (dp
, code
, arg
);
378 return unw_decode_x4 (dp
, code
, arg
);
381 UNW_DEC_BAD_CODE(code
);
388 static inline unsigned char *
389 unw_decode_b1 (unsigned char *dp
, unsigned char code
, void *arg
)
391 unw_word label
= (code
& 0x1f);
393 if ((code
& 0x20) != 0)
394 UNW_DEC_COPY_STATE(B1
, label
, arg
);
396 UNW_DEC_LABEL_STATE(B1
, label
, arg
);
400 static inline unsigned char *
401 unw_decode_b2 (unsigned char *dp
, unsigned char code
, void *arg
)
405 t
= unw_decode_uleb128 (&dp
);
406 UNW_DEC_EPILOGUE(B2
, t
, (code
& 0x1f), arg
);
410 static inline unsigned char *
411 unw_decode_b3_x4 (unsigned char *dp
, unsigned char code
, void *arg
)
413 unw_word t
, ecount
, label
;
415 if ((code
& 0x10) == 0)
417 t
= unw_decode_uleb128 (&dp
);
418 ecount
= unw_decode_uleb128 (&dp
);
419 UNW_DEC_EPILOGUE(B3
, t
, ecount
, arg
);
421 else if ((code
& 0x07) == 0)
423 label
= unw_decode_uleb128 (&dp
);
424 if ((code
& 0x08) != 0)
425 UNW_DEC_COPY_STATE(B4
, label
, arg
);
427 UNW_DEC_LABEL_STATE(B4
, label
, arg
);
432 case 1: return unw_decode_x1 (dp
, code
, arg
);
433 case 2: return unw_decode_x2 (dp
, code
, arg
);
434 case 3: return unw_decode_x3 (dp
, code
, arg
);
435 case 4: return unw_decode_x4 (dp
, code
, arg
);
436 default: UNW_DEC_BAD_CODE(code
); break;
441 typedef unsigned char *(*unw_decoder
) (unsigned char *, unsigned char, void *);
444 * Decode one descriptor and return address of next descriptor.
446 static inline unsigned char *
447 unw_decode (unsigned char *dp
, int inside_body
, void *arg
)
449 unsigned char code
, primary
;
455 dp
= unw_decode_r1 (dp
, code
, arg
);
456 else if (primary
== 2)
457 dp
= unw_decode_r2 (dp
, code
, arg
);
458 else if (primary
== 3)
459 dp
= unw_decode_r3 (dp
, code
, arg
);
460 else if (inside_body
)
464 case 5: dp
= unw_decode_b1 (dp
, code
, arg
); break;
465 case 6: dp
= unw_decode_b2 (dp
, code
, arg
); break;
466 case 7: dp
= unw_decode_b3_x4 (dp
, code
, arg
); break;
471 case 4: dp
= unw_decode_p1 (dp
, code
, arg
); break;
472 case 5: dp
= unw_decode_p2_p5 (dp
, code
, arg
); break;
473 case 6: dp
= unw_decode_p6 (dp
, code
, arg
); break;
474 case 7: dp
= unw_decode_p7_p10 (dp
, code
, arg
); break;