1 /* libunwind - a platform-independent unwind library
2 Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
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. */
28 #include "libunwind_i.h"
30 #define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool))
31 #define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs))
34 read_regnum (unw_addr_space_t as
, unw_accessors_t
*a
, unw_word_t
*addr
,
35 unw_word_t
*valp
, void *arg
)
39 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, valp
, arg
)) < 0)
42 if (*valp
>= DWARF_NUM_PRESERVED_REGS
)
44 Debug (1, "Invalid register number %u\n", (unsigned int) *valp
);
51 set_reg (dwarf_state_record_t
*sr
, unw_word_t regnum
, dwarf_where_t where
,
54 sr
->rs_current
.reg
[regnum
].where
= where
;
55 sr
->rs_current
.reg
[regnum
].val
= val
;
58 /* Run a CFI program to update the register state. */
60 run_cfi_program (struct dwarf_cursor
*c
, dwarf_state_record_t
*sr
,
61 unw_word_t ip
, unw_word_t
*addr
, unw_word_t end_addr
,
62 struct dwarf_cie_info
*dci
)
64 unw_word_t curr_ip
, operand
= 0, regnum
, val
, len
, fde_encoding
;
65 dwarf_reg_state_t
*rs_stack
= NULL
, *new_rs
, *old_rs
;
76 if (c
->pi
.flags
& UNW_PI_FLAG_DEBUG_FRAME
)
78 /* .debug_frame CFI is stored in local address space. */
79 as
= unw_local_addr_space
;
82 a
= unw_get_accessors (as
);
83 curr_ip
= c
->pi
.start_ip
;
85 /* Process everything up to and including the current 'ip',
86 including all the DW_CFA_advance_loc instructions. See
87 'c->use_prev_instr' use in 'fetch_proc_info' for details. */
88 while (curr_ip
<= ip
&& *addr
< end_addr
)
90 if ((ret
= dwarf_readu8 (as
, a
, addr
, &op
, arg
)) < 0)
93 if (op
& DWARF_CFA_OPCODE_MASK
)
95 operand
= op
& DWARF_CFA_OPERAND_MASK
;
96 op
&= ~DWARF_CFA_OPERAND_MASK
;
98 switch ((dwarf_cfa_t
) op
)
100 case DW_CFA_advance_loc
:
101 curr_ip
+= operand
* dci
->code_align
;
102 Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip
);
105 case DW_CFA_advance_loc1
:
106 if ((ret
= dwarf_readu8 (as
, a
, addr
, &u8
, arg
)) < 0)
108 curr_ip
+= u8
* dci
->code_align
;
109 Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip
);
112 case DW_CFA_advance_loc2
:
113 if ((ret
= dwarf_readu16 (as
, a
, addr
, &u16
, arg
)) < 0)
115 curr_ip
+= u16
* dci
->code_align
;
116 Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip
);
119 case DW_CFA_advance_loc4
:
120 if ((ret
= dwarf_readu32 (as
, a
, addr
, &u32
, arg
)) < 0)
122 curr_ip
+= u32
* dci
->code_align
;
123 Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip
);
126 case DW_CFA_MIPS_advance_loc8
:
127 #ifdef UNW_TARGET_MIPS
131 if ((ret
= dwarf_readu64 (as
, a
, addr
, &u64
, arg
)) < 0)
133 curr_ip
+= u64
* dci
->code_align
;
134 Debug (15, "CFA_MIPS_advance_loc8\n");
138 Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n");
145 if (regnum
>= DWARF_NUM_PRESERVED_REGS
)
147 Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n",
148 (unsigned int) regnum
);
152 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &val
, arg
)) < 0)
154 set_reg (sr
, regnum
, DWARF_WHERE_CFAREL
, val
* dci
->data_align
);
155 Debug (15, "CFA_offset r%lu at cfa+0x%lx\n",
156 (long) regnum
, (long) (val
* dci
->data_align
));
159 case DW_CFA_offset_extended
:
160 if (((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
161 || ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &val
, arg
)) < 0))
163 set_reg (sr
, regnum
, DWARF_WHERE_CFAREL
, val
* dci
->data_align
);
164 Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n",
165 (long) regnum
, (long) (val
* dci
->data_align
));
168 case DW_CFA_offset_extended_sf
:
169 if (((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
170 || ((ret
= dwarf_read_sleb128 (as
, a
, addr
, &val
, arg
)) < 0))
172 set_reg (sr
, regnum
, DWARF_WHERE_CFAREL
, val
* dci
->data_align
);
173 Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n",
174 (long) regnum
, (long) (val
* dci
->data_align
));
179 if (regnum
>= DWARF_NUM_PRESERVED_REGS
)
181 Debug (1, "Invalid register number %u in DW_CFA_restore\n",
182 (unsigned int) regnum
);
186 sr
->rs_current
.reg
[regnum
] = sr
->rs_initial
.reg
[regnum
];
187 Debug (15, "CFA_restore r%lu\n", (long) regnum
);
190 case DW_CFA_restore_extended
:
191 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, ®num
, arg
)) < 0)
193 if (regnum
>= DWARF_NUM_PRESERVED_REGS
)
195 Debug (1, "Invalid register number %u in "
196 "DW_CFA_restore_extended\n", (unsigned int) regnum
);
200 sr
->rs_current
.reg
[regnum
] = sr
->rs_initial
.reg
[regnum
];
201 Debug (15, "CFA_restore_extended r%lu\n", (long) regnum
);
208 fde_encoding
= dci
->fde_encoding
;
209 if ((ret
= dwarf_read_encoded_pointer (as
, a
, addr
, fde_encoding
,
210 c
->pi
.gp
, c
->pi
.start_ip
, &curr_ip
,
213 Debug (15, "CFA_set_loc to 0x%lx\n", (long) curr_ip
);
216 case DW_CFA_undefined
:
217 if ((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
219 set_reg (sr
, regnum
, DWARF_WHERE_UNDEF
, 0);
220 Debug (15, "CFA_undefined r%lu\n", (long) regnum
);
223 case DW_CFA_same_value
:
224 if ((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
226 set_reg (sr
, regnum
, DWARF_WHERE_SAME
, 0);
227 Debug (15, "CFA_same_value r%lu\n", (long) regnum
);
230 case DW_CFA_register
:
231 if (((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
232 || ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &val
, arg
)) < 0))
234 set_reg (sr
, regnum
, DWARF_WHERE_REG
, val
);
235 Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum
, (long) val
);
238 case DW_CFA_remember_state
:
239 new_rs
= alloc_reg_state ();
242 Debug (1, "Out of memory in DW_CFA_remember_state\n");
247 memcpy (new_rs
->reg
, sr
->rs_current
.reg
, sizeof (new_rs
->reg
));
248 new_rs
->next
= rs_stack
;
250 Debug (15, "CFA_remember_state\n");
253 case DW_CFA_restore_state
:
256 Debug (1, "register-state stack underflow\n");
260 memcpy (&sr
->rs_current
.reg
, &rs_stack
->reg
, sizeof (rs_stack
->reg
));
262 rs_stack
= rs_stack
->next
;
263 free_reg_state (old_rs
);
264 Debug (15, "CFA_restore_state\n");
268 if (((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
269 || ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &val
, arg
)) < 0))
271 set_reg (sr
, DWARF_CFA_REG_COLUMN
, DWARF_WHERE_REG
, regnum
);
272 set_reg (sr
, DWARF_CFA_OFF_COLUMN
, 0, val
); /* NOT factored! */
273 Debug (15, "CFA_def_cfa r%lu+0x%lx\n", (long) regnum
, (long) val
);
276 case DW_CFA_def_cfa_sf
:
277 if (((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
278 || ((ret
= dwarf_read_sleb128 (as
, a
, addr
, &val
, arg
)) < 0))
280 set_reg (sr
, DWARF_CFA_REG_COLUMN
, DWARF_WHERE_REG
, regnum
);
281 set_reg (sr
, DWARF_CFA_OFF_COLUMN
, 0,
282 val
* dci
->data_align
); /* factored! */
283 Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n",
284 (long) regnum
, (long) (val
* dci
->data_align
));
287 case DW_CFA_def_cfa_register
:
288 if ((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
290 set_reg (sr
, DWARF_CFA_REG_COLUMN
, DWARF_WHERE_REG
, regnum
);
291 Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum
);
294 case DW_CFA_def_cfa_offset
:
295 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &val
, arg
)) < 0)
297 set_reg (sr
, DWARF_CFA_OFF_COLUMN
, 0, val
); /* NOT factored! */
298 Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val
);
301 case DW_CFA_def_cfa_offset_sf
:
302 if ((ret
= dwarf_read_sleb128 (as
, a
, addr
, &val
, arg
)) < 0)
304 set_reg (sr
, DWARF_CFA_OFF_COLUMN
, 0,
305 val
* dci
->data_align
); /* factored! */
306 Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n",
307 (long) (val
* dci
->data_align
));
310 case DW_CFA_def_cfa_expression
:
311 /* Save the address of the DW_FORM_block for later evaluation. */
312 set_reg (sr
, DWARF_CFA_REG_COLUMN
, DWARF_WHERE_EXPR
, *addr
);
314 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &len
, arg
)) < 0)
317 Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n",
318 (long) *addr
, (long) len
);
322 case DW_CFA_expression
:
323 if ((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
326 /* Save the address of the DW_FORM_block for later evaluation. */
327 set_reg (sr
, regnum
, DWARF_WHERE_EXPR
, *addr
);
329 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &len
, arg
)) < 0)
332 Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n",
333 (long) regnum
, (long) addr
, (long) len
);
337 case DW_CFA_val_expression
:
338 if ((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
341 /* Save the address of the DW_FORM_block for later evaluation. */
342 set_reg (sr
, regnum
, DWARF_WHERE_VAL_EXPR
, *addr
);
344 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &len
, arg
)) < 0)
347 Debug (15, "CFA_val_expression r%lu @ 0x%lx [%lu bytes]\n",
348 (long) regnum
, (long) addr
, (long) len
);
352 case DW_CFA_GNU_args_size
:
353 if ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &val
, arg
)) < 0)
356 Debug (15, "CFA_GNU_args_size %lu\n", (long) val
);
359 case DW_CFA_GNU_negative_offset_extended
:
360 /* A comment in GCC says that this is obsoleted by
361 DW_CFA_offset_extended_sf, but that it's used by older
363 if (((ret
= read_regnum (as
, a
, addr
, ®num
, arg
)) < 0)
364 || ((ret
= dwarf_read_uleb128 (as
, a
, addr
, &val
, arg
)) < 0))
366 set_reg (sr
, regnum
, DWARF_WHERE_CFAREL
, -(val
* dci
->data_align
));
367 Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n",
368 (long) -(val
* dci
->data_align
));
371 case DW_CFA_GNU_window_save
:
372 #ifdef UNW_TARGET_SPARC
373 /* This is a special CFA to handle all 16 windowed registers
375 for (regnum
= 16; regnum
< 32; ++regnum
)
376 set_reg (sr
, regnum
, DWARF_WHERE_CFAREL
,
377 (regnum
- 16) * sizeof (unw_word_t
));
378 Debug (15, "CFA_GNU_window_save\n");
385 Debug (1, "Unexpected CFA opcode 0x%x\n", op
);
393 /* Free the register-state stack, if not empty already. */
397 rs_stack
= rs_stack
->next
;
398 free_reg_state (old_rs
);
404 fetch_proc_info (struct dwarf_cursor
*c
, unw_word_t ip
, int need_unwind_info
)
406 int ret
, dynamic
= 1;
408 /* The 'ip' can point either to the previous or next instruction
409 depending on what type of frame we have: normal call or a place
410 to resume execution (e.g. after signal frame).
412 For a normal call frame we need to back up so we point within the
413 call itself; this is important because a) the call might be the
414 very last instruction of the function and the edge of the FDE,
415 and b) so that run_cfi_program() runs locations up to the call
418 For execution resume, we need to do the exact opposite and look
419 up using the current 'ip' value. That is where execution will
420 continue, and it's important we get this right, as 'ip' could be
421 right at the function entry and hence FDE edge, or at instruction
422 that manipulates CFA (push/pop). */
423 if (c
->use_prev_instr
)
426 if (c
->pi_valid
&& !need_unwind_info
)
429 memset (&c
->pi
, 0, sizeof (c
->pi
));
431 /* check dynamic info first --- it overrides everything else */
432 ret
= unwi_find_dynamic_proc_info (c
->as
, ip
, &c
->pi
, need_unwind_info
,
434 if (ret
== -UNW_ENOINFO
)
437 if ((ret
= tdep_find_proc_info (c
, ip
, need_unwind_info
)) < 0)
441 if (c
->pi
.format
!= UNW_INFO_FORMAT_DYNAMIC
442 && c
->pi
.format
!= UNW_INFO_FORMAT_TABLE
443 && c
->pi
.format
!= UNW_INFO_FORMAT_REMOTE_TABLE
)
447 c
->pi_is_dynamic
= dynamic
;
449 /* Let system/machine-dependent code determine frame-specific attributes. */
451 tdep_fetch_frame (c
, ip
, need_unwind_info
);
453 /* Update use_prev_instr for the next frame. */
454 if (need_unwind_info
)
456 assert(c
->pi
.unwind_info
);
457 struct dwarf_cie_info
*dci
= c
->pi
.unwind_info
;
458 c
->use_prev_instr
= ! dci
->signal_frame
;
465 parse_dynamic (struct dwarf_cursor
*c
, unw_word_t ip
, dwarf_state_record_t
*sr
)
467 Debug (1, "Not yet implemented\n");
469 /* Don't forget to set the ret_addr_column! */
470 c
->ret_addr_column
= XXX
;
476 put_unwind_info (struct dwarf_cursor
*c
, unw_proc_info_t
*pi
)
478 if (c
->pi_is_dynamic
)
479 unwi_put_dynamic_unwind_info (c
->as
, pi
, c
->as_arg
);
480 else if (pi
->unwind_info
&& pi
->format
== UNW_INFO_FORMAT_TABLE
)
482 mempool_free (&dwarf_cie_info_pool
, pi
->unwind_info
);
483 pi
->unwind_info
= NULL
;
488 parse_fde (struct dwarf_cursor
*c
, unw_word_t ip
, dwarf_state_record_t
*sr
)
490 struct dwarf_cie_info
*dci
;
494 dci
= c
->pi
.unwind_info
;
495 c
->ret_addr_column
= dci
->ret_addr_column
;
497 addr
= dci
->cie_instr_start
;
498 if ((ret
= run_cfi_program (c
, sr
, ~(unw_word_t
) 0, &addr
,
499 dci
->cie_instr_end
, dci
)) < 0)
502 memcpy (&sr
->rs_initial
, &sr
->rs_current
, sizeof (sr
->rs_initial
));
504 addr
= dci
->fde_instr_start
;
505 if ((ret
= run_cfi_program (c
, sr
, ip
, &addr
, dci
->fde_instr_end
, dci
)) < 0)
512 flush_rs_cache (struct dwarf_rs_cache
*cache
)
516 cache
->lru_head
= DWARF_UNW_CACHE_SIZE
- 1;
519 for (i
= 0; i
< DWARF_UNW_CACHE_SIZE
; ++i
)
522 cache
->buckets
[i
].lru_chain
= (i
- 1);
523 cache
->buckets
[i
].coll_chain
= -1;
524 cache
->buckets
[i
].ip
= 0;
525 cache
->buckets
[i
].valid
= 0;
527 for (i
= 0; i
<DWARF_UNW_HASH_SIZE
; ++i
)
531 static inline struct dwarf_rs_cache
*
532 get_rs_cache (unw_addr_space_t as
, intrmask_t
*saved_maskp
)
534 struct dwarf_rs_cache
*cache
= &as
->global_cache
;
535 unw_caching_policy_t caching
= as
->caching_policy
;
537 if (caching
== UNW_CACHE_NONE
)
540 if (likely (caching
== UNW_CACHE_GLOBAL
))
542 Debug (16, "acquiring lock\n");
543 lock_acquire (&cache
->lock
, *saved_maskp
);
546 if (atomic_read (&as
->cache_generation
) != atomic_read (&cache
->generation
))
548 flush_rs_cache (cache
);
549 cache
->generation
= as
->cache_generation
;
556 put_rs_cache (unw_addr_space_t as
, struct dwarf_rs_cache
*cache
,
557 intrmask_t
*saved_maskp
)
559 assert (as
->caching_policy
!= UNW_CACHE_NONE
);
561 Debug (16, "unmasking signals/interrupts and releasing lock\n");
562 if (likely (as
->caching_policy
== UNW_CACHE_GLOBAL
))
563 lock_release (&cache
->lock
, *saved_maskp
);
566 static inline unw_hash_index_t CONST_ATTR
569 /* based on (sqrt(5)/2-1)*2^64 */
570 # define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL)
572 return ip
* magic
>> ((sizeof(unw_word_t
) * 8) - DWARF_LOG_UNW_HASH_SIZE
);
576 cache_match (dwarf_reg_state_t
*rs
, unw_word_t ip
)
578 if (rs
->valid
&& (ip
== rs
->ip
))
583 static dwarf_reg_state_t
*
584 rs_lookup (struct dwarf_rs_cache
*cache
, struct dwarf_cursor
*c
)
586 dwarf_reg_state_t
*rs
= cache
->buckets
+ c
->hint
;
587 unsigned short index
;
592 if (cache_match (rs
, ip
))
595 index
= cache
->hash
[hash (ip
)];
596 if (index
>= DWARF_UNW_CACHE_SIZE
)
599 rs
= cache
->buckets
+ index
;
602 if (cache_match (rs
, ip
))
604 /* update hint; no locking needed: single-word writes are atomic */
605 c
->hint
= cache
->buckets
[c
->prev_rs
].hint
=
606 (rs
- cache
->buckets
);
609 if (rs
->coll_chain
>= DWARF_UNW_HASH_SIZE
)
611 rs
= cache
->buckets
+ rs
->coll_chain
;
615 static inline dwarf_reg_state_t
*
616 rs_new (struct dwarf_rs_cache
*cache
, struct dwarf_cursor
* c
)
618 dwarf_reg_state_t
*rs
, *prev
, *tmp
;
619 unw_hash_index_t index
;
622 head
= cache
->lru_head
;
623 rs
= cache
->buckets
+ head
;
624 cache
->lru_head
= rs
->lru_chain
;
626 /* re-insert rs at the tail of the LRU chain: */
627 cache
->buckets
[cache
->lru_tail
].lru_chain
= head
;
628 cache
->lru_tail
= head
;
630 /* remove the old rs from the hash table (if it's there): */
633 index
= hash (rs
->ip
);
634 tmp
= cache
->buckets
+ cache
->hash
[index
];
641 prev
->coll_chain
= tmp
->coll_chain
;
643 cache
->hash
[index
] = tmp
->coll_chain
;
648 if (tmp
->coll_chain
>= DWARF_UNW_CACHE_SIZE
)
649 /* old rs wasn't in the hash-table */
651 tmp
= cache
->buckets
+ tmp
->coll_chain
;
655 /* enter new rs in the hash table */
656 index
= hash (c
->ip
);
657 rs
->coll_chain
= cache
->hash
[index
];
658 cache
->hash
[index
] = rs
- cache
->buckets
;
663 rs
->ret_addr_column
= c
->ret_addr_column
;
664 rs
->signal_frame
= 0;
665 tdep_cache_frame (c
, rs
);
671 create_state_record_for (struct dwarf_cursor
*c
, dwarf_state_record_t
*sr
,
676 assert (c
->pi_valid
);
678 memset (sr
, 0, sizeof (*sr
));
679 for (i
= 0; i
< DWARF_NUM_PRESERVED_REGS
+ 2; ++i
)
680 set_reg (sr
, i
, DWARF_WHERE_SAME
, 0);
682 switch (c
->pi
.format
)
684 case UNW_INFO_FORMAT_TABLE
:
685 case UNW_INFO_FORMAT_REMOTE_TABLE
:
686 ret
= parse_fde (c
, ip
, sr
);
689 case UNW_INFO_FORMAT_DYNAMIC
:
690 ret
= parse_dynamic (c
, ip
, sr
);
694 Debug (1, "Unexpected unwind-info format %d\n", c
->pi
.format
);
701 eval_location_expr (struct dwarf_cursor
*c
, unw_addr_space_t as
,
702 unw_accessors_t
*a
, unw_word_t addr
,
703 dwarf_loc_t
*locp
, void *arg
)
705 int ret
, is_register
;
708 /* read the length of the expression: */
709 if ((ret
= dwarf_read_uleb128 (as
, a
, &addr
, &len
, arg
)) < 0)
712 /* evaluate the expression: */
713 if ((ret
= dwarf_eval_expr (c
, &addr
, len
, &val
, &is_register
)) < 0)
717 *locp
= DWARF_REG_LOC (c
, dwarf_to_unw_regnum (val
));
719 *locp
= DWARF_MEM_LOC (c
, val
);
725 apply_reg_state (struct dwarf_cursor
*c
, struct dwarf_reg_state
*rs
)
727 unw_word_t regnum
, addr
, cfa
, ip
;
728 unw_word_t prev_ip
, prev_cfa
;
740 a
= unw_get_accessors (as
);
742 /* Evaluate the CFA first, because it may be referred to by other
745 if (rs
->reg
[DWARF_CFA_REG_COLUMN
].where
== DWARF_WHERE_REG
)
747 /* CFA is equal to [reg] + offset: */
749 /* As a special-case, if the stack-pointer is the CFA and the
750 stack-pointer wasn't saved, popping the CFA implicitly pops
751 the stack-pointer as well. */
752 if ((rs
->reg
[DWARF_CFA_REG_COLUMN
].val
== UNW_TDEP_SP
)
753 && (UNW_TDEP_SP
< ARRAY_SIZE(rs
->reg
))
754 && (rs
->reg
[UNW_TDEP_SP
].where
== DWARF_WHERE_SAME
))
758 regnum
= dwarf_to_unw_regnum (rs
->reg
[DWARF_CFA_REG_COLUMN
].val
);
759 if ((ret
= unw_get_reg ((unw_cursor_t
*) c
, regnum
, &cfa
)) < 0)
762 cfa
+= rs
->reg
[DWARF_CFA_OFF_COLUMN
].val
;
766 /* CFA is equal to EXPR: */
768 assert (rs
->reg
[DWARF_CFA_REG_COLUMN
].where
== DWARF_WHERE_EXPR
);
770 addr
= rs
->reg
[DWARF_CFA_REG_COLUMN
].val
;
771 if ((ret
= eval_location_expr (c
, as
, a
, addr
, &cfa_loc
, arg
)) < 0)
773 /* the returned location better be a memory location... */
774 if (DWARF_IS_REG_LOC (cfa_loc
))
775 return -UNW_EBADFRAME
;
776 cfa
= DWARF_GET_LOC (cfa_loc
);
779 for (i
= 0; i
< DWARF_NUM_PRESERVED_REGS
; ++i
)
781 switch ((dwarf_where_t
) rs
->reg
[i
].where
)
783 case DWARF_WHERE_UNDEF
:
784 c
->loc
[i
] = DWARF_NULL_LOC
;
787 case DWARF_WHERE_SAME
:
790 case DWARF_WHERE_CFAREL
:
791 c
->loc
[i
] = DWARF_MEM_LOC (c
, cfa
+ rs
->reg
[i
].val
);
794 case DWARF_WHERE_REG
:
795 c
->loc
[i
] = DWARF_REG_LOC (c
, dwarf_to_unw_regnum (rs
->reg
[i
].val
));
798 case DWARF_WHERE_EXPR
:
799 addr
= rs
->reg
[i
].val
;
800 if ((ret
= eval_location_expr (c
, as
, a
, addr
, c
->loc
+ i
, arg
)) < 0)
804 case DWARF_WHERE_VAL_EXPR
:
805 addr
= rs
->reg
[i
].val
;
806 if ((ret
= eval_location_expr (c
, as
, a
, addr
, c
->loc
+ i
, arg
)) < 0)
808 c
->loc
[i
] = DWARF_VAL_LOC (c
, DWARF_GET_LOC (c
->loc
[i
]));
814 /* DWARF spec says undefined return address location means end of stack. */
815 if (DWARF_IS_NULL_LOC (c
->loc
[c
->ret_addr_column
]))
819 ret
= dwarf_get (c
, c
->loc
[c
->ret_addr_column
], &ip
);
825 /* XXX: check for ip to be code_aligned */
826 if (c
->ip
== prev_ip
&& c
->cfa
== prev_cfa
)
828 Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n",
829 __FUNCTION__
, (long) c
->ip
);
830 return -UNW_EBADFRAME
;
834 tdep_stash_frame (c
, rs
);
840 uncached_dwarf_find_save_locs (struct dwarf_cursor
*c
)
842 dwarf_state_record_t sr
;
845 if ((ret
= fetch_proc_info (c
, c
->ip
, 1)) < 0)
847 put_unwind_info (c
, &c
->pi
);
851 if ((ret
= create_state_record_for (c
, &sr
, c
->ip
)) < 0)
854 if ((ret
= apply_reg_state (c
, &sr
.rs_current
)) < 0)
857 put_unwind_info (c
, &c
->pi
);
861 /* The function finds the saved locations and applies the register
864 dwarf_find_save_locs (struct dwarf_cursor
*c
)
866 dwarf_state_record_t sr
;
867 dwarf_reg_state_t
*rs
, rs_copy
;
868 struct dwarf_rs_cache
*cache
;
870 intrmask_t saved_mask
;
872 if (c
->as
->caching_policy
== UNW_CACHE_NONE
)
873 return uncached_dwarf_find_save_locs (c
);
875 cache
= get_rs_cache(c
->as
, &saved_mask
);
876 rs
= rs_lookup(cache
, c
);
880 c
->ret_addr_column
= rs
->ret_addr_column
;
881 c
->use_prev_instr
= ! rs
->signal_frame
;
885 if ((ret
= fetch_proc_info (c
, c
->ip
, 1)) < 0 ||
886 (ret
= create_state_record_for (c
, &sr
, c
->ip
)) < 0)
888 put_rs_cache (c
->as
, cache
, &saved_mask
);
889 put_unwind_info (c
, &c
->pi
);
893 rs
= rs_new (cache
, c
);
894 memcpy(rs
, &sr
.rs_current
, offsetof(struct dwarf_reg_state
, ip
));
895 cache
->buckets
[c
->prev_rs
].hint
= rs
- cache
->buckets
;
898 c
->prev_rs
= rs
- cache
->buckets
;
900 put_unwind_info (c
, &c
->pi
);
903 memcpy (&rs_copy
, rs
, sizeof (rs_copy
));
904 put_rs_cache (c
->as
, cache
, &saved_mask
);
906 tdep_reuse_frame (c
, &rs_copy
);
907 if ((ret
= apply_reg_state (c
, &rs_copy
)) < 0)
913 /* The proc-info must be valid for IP before this routine can be
916 dwarf_create_state_record (struct dwarf_cursor
*c
, dwarf_state_record_t
*sr
)
918 return create_state_record_for (c
, sr
, c
->ip
);
922 dwarf_make_proc_info (struct dwarf_cursor
*c
)
925 if (c
->as
->caching_policy
== UNW_CACHE_NONE
926 || get_cached_proc_info (c
) < 0)
928 /* Lookup it up the slow way... */
929 return fetch_proc_info (c
, c
->ip
, 0);