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>
4
5This file is part of libunwind.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
25
26#include <stddef.h>
27#include "dwarf_i.h"
28#include "libunwind_i.h"
29
30#define alloc_reg_state()	(mempool_alloc (&dwarf_reg_state_pool))
31#define free_reg_state(rs)	(mempool_free (&dwarf_reg_state_pool, rs))
32
33static inline int
34read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
35	     unw_word_t *valp, void *arg)
36{
37  int ret;
38
39  if ((ret = dwarf_read_uleb128 (as, a, addr, valp, arg)) < 0)
40    return ret;
41
42  if (*valp >= DWARF_NUM_PRESERVED_REGS)
43    {
44      Debug (1, "Invalid register number %u\n", (unsigned int) *valp);
45      return -UNW_EBADREG;
46    }
47  return 0;
48}
49
50static inline void
51set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where,
52	 unw_word_t val)
53{
54  sr->rs_current.reg[regnum].where = where;
55  sr->rs_current.reg[regnum].val = val;
56}
57
58/* Run a CFI program to update the register state.  */
59static int
60run_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)
63{
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;
66  unw_addr_space_t as;
67  unw_accessors_t *a;
68  uint8_t u8, op;
69  uint16_t u16;
70  uint32_t u32;
71  void *arg;
72  int ret;
73
74  as = c->as;
75  arg = c->as_arg;
76  if (c->pi.flags & UNW_PI_FLAG_DEBUG_FRAME)
77    {
78      /* .debug_frame CFI is stored in local address space.  */
79      as = unw_local_addr_space;
80      arg = NULL;
81    }
82  a = unw_get_accessors (as);
83  curr_ip = c->pi.start_ip;
84
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)
89    {
90      if ((ret = dwarf_readu8 (as, a, addr, &op, arg)) < 0)
91	return ret;
92
93      if (op & DWARF_CFA_OPCODE_MASK)
94	{
95	  operand = op & DWARF_CFA_OPERAND_MASK;
96	  op &= ~DWARF_CFA_OPERAND_MASK;
97	}
98      switch ((dwarf_cfa_t) op)
99	{
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);
103	  break;
104
105	case DW_CFA_advance_loc1:
106	  if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0)
107	    goto fail;
108	  curr_ip += u8 * dci->code_align;
109	  Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip);
110	  break;
111
112	case DW_CFA_advance_loc2:
113	  if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0)
114	    goto fail;
115	  curr_ip += u16 * dci->code_align;
116	  Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip);
117	  break;
118
119	case DW_CFA_advance_loc4:
120	  if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0)
121	    goto fail;
122	  curr_ip += u32 * dci->code_align;
123	  Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip);
124	  break;
125
126	case DW_CFA_MIPS_advance_loc8:
127#ifdef UNW_TARGET_MIPS
128	  {
129	    uint64_t u64;
130
131	    if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0)
132	      goto fail;
133	    curr_ip += u64 * dci->code_align;
134	    Debug (15, "CFA_MIPS_advance_loc8\n");
135	    break;
136	  }
137#else
138	  Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n");
139	  ret = -UNW_EINVAL;
140	  goto fail;
141#endif
142
143	case DW_CFA_offset:
144	  regnum = operand;
145	  if (regnum >= DWARF_NUM_PRESERVED_REGS)
146	    {
147	      Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n",
148		     (unsigned int) regnum);
149	      ret = -UNW_EBADREG;
150	      goto fail;
151	    }
152	  if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
153	    goto fail;
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));
157	  break;
158
159	case DW_CFA_offset_extended:
160	  if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
161	      || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
162	    goto fail;
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));
166	  break;
167
168	case DW_CFA_offset_extended_sf:
169	  if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
170	      || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0))
171	    goto fail;
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));
175	  break;
176
177	case DW_CFA_restore:
178	  regnum = operand;
179	  if (regnum >= DWARF_NUM_PRESERVED_REGS)
180	    {
181	      Debug (1, "Invalid register number %u in DW_CFA_restore\n",
182		     (unsigned int) regnum);
183	      ret = -UNW_EINVAL;
184	      goto fail;
185	    }
186	  sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum];
187	  Debug (15, "CFA_restore r%lu\n", (long) regnum);
188	  break;
189
190	case DW_CFA_restore_extended:
191	  if ((ret = dwarf_read_uleb128 (as, a, addr, &regnum, arg)) < 0)
192	    goto fail;
193	  if (regnum >= DWARF_NUM_PRESERVED_REGS)
194	    {
195	      Debug (1, "Invalid register number %u in "
196		     "DW_CFA_restore_extended\n", (unsigned int) regnum);
197	      ret = -UNW_EINVAL;
198	      goto fail;
199	    }
200	  sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum];
201	  Debug (15, "CFA_restore_extended r%lu\n", (long) regnum);
202	  break;
203
204	case DW_CFA_nop:
205	  break;
206
207	case DW_CFA_set_loc:
208	  fde_encoding = dci->fde_encoding;
209	  if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding,
210						 &c->pi, &curr_ip,
211						 arg)) < 0)
212	    goto fail;
213	  Debug (15, "CFA_set_loc to 0x%lx\n", (long) curr_ip);
214	  break;
215
216	case DW_CFA_undefined:
217	  if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
218	    goto fail;
219	  set_reg (sr, regnum, DWARF_WHERE_UNDEF, 0);
220	  Debug (15, "CFA_undefined r%lu\n", (long) regnum);
221	  break;
222
223	case DW_CFA_same_value:
224	  if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
225	    goto fail;
226	  set_reg (sr, regnum, DWARF_WHERE_SAME, 0);
227	  Debug (15, "CFA_same_value r%lu\n", (long) regnum);
228	  break;
229
230	case DW_CFA_register:
231	  if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
232	      || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
233	    goto fail;
234	  set_reg (sr, regnum, DWARF_WHERE_REG, val);
235	  Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum, (long) val);
236	  break;
237
238	case DW_CFA_remember_state:
239	  new_rs = alloc_reg_state ();
240	  if (!new_rs)
241	    {
242	      Debug (1, "Out of memory in DW_CFA_remember_state\n");
243	      ret = -UNW_ENOMEM;
244	      goto fail;
245	    }
246
247	  memcpy (new_rs->reg, sr->rs_current.reg, sizeof (new_rs->reg));
248	  new_rs->next = rs_stack;
249	  rs_stack = new_rs;
250	  Debug (15, "CFA_remember_state\n");
251	  break;
252
253	case DW_CFA_restore_state:
254	  if (!rs_stack)
255	    {
256	      Debug (1, "register-state stack underflow\n");
257	      ret = -UNW_EINVAL;
258	      goto fail;
259	    }
260	  memcpy (&sr->rs_current.reg, &rs_stack->reg, sizeof (rs_stack->reg));
261	  old_rs = rs_stack;
262	  rs_stack = rs_stack->next;
263	  free_reg_state (old_rs);
264	  Debug (15, "CFA_restore_state\n");
265	  break;
266
267	case DW_CFA_def_cfa:
268	  if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
269	      || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
270	    goto fail;
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);
274	  break;
275
276	case DW_CFA_def_cfa_sf:
277	  if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
278	      || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0))
279	    goto fail;
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));
285	  break;
286
287	case DW_CFA_def_cfa_register:
288	  if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
289	    goto fail;
290	  set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum);
291	  Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum);
292	  break;
293
294	case DW_CFA_def_cfa_offset:
295	  if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
296	    goto fail;
297	  set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val);	/* NOT factored! */
298	  Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val);
299	  break;
300
301	case DW_CFA_def_cfa_offset_sf:
302	  if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)
303	    goto fail;
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));
308	  break;
309
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);
313
314	  if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0)
315	    goto fail;
316
317	  Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n",
318		 (long) *addr, (long) len);
319	  *addr += len;
320	  break;
321
322	case DW_CFA_expression:
323	  if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
324	    goto fail;
325
326	  /* Save the address of the DW_FORM_block for later evaluation. */
327	  set_reg (sr, regnum, DWARF_WHERE_EXPR, *addr);
328
329	  if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0)
330	    goto fail;
331
332	  Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n",
333		 (long) regnum, (long) addr, (long) len);
334	  *addr += len;
335	  break;
336
337	case DW_CFA_GNU_args_size:
338	  if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
339	    goto fail;
340	  sr->args_size = val;
341	  Debug (15, "CFA_GNU_args_size %lu\n", (long) val);
342	  break;
343
344	case DW_CFA_GNU_negative_offset_extended:
345	  /* A comment in GCC says that this is obsoleted by
346	     DW_CFA_offset_extended_sf, but that it's used by older
347	     PowerPC code.  */
348	  if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
349	      || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
350	    goto fail;
351	  set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align));
352	  Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n",
353		 (long) -(val * dci->data_align));
354	  break;
355
356	case DW_CFA_GNU_window_save:
357#ifdef UNW_TARGET_SPARC
358	  /* This is a special CFA to handle all 16 windowed registers
359	     on SPARC.  */
360	  for (regnum = 16; regnum < 32; ++regnum)
361	    set_reg (sr, regnum, DWARF_WHERE_CFAREL,
362		     (regnum - 16) * sizeof (unw_word_t));
363	  Debug (15, "CFA_GNU_window_save\n");
364	  break;
365#else
366	  /* FALL THROUGH */
367#endif
368	case DW_CFA_lo_user:
369	case DW_CFA_hi_user:
370	  Debug (1, "Unexpected CFA opcode 0x%x\n", op);
371	  ret = -UNW_EINVAL;
372	  goto fail;
373	}
374    }
375  ret = 0;
376
377 fail:
378  /* Free the register-state stack, if not empty already.  */
379  while (rs_stack)
380    {
381      old_rs = rs_stack;
382      rs_stack = rs_stack->next;
383      free_reg_state (old_rs);
384    }
385  return ret;
386}
387
388static int
389fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip, int need_unwind_info)
390{
391  int ret, dynamic = 1;
392
393  /* The 'ip' can point either to the previous or next instruction
394     depending on what type of frame we have: normal call or a place
395     to resume execution (e.g. after signal frame).
396
397     For a normal call frame we need to back up so we point within the
398     call itself; this is important because a) the call might be the
399     very last instruction of the function and the edge of the FDE,
400     and b) so that run_cfi_program() runs locations up to the call
401     but not more.
402
403     For execution resume, we need to do the exact opposite and look
404     up using the current 'ip' value.  That is where execution will
405     continue, and it's important we get this right, as 'ip' could be
406     right at the function entry and hence FDE edge, or at instruction
407     that manipulates CFA (push/pop). */
408  if (c->use_prev_instr)
409    --ip;
410
411  if (c->pi_valid && !need_unwind_info)
412    return 0;
413
414  memset (&c->pi, 0, sizeof (c->pi));
415
416  /* check dynamic info first --- it overrides everything else */
417  ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info,
418				     c->as_arg);
419  if (ret == -UNW_ENOINFO)
420    {
421      dynamic = 0;
422      if ((ret = tdep_find_proc_info (c, ip, need_unwind_info)) < 0)
423	return ret;
424    }
425
426  if (c->pi.format != UNW_INFO_FORMAT_DYNAMIC
427      && c->pi.format != UNW_INFO_FORMAT_TABLE
428      && c->pi.format != UNW_INFO_FORMAT_REMOTE_TABLE)
429    return -UNW_ENOINFO;
430
431  c->pi_valid = 1;
432  c->pi_is_dynamic = dynamic;
433
434  /* Let system/machine-dependent code determine frame-specific attributes. */
435  if (ret >= 0)
436    tdep_fetch_frame (c, ip, need_unwind_info);
437
438  /* Update use_prev_instr for the next frame. */
439  if (need_unwind_info)
440  {
441    assert(c->pi.unwind_info);
442    struct dwarf_cie_info *dci = c->pi.unwind_info;
443    c->use_prev_instr = ! dci->signal_frame;
444  }
445
446  return ret;
447}
448
449static int
450parse_dynamic (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr)
451{
452  Debug (1, "Not yet implemented\n");
453#if 0
454  /* Don't forget to set the ret_addr_column!  */
455  c->ret_addr_column = XXX;
456#endif
457  return -UNW_ENOINFO;
458}
459
460static inline void
461put_unwind_info (struct dwarf_cursor *c, unw_proc_info_t *pi)
462{
463  if (c->pi_is_dynamic)
464    unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg);
465  else if (pi->unwind_info && pi->format == UNW_INFO_FORMAT_TABLE)
466    {
467      mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
468      pi->unwind_info = NULL;
469    }
470}
471
472static inline int
473parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr)
474{
475  struct dwarf_cie_info *dci;
476  unw_word_t addr;
477  int ret;
478
479  dci = c->pi.unwind_info;
480  c->ret_addr_column = dci->ret_addr_column;
481
482  addr = dci->cie_instr_start;
483  if ((ret = run_cfi_program (c, sr, ~(unw_word_t) 0, &addr,
484			      dci->cie_instr_end, dci)) < 0)
485    return ret;
486
487  memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial));
488
489  addr = dci->fde_instr_start;
490  if ((ret = run_cfi_program (c, sr, ip, &addr, dci->fde_instr_end, dci)) < 0)
491    return ret;
492
493  return 0;
494}
495
496static inline void
497flush_rs_cache (struct dwarf_rs_cache *cache)
498{
499  int i;
500
501  cache->lru_head = DWARF_UNW_CACHE_SIZE - 1;
502  cache->lru_tail = 0;
503
504  for (i = 0; i < DWARF_UNW_CACHE_SIZE; ++i)
505    {
506      if (i > 0)
507	cache->buckets[i].lru_chain = (i - 1);
508      cache->buckets[i].coll_chain = -1;
509      cache->buckets[i].ip = 0;
510      cache->buckets[i].valid = 0;
511    }
512  for (i = 0; i<DWARF_UNW_HASH_SIZE; ++i)
513    cache->hash[i] = -1;
514}
515
516static inline struct dwarf_rs_cache *
517get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
518{
519  struct dwarf_rs_cache *cache = &as->global_cache;
520  unw_caching_policy_t caching = as->caching_policy;
521
522  if (caching == UNW_CACHE_NONE)
523    return NULL;
524
525  if (likely (caching == UNW_CACHE_GLOBAL))
526    {
527      Debug (16, "acquiring lock\n");
528      lock_acquire (&cache->lock, *saved_maskp);
529    }
530
531  if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation))
532    {
533      flush_rs_cache (cache);
534      cache->generation = as->cache_generation;
535    }
536
537  return cache;
538}
539
540static inline void
541put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache,
542		  intrmask_t *saved_maskp)
543{
544  assert (as->caching_policy != UNW_CACHE_NONE);
545
546  Debug (16, "unmasking signals/interrupts and releasing lock\n");
547  if (likely (as->caching_policy == UNW_CACHE_GLOBAL))
548    lock_release (&cache->lock, *saved_maskp);
549}
550
551static inline unw_hash_index_t CONST_ATTR
552hash (unw_word_t ip)
553{
554  /* based on (sqrt(5)/2-1)*2^64 */
555# define magic	((unw_word_t) 0x9e3779b97f4a7c16ULL)
556
557  return ip * magic >> ((sizeof(unw_word_t) * 8) - DWARF_LOG_UNW_HASH_SIZE);
558}
559
560static inline long
561cache_match (dwarf_reg_state_t *rs, unw_word_t ip)
562{
563  if (rs->valid && (ip == rs->ip))
564    return 1;
565  return 0;
566}
567
568static dwarf_reg_state_t *
569rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c)
570{
571  dwarf_reg_state_t *rs = cache->buckets + c->hint;
572  unsigned short index;
573  unw_word_t ip;
574
575  ip = c->ip;
576
577  if (cache_match (rs, ip))
578    return rs;
579
580  index = cache->hash[hash (ip)];
581  if (index >= DWARF_UNW_CACHE_SIZE)
582    return NULL;
583
584  rs = cache->buckets + index;
585  while (1)
586    {
587      if (cache_match (rs, ip))
588        {
589          /* update hint; no locking needed: single-word writes are atomic */
590          c->hint = cache->buckets[c->prev_rs].hint =
591            (rs - cache->buckets);
592          return rs;
593        }
594      if (rs->coll_chain >= DWARF_UNW_HASH_SIZE)
595        return NULL;
596      rs = cache->buckets + rs->coll_chain;
597    }
598}
599
600static inline dwarf_reg_state_t *
601rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c)
602{
603  dwarf_reg_state_t *rs, *prev, *tmp;
604  unw_hash_index_t index;
605  unsigned short head;
606
607  head = cache->lru_head;
608  rs = cache->buckets + head;
609  cache->lru_head = rs->lru_chain;
610
611  /* re-insert rs at the tail of the LRU chain: */
612  cache->buckets[cache->lru_tail].lru_chain = head;
613  cache->lru_tail = head;
614
615  /* remove the old rs from the hash table (if it's there): */
616  if (rs->ip)
617    {
618      index = hash (rs->ip);
619      tmp = cache->buckets + cache->hash[index];
620      prev = NULL;
621      while (1)
622	{
623	  if (tmp == rs)
624	    {
625	      if (prev)
626		prev->coll_chain = tmp->coll_chain;
627	      else
628		cache->hash[index] = tmp->coll_chain;
629	      break;
630	    }
631	  else
632	    prev = tmp;
633	  if (tmp->coll_chain >= DWARF_UNW_CACHE_SIZE)
634	    /* old rs wasn't in the hash-table */
635	    break;
636	  tmp = cache->buckets + tmp->coll_chain;
637	}
638    }
639
640  /* enter new rs in the hash table */
641  index = hash (c->ip);
642  rs->coll_chain = cache->hash[index];
643  cache->hash[index] = rs - cache->buckets;
644
645  rs->hint = 0;
646  rs->ip = c->ip;
647  rs->valid = 1;
648  rs->ret_addr_column = c->ret_addr_column;
649  rs->signal_frame = 0;
650  tdep_cache_frame (c, rs);
651
652  return rs;
653}
654
655static int
656create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr,
657			 unw_word_t ip)
658{
659  int i, ret;
660
661  assert (c->pi_valid);
662
663  memset (sr, 0, sizeof (*sr));
664  for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i)
665    set_reg (sr, i, DWARF_WHERE_SAME, 0);
666
667  switch (c->pi.format)
668    {
669    case UNW_INFO_FORMAT_TABLE:
670    case UNW_INFO_FORMAT_REMOTE_TABLE:
671      ret = parse_fde (c, ip, sr);
672      break;
673
674    case UNW_INFO_FORMAT_DYNAMIC:
675      ret = parse_dynamic (c, ip, sr);
676      break;
677
678    default:
679      Debug (1, "Unexpected unwind-info format %d\n", c->pi.format);
680      ret = -UNW_EINVAL;
681    }
682  return ret;
683}
684
685static inline int
686eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as,
687		    unw_accessors_t *a, unw_word_t addr,
688		    dwarf_loc_t *locp, void *arg)
689{
690  int ret, is_register;
691  unw_word_t len, val;
692
693  /* read the length of the expression: */
694  if ((ret = dwarf_read_uleb128 (as, a, &addr, &len, arg)) < 0)
695    return ret;
696
697  /* evaluate the expression: */
698  if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0)
699    return ret;
700
701  if (is_register)
702    *locp = DWARF_REG_LOC (c, dwarf_to_unw_regnum (val));
703  else
704    *locp = DWARF_MEM_LOC (c, val);
705
706  return 0;
707}
708
709static int
710apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
711{
712  unw_word_t regnum, addr, cfa, ip;
713  unw_word_t prev_ip, prev_cfa;
714  unw_addr_space_t as;
715  dwarf_loc_t cfa_loc;
716  unw_accessors_t *a;
717  int i, ret;
718  void *arg;
719
720  prev_ip = c->ip;
721  prev_cfa = c->cfa;
722
723  as = c->as;
724  arg = c->as_arg;
725  a = unw_get_accessors (as);
726
727  /* Evaluate the CFA first, because it may be referred to by other
728     expressions.  */
729
730  if (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG)
731    {
732      /* CFA is equal to [reg] + offset: */
733
734      /* As a special-case, if the stack-pointer is the CFA and the
735	 stack-pointer wasn't saved, popping the CFA implicitly pops
736	 the stack-pointer as well.  */
737      if ((rs->reg[DWARF_CFA_REG_COLUMN].val == UNW_TDEP_SP)
738          && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg))
739	  && (rs->reg[UNW_TDEP_SP].where == DWARF_WHERE_SAME))
740	  cfa = c->cfa;
741      else
742	{
743	  regnum = dwarf_to_unw_regnum (rs->reg[DWARF_CFA_REG_COLUMN].val);
744	  if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0)
745	    return ret;
746	}
747      cfa += rs->reg[DWARF_CFA_OFF_COLUMN].val;
748    }
749  else
750    {
751      /* CFA is equal to EXPR: */
752
753      assert (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_EXPR);
754
755      addr = rs->reg[DWARF_CFA_REG_COLUMN].val;
756      if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0)
757	return ret;
758      /* the returned location better be a memory location... */
759      if (DWARF_IS_REG_LOC (cfa_loc))
760	return -UNW_EBADFRAME;
761      cfa = DWARF_GET_LOC (cfa_loc);
762    }
763
764  for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
765    {
766      switch ((dwarf_where_t) rs->reg[i].where)
767	{
768	case DWARF_WHERE_UNDEF:
769	  c->loc[i] = DWARF_NULL_LOC;
770	  break;
771
772	case DWARF_WHERE_SAME:
773	  break;
774
775	case DWARF_WHERE_CFAREL:
776	  c->loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg[i].val);
777	  break;
778
779	case DWARF_WHERE_REG:
780	  c->loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg[i].val));
781	  break;
782
783	case DWARF_WHERE_EXPR:
784	  addr = rs->reg[i].val;
785	  if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0)
786	    return ret;
787	  break;
788	}
789    }
790
791  c->cfa = cfa;
792  /* DWARF spec says undefined return address location means end of stack. */
793  if (DWARF_IS_NULL_LOC (c->loc[c->ret_addr_column]))
794    c->ip = 0;
795  else
796  {
797    ret = dwarf_get (c, c->loc[c->ret_addr_column], &ip);
798    if (ret < 0)
799      return ret;
800    c->ip = ip;
801  }
802
803  /* XXX: check for ip to be code_aligned */
804  if (c->ip == prev_ip && c->cfa == prev_cfa)
805    {
806      Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n",
807	       __FUNCTION__, (long) c->ip);
808      return -UNW_EBADFRAME;
809    }
810
811  if (c->stash_frames)
812    tdep_stash_frame (c, rs);
813
814  return 0;
815}
816
817static int
818uncached_dwarf_find_save_locs (struct dwarf_cursor *c)
819{
820  dwarf_state_record_t sr;
821  int ret;
822
823  if ((ret = fetch_proc_info (c, c->ip, 1)) < 0)
824    {
825      put_unwind_info (c, &c->pi);
826      return ret;
827    }
828
829  if ((ret = create_state_record_for (c, &sr, c->ip)) < 0)
830    {
831      /* ANDROID support update. */
832      put_unwind_info (c, &c->pi);
833      /* End of ANDROID update. */
834      return ret;
835    }
836
837  if ((ret = apply_reg_state (c, &sr.rs_current)) < 0)
838    {
839      /* ANDROID support update. */
840      put_unwind_info (c, &c->pi);
841      /* End of ANDROID update. */
842      return ret;
843    }
844
845  put_unwind_info (c, &c->pi);
846  return 0;
847}
848
849/* The function finds the saved locations and applies the register
850   state as well. */
851HIDDEN int
852dwarf_find_save_locs (struct dwarf_cursor *c)
853{
854#if defined(CONSERVE_STACK)
855  dwarf_reg_state_t *rs_copy;
856#else
857  dwarf_reg_state_t rs_copy_stack;
858  dwarf_reg_state_t *rs_copy = &rs_copy_stack;
859#endif
860  dwarf_reg_state_t *rs;
861  struct dwarf_rs_cache *cache;
862  int ret = 0;
863  intrmask_t saved_mask;
864
865  if (c->as->caching_policy == UNW_CACHE_NONE)
866    return uncached_dwarf_find_save_locs (c);
867
868  cache = get_rs_cache(c->as, &saved_mask);
869  rs = rs_lookup(cache, c);
870
871  if (rs)
872    {
873      c->ret_addr_column = rs->ret_addr_column;
874      c->use_prev_instr = ! rs->signal_frame;
875    }
876  else
877    {
878#if !defined(CONSERVE_STACK)
879      dwarf_state_record_t sr_stack;
880      dwarf_state_record_t *sr = &sr_stack;
881#else
882      dwarf_state_record_t *sr = (dwarf_state_record_t*)malloc(sizeof(dwarf_state_record_t));
883
884      if (sr == NULL)
885        return -UNW_ENOMEM;
886#endif
887
888      if ((ret = fetch_proc_info (c, c->ip, 1)) < 0 ||
889	  (ret = create_state_record_for (c, sr, c->ip)) < 0)
890	{
891          put_rs_cache (c->as, cache, &saved_mask);
892          put_unwind_info (c, &c->pi);
893#if defined(CONSERVE_STACK)
894          free(sr);
895#endif
896	  return ret;
897	}
898
899      rs = rs_new (cache, c);
900      memcpy(rs, &sr->rs_current, offsetof(struct dwarf_reg_state, ip));
901      cache->buckets[c->prev_rs].hint = rs - cache->buckets;
902
903      c->hint = rs->hint;
904      c->prev_rs = rs - cache->buckets;
905
906      put_unwind_info (c, &c->pi);
907
908#if defined(CONSERVE_STACK)
909      free(sr);
910#endif
911    }
912
913#if defined(CONSERVE_STACK)
914  rs_copy = (dwarf_reg_state_t*)malloc(sizeof(dwarf_reg_state_t));
915  if (rs_copy == NULL)
916    return -UNW_ENOMEM;
917#endif
918
919  memcpy (rs_copy, rs, sizeof (*rs_copy));
920  put_rs_cache (c->as, cache, &saved_mask);
921
922  tdep_reuse_frame (c, rs_copy);
923  ret = apply_reg_state (c, rs_copy);
924
925#if defined(CONSERVE_STACK)
926  free(rs_copy);
927#endif
928
929  return ret;
930}
931
932/* The proc-info must be valid for IP before this routine can be
933   called.  */
934HIDDEN int
935dwarf_create_state_record (struct dwarf_cursor *c, dwarf_state_record_t *sr)
936{
937  return create_state_record_for (c, sr, c->ip);
938}
939
940HIDDEN int
941dwarf_make_proc_info (struct dwarf_cursor *c)
942{
943#if 0
944  if (c->as->caching_policy == UNW_CACHE_NONE
945      || get_cached_proc_info (c) < 0)
946#endif
947    /* Lookup it up the slow way... */
948    return fetch_proc_info (c, c->ip, 0);
949  return 0;
950}
951