unwind-dw2.c 46.8 KB
Newer Older
1
/* DWARF2 exception handling and frame unwind runtime interface routines.
2
   Copyright (C) 1997-2017 Free Software Foundation, Inc.
3

4
   This file is part of GCC.
5

6 7
   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9 10
   any later version.

11 12 13 14
   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.
15

16 17 18 19 20 21 22 23
   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */
24 25 26

#include "tconfig.h"
#include "tsystem.h"
27 28
#include "coretypes.h"
#include "tm.h"
29
#include "libgcc_tm.h"
30
#include "dwarf2.h"
31
#include "unwind.h"
32 33 34
#ifdef __USING_SJLJ_EXCEPTIONS__
# define NO_SIZE_OF_ENCODED_VALUE
#endif
35
#include "unwind-pe.h"
36 37
#include "unwind-dw2-fde.h"
#include "gthr.h"
Geoffrey Keating committed
38
#include "unwind-dw2.h"
39

40 41 42 43
#ifdef HAVE_SYS_SDT_H
#include <sys/sdt.h>
#endif

44
#ifndef __USING_SJLJ_EXCEPTIONS__
45

46 47
#ifndef __LIBGCC_STACK_GROWS_DOWNWARD__
#define __LIBGCC_STACK_GROWS_DOWNWARD__ 0
48
#else
49 50
#undef __LIBGCC_STACK_GROWS_DOWNWARD__
#define __LIBGCC_STACK_GROWS_DOWNWARD__ 1
51 52
#endif

53 54
/* Dwarf frame registers used for pre gcc 3.0 compiled glibc.  */
#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
55
#define PRE_GCC3_DWARF_FRAME_REGISTERS __LIBGCC_DWARF_FRAME_REGISTERS__
56 57
#endif

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
/* ??? For the public function interfaces, we tend to gcc_assert that the
   column numbers are in range.  For the dwarf2 unwind info this does happen,
   although so far in a case that doesn't actually matter.

   See PR49146, in which a call from x86_64 ms abi to x86_64 unix abi stores
   the call-saved xmm registers and annotates them.  We havn't bothered
   providing support for the xmm registers for the x86_64 port primarily
   because the 64-bit windows targets don't use dwarf2 unwind, using sjlj or
   SEH instead.  Adding the support for unix targets would generally be a
   waste.  However, some runtime libraries supplied with ICC do contain such
   an unorthodox transition, as well as the unwind info to match.  This loss
   of register restoration doesn't matter in practice, because the exception
   is caught in the native unix abi, where all of the xmm registers are 
   call clobbered.

   Ideally, we'd record some bit to notice when we're failing to restore some
   register recorded in the unwind info, but to do that we need annotation on
   the unix->ms abi edge, so that we know when the register data may be
   discarded.  And since this edge is also within the ICC library, we're
   unlikely to be able to get the new annotation.

   Barring a magic solution to restore the ms abi defined 128-bit xmm registers
   (as distictly opposed to the full runtime width) without causing extra
   overhead for normal unix abis, the best solution seems to be to simply
   ignore unwind data for unknown columns.  */

#define UNWIND_COLUMN_IN_RANGE(x) \
85
    __builtin_expect((x) <= __LIBGCC_DWARF_FRAME_REGISTERS__, 1)
86

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
#ifdef REG_VALUE_IN_UNWIND_CONTEXT
typedef _Unwind_Word _Unwind_Context_Reg_Val;

#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
#define ASSUME_EXTENDED_UNWIND_CONTEXT 1
#endif

static inline _Unwind_Word
_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
{
  return val;
}

static inline _Unwind_Context_Reg_Val
_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
{
  return val;
}
#else
typedef void *_Unwind_Context_Reg_Val;

static inline _Unwind_Word
_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
{
  return (_Unwind_Word) (_Unwind_Internal_Ptr) val;
}

static inline _Unwind_Context_Reg_Val
_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
{
  return (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) val;
}
#endif

#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
#define ASSUME_EXTENDED_UNWIND_CONTEXT 0
#endif

Jason Merrill committed
125 126 127
/* This is the register and unwind state for a particular frame.  This
   provides the information necessary to unwind up past a frame and return
   to its caller.  */
128 129
struct _Unwind_Context
{
130
  _Unwind_Context_Reg_Val reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
131 132 133 134
  void *cfa;
  void *ra;
  void *lsda;
  struct dwarf_eh_bases bases;
135 136 137 138
  /* Signal frame context.  */
#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
  /* Context which has version/args_size/by_value fields.  */
#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
139 140
  /* Bit reserved on AArch64, return address has been signed with A key.  */
#define RA_A_SIGNED_BIT ((~(_Unwind_Word) 0 >> 3) + 1)
141 142 143 144
  _Unwind_Word flags;
  /* 0 for now, can be increased when further fields are added to
     struct _Unwind_Context.  */
  _Unwind_Word version;
145
  _Unwind_Word args_size;
146
  char by_value[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
147 148 149
};

/* Byte size of every register managed by these routines.  */
150
static unsigned char dwarf_reg_size_table[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165


/* Read unaligned data from the instruction buffer.  */

union unaligned
{
  void *p;
  unsigned u2 __attribute__ ((mode (HI)));
  unsigned u4 __attribute__ ((mode (SI)));
  unsigned u8 __attribute__ ((mode (DI)));
  signed s2 __attribute__ ((mode (HI)));
  signed s4 __attribute__ ((mode (SI)));
  signed s8 __attribute__ ((mode (DI)));
} __attribute__ ((packed));

166 167 168 169
static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
					       _Unwind_FrameState *);

170
static inline void *
171
read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
172 173

static inline int
174
read_1u (const void *p) { return *(const unsigned char *) p; }
175 176

static inline int
177
read_1s (const void *p) { return *(const signed char *) p; }
178 179

static inline int
180
read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
181 182

static inline int
183
read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
184 185

static inline unsigned int
186
read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
187 188

static inline int
189
read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
190 191

static inline unsigned long
192
read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
193 194

static inline unsigned long
195
read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
196

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
static inline _Unwind_Word
_Unwind_IsSignalFrame (struct _Unwind_Context *context)
{
  return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
}

static inline void
_Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
{
  if (val)
    context->flags |= SIGNAL_FRAME_BIT;
  else
    context->flags &= ~SIGNAL_FRAME_BIT;
}

static inline _Unwind_Word
_Unwind_IsExtendedContext (struct _Unwind_Context *context)
{
215 216
  return (ASSUME_EXTENDED_UNWIND_CONTEXT
	  || (context->flags & EXTENDED_CONTEXT_BIT));
217 218
}

219
/* Get the value of register INDEX as saved in CONTEXT.  */
220 221 222 223

inline _Unwind_Word
_Unwind_GetGR (struct _Unwind_Context *context, int index)
{
224
  int size;
225
  _Unwind_Context_Reg_Val val;
226

227 228 229 230 231
#ifdef DWARF_ZERO_REG
  if (index == DWARF_ZERO_REG)
    return 0;
#endif

232
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
233
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
234
  size = dwarf_reg_size_table[index];
235
  val = context->reg[index];
236

237
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
238
    return _Unwind_Get_Unwind_Word (val);
239

240
  /* This will segfault if the register hasn't been saved.  */
241
  if (size == sizeof(_Unwind_Ptr))
242
    return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
243 244 245
  else
    {
      gcc_assert (size == sizeof(_Unwind_Word));
246
      return * (_Unwind_Word *) (_Unwind_Internal_Ptr) val;
247
    }
248 249 250 251 252 253
}

static inline void *
_Unwind_GetPtr (struct _Unwind_Context *context, int index)
{
  return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
254 255
}

256 257 258 259 260
/* Get the value of the CFA as saved in CONTEXT.  */

_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *context)
{
261
  return (_Unwind_Ptr) context->cfa;
262 263
}

264
/* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
265 266 267 268

inline void
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
{
269 270 271
  int size;
  void *ptr;

272
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
273
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
274
  size = dwarf_reg_size_table[index];
275

276
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
277
    {
278
      context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
279 280 281
      return;
    }

282
  ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
283 284 285 286

  if (size == sizeof(_Unwind_Ptr))
    * (_Unwind_Ptr *) ptr = val;
  else
287 288 289 290
    {
      gcc_assert (size == sizeof(_Unwind_Word));
      * (_Unwind_Word *) ptr = val;
    }
291 292
}

293 294 295 296 297 298
/* Get the pointer to a register INDEX as saved in CONTEXT.  */

static inline void *
_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
{
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
299
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
300
    return &context->reg[index];
301
  return (void *) (_Unwind_Internal_Ptr) context->reg[index];
302 303 304 305 306 307 308 309
}

/* Set the pointer to a register INDEX as saved in CONTEXT.  */

static inline void
_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
{
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
310 311
  if (_Unwind_IsExtendedContext (context))
    context->by_value[index] = 0;
312
  context->reg[index] = (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) p;
313 314
}

315 316 317 318 319 320 321 322
/* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */

static inline void
_Unwind_SetGRValue (struct _Unwind_Context *context, int index,
		    _Unwind_Word val)
{
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
323 324
  /* Return column size may be smaller than _Unwind_Context_Reg_Val.  */
  gcc_assert (dwarf_reg_size_table[index] <= sizeof (_Unwind_Context_Reg_Val));
325 326

  context->by_value[index] = 1;
327
  context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
328 329
}

330
/* Return nonzero if register INDEX is stored by value rather than
331 332 333 334 335 336 337 338 339
   by reference.  */

static inline int
_Unwind_GRByValue (struct _Unwind_Context *context, int index)
{
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
  return context->by_value[index];
}

340 341 342 343 344 345 346 347
/* Retrieve the return address for CONTEXT.  */

inline _Unwind_Ptr
_Unwind_GetIP (struct _Unwind_Context *context)
{
  return (_Unwind_Ptr) context->ra;
}

348 349 350 351 352 353
/* Retrieve the return address and flag whether that IP is before
   or after first not yet fully executed instruction.  */

inline _Unwind_Ptr
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
{
354
  *ip_before_insn = _Unwind_IsSignalFrame (context);
355 356 357
  return (_Unwind_Ptr) context->ra;
}

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
/* Overwrite the return address for CONTEXT with VAL.  */

inline void
_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
{
  context->ra = (void *) val;
}

void *
_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
{
  return context->lsda;
}

_Unwind_Ptr
_Unwind_GetRegionStart (struct _Unwind_Context *context)
{
  return (_Unwind_Ptr) context->bases.func;
}

378
void *
379
_Unwind_FindEnclosingFunction (void *pc)
380 381
{
  struct dwarf_eh_bases bases;
382
  const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
383 384 385 386 387 388
  if (fde)
    return bases.func;
  else
    return NULL;
}

389 390 391 392 393 394 395 396 397 398 399 400 401
#ifndef __ia64__
_Unwind_Ptr
_Unwind_GetDataRelBase (struct _Unwind_Context *context)
{
  return (_Unwind_Ptr) context->bases.dbase;
}

_Unwind_Ptr
_Unwind_GetTextRelBase (struct _Unwind_Context *context)
{
  return (_Unwind_Ptr) context->bases.tbase;
}
#endif
402

403
#include "md-unwind-support.h"
404 405 406 407 408

/* Extract any interesting information from the CIE for the translation
   unit F belongs to.  Return a pointer to the byte after the augmentation,
   or NULL if we encountered an undecipherable augmentation.  */

409
static const unsigned char *
410
extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
411 412
		  _Unwind_FrameState *fs)
{
413
  const unsigned char *aug = cie->augmentation;
414
  const unsigned char *p = aug + strlen ((const char *)aug) + 1;
415
  const unsigned char *ret = NULL;
416 417
  _uleb128_t utmp;
  _sleb128_t stmp;
418

419 420 421 422 423 424 425 426 427
  /* g++ v2 "eh" has pointer immediately following augmentation string,
     so it must be handled first.  */
  if (aug[0] == 'e' && aug[1] == 'h')
    {
      fs->eh_ptr = read_pointer (p);
      p += sizeof (void *);
      aug += 2;
    }

428 429 430 431 432 433 434 435 436 437
  /* After the augmentation resp. pointer for "eh" augmentation
     follows for CIE version >= 4 address size byte and
     segment size byte.  */
  if (__builtin_expect (cie->version >= 4, 0))
    {
      if (p[0] != sizeof (void *) || p[1] != 0)
	return NULL;
      p += 2;
    }
  /* Immediately following this are the code and
438
     data alignment and return address column.  */
439 440 441 442
  p = read_uleb128 (p, &utmp);
  fs->code_align = (_Unwind_Word)utmp;
  p = read_sleb128 (p, &stmp);
  fs->data_align = (_Unwind_Sword)stmp;
443 444 445
  if (cie->version == 1)
    fs->retaddr_column = *p++;
  else
446 447 448 449
    {
      p = read_uleb128 (p, &utmp);
      fs->retaddr_column = (_Unwind_Word)utmp;
    }
450
  fs->lsda_encoding = DW_EH_PE_omit;
451 452 453 454 455 456

  /* If the augmentation starts with 'z', then a uleb128 immediately
     follows containing the length of the augmentation field following
     the size.  */
  if (*aug == 'z')
    {
457 458
      p = read_uleb128 (p, &utmp);
      ret = p + utmp;
459 460 461 462 463 464 465 466

      fs->saw_z = 1;
      ++aug;
    }

  /* Iterate over recognized augmentation subsequences.  */
  while (*aug != '\0')
    {
467
      /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
468
      if (aug[0] == 'L')
469 470 471 472 473 474
	{
	  fs->lsda_encoding = *p++;
	  aug += 1;
	}

      /* "R" indicates a byte indicating how FDE addresses are encoded.  */
475 476
      else if (aug[0] == 'R')
	{
477
	  fs->fde_encoding = *p++;
478 479 480
	  aug += 1;
	}

481
      /* "P" indicates a personality routine in the CIE augmentation.  */
482 483
      else if (aug[0] == 'P')
	{
484
	  _Unwind_Ptr personality;
H.J. Lu committed
485

486 487
	  p = read_encoded_value (context, *p, p + 1, &personality);
	  fs->personality = (_Unwind_Personality_Fn) personality;
488 489 490
	  aug += 1;
	}

491 492 493 494 495 496 497
      /* "S" indicates a signal frame.  */
      else if (aug[0] == 'S')
	{
	  fs->signal_frame = 1;
	  aug += 1;
	}

498 499 500 501 502 503 504 505 506 507 508 509 510 511
      /* Otherwise we have an unknown augmentation string.
	 Bail unless we saw a 'z' prefix.  */
      else
	return ret;
    }

  return ret ? ret : p;
}


/* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
   onto the stack to start.  */

static _Unwind_Word
512
execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
513 514
		  struct _Unwind_Context *context, _Unwind_Word initial)
{
515
  _Unwind_Word stack[64];	/* ??? Assume this is enough.  */
516 517 518 519 520 521 522 523
  int stack_elt;

  stack[0] = initial;
  stack_elt = 1;

  while (op_ptr < op_end)
    {
      enum dwarf_location_atom op = *op_ptr++;
524 525 526
      _Unwind_Word result;
      _uleb128_t reg, utmp;
      _sleb128_t offset, stmp;
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569

      switch (op)
	{
	case DW_OP_lit0:
	case DW_OP_lit1:
	case DW_OP_lit2:
	case DW_OP_lit3:
	case DW_OP_lit4:
	case DW_OP_lit5:
	case DW_OP_lit6:
	case DW_OP_lit7:
	case DW_OP_lit8:
	case DW_OP_lit9:
	case DW_OP_lit10:
	case DW_OP_lit11:
	case DW_OP_lit12:
	case DW_OP_lit13:
	case DW_OP_lit14:
	case DW_OP_lit15:
	case DW_OP_lit16:
	case DW_OP_lit17:
	case DW_OP_lit18:
	case DW_OP_lit19:
	case DW_OP_lit20:
	case DW_OP_lit21:
	case DW_OP_lit22:
	case DW_OP_lit23:
	case DW_OP_lit24:
	case DW_OP_lit25:
	case DW_OP_lit26:
	case DW_OP_lit27:
	case DW_OP_lit28:
	case DW_OP_lit29:
	case DW_OP_lit30:
	case DW_OP_lit31:
	  result = op - DW_OP_lit0;
	  break;

	case DW_OP_addr:
	  result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
	  op_ptr += sizeof (void *);
	  break;

570 571 572 573 574 575 576 577
	case DW_OP_GNU_encoded_addr:
	  {
	    _Unwind_Ptr presult;
	    op_ptr = read_encoded_value (context, *op_ptr, op_ptr+1, &presult);
	    result = presult;
	  }
	  break;

578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
	case DW_OP_const1u:
	  result = read_1u (op_ptr);
	  op_ptr += 1;
	  break;
	case DW_OP_const1s:
	  result = read_1s (op_ptr);
	  op_ptr += 1;
	  break;
	case DW_OP_const2u:
	  result = read_2u (op_ptr);
	  op_ptr += 2;
	  break;
	case DW_OP_const2s:
	  result = read_2s (op_ptr);
	  op_ptr += 2;
	  break;
	case DW_OP_const4u:
	  result = read_4u (op_ptr);
	  op_ptr += 4;
	  break;
	case DW_OP_const4s:
	  result = read_4s (op_ptr);
	  op_ptr += 4;
	  break;
	case DW_OP_const8u:
	  result = read_8u (op_ptr);
	  op_ptr += 8;
	  break;
	case DW_OP_const8s:
	  result = read_8s (op_ptr);
	  op_ptr += 8;
	  break;
	case DW_OP_constu:
611 612
	  op_ptr = read_uleb128 (op_ptr, &utmp);
	  result = (_Unwind_Word)utmp;
613 614
	  break;
	case DW_OP_consts:
615
	  op_ptr = read_sleb128 (op_ptr, &stmp);
616
	  result = (_Unwind_Sword)stmp;
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
	  break;

	case DW_OP_reg0:
	case DW_OP_reg1:
	case DW_OP_reg2:
	case DW_OP_reg3:
	case DW_OP_reg4:
	case DW_OP_reg5:
	case DW_OP_reg6:
	case DW_OP_reg7:
	case DW_OP_reg8:
	case DW_OP_reg9:
	case DW_OP_reg10:
	case DW_OP_reg11:
	case DW_OP_reg12:
	case DW_OP_reg13:
	case DW_OP_reg14:
	case DW_OP_reg15:
	case DW_OP_reg16:
	case DW_OP_reg17:
	case DW_OP_reg18:
	case DW_OP_reg19:
	case DW_OP_reg20:
	case DW_OP_reg21:
	case DW_OP_reg22:
	case DW_OP_reg23:
	case DW_OP_reg24:
	case DW_OP_reg25:
	case DW_OP_reg26:
	case DW_OP_reg27:
	case DW_OP_reg28:
	case DW_OP_reg29:
	case DW_OP_reg30:
	case DW_OP_reg31:
	  result = _Unwind_GetGR (context, op - DW_OP_reg0);
	  break;
	case DW_OP_regx:
654
	  op_ptr = read_uleb128 (op_ptr, &reg);
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
	  result = _Unwind_GetGR (context, reg);
	  break;

	case DW_OP_breg0:
	case DW_OP_breg1:
	case DW_OP_breg2:
	case DW_OP_breg3:
	case DW_OP_breg4:
	case DW_OP_breg5:
	case DW_OP_breg6:
	case DW_OP_breg7:
	case DW_OP_breg8:
	case DW_OP_breg9:
	case DW_OP_breg10:
	case DW_OP_breg11:
	case DW_OP_breg12:
	case DW_OP_breg13:
	case DW_OP_breg14:
	case DW_OP_breg15:
	case DW_OP_breg16:
	case DW_OP_breg17:
	case DW_OP_breg18:
	case DW_OP_breg19:
	case DW_OP_breg20:
	case DW_OP_breg21:
	case DW_OP_breg22:
	case DW_OP_breg23:
	case DW_OP_breg24:
	case DW_OP_breg25:
	case DW_OP_breg26:
	case DW_OP_breg27:
	case DW_OP_breg28:
	case DW_OP_breg29:
	case DW_OP_breg30:
	case DW_OP_breg31:
690
	  op_ptr = read_sleb128 (op_ptr, &offset);
691 692 693
	  result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
	  break;
	case DW_OP_bregx:
694 695
	  op_ptr = read_uleb128 (op_ptr, &reg);
	  op_ptr = read_sleb128 (op_ptr, &offset);
696
	  result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
697 698 699
	  break;

	case DW_OP_dup:
700
	  gcc_assert (stack_elt);
701 702 703 704
	  result = stack[stack_elt - 1];
	  break;

	case DW_OP_drop:
705 706
	  gcc_assert (stack_elt);
	  stack_elt -= 1;
707 708 709 710
	  goto no_push;

	case DW_OP_pick:
	  offset = *op_ptr++;
711
	  gcc_assert (offset < stack_elt - 1);
712 713 714 715
	  result = stack[stack_elt - 1 - offset];
	  break;

	case DW_OP_over:
716
	  gcc_assert (stack_elt >= 2);
717 718 719
	  result = stack[stack_elt - 2];
	  break;

720 721 722 723 724 725 726 727 728 729
	case DW_OP_swap:
	  {
	    _Unwind_Word t;
	    gcc_assert (stack_elt >= 2);
	    t = stack[stack_elt - 1];
	    stack[stack_elt - 1] = stack[stack_elt - 2];
	    stack[stack_elt - 2] = t;
	    goto no_push;
	  }

730 731 732 733
	case DW_OP_rot:
	  {
	    _Unwind_Word t1, t2, t3;

734
	    gcc_assert (stack_elt >= 3);
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
	    t1 = stack[stack_elt - 1];
	    t2 = stack[stack_elt - 2];
	    t3 = stack[stack_elt - 3];
	    stack[stack_elt - 1] = t2;
	    stack[stack_elt - 2] = t3;
	    stack[stack_elt - 3] = t1;
	    goto no_push;
	  }

	case DW_OP_deref:
	case DW_OP_deref_size:
	case DW_OP_abs:
	case DW_OP_neg:
	case DW_OP_not:
	case DW_OP_plus_uconst:
	  /* Unary operations.  */
751 752
	  gcc_assert (stack_elt);
	  stack_elt -= 1;
H.J. Lu committed
753

754 755 756 757 758 759
	  result = stack[stack_elt];

	  switch (op)
	    {
	    case DW_OP_deref:
	      {
Kazu Hirata committed
760
		void *ptr = (void *) (_Unwind_Ptr) result;
761 762 763 764 765 766
		result = (_Unwind_Ptr) read_pointer (ptr);
	      }
	      break;

	    case DW_OP_deref_size:
	      {
Kazu Hirata committed
767
		void *ptr = (void *) (_Unwind_Ptr) result;
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782
		switch (*op_ptr++)
		  {
		  case 1:
		    result = read_1u (ptr);
		    break;
		  case 2:
		    result = read_2u (ptr);
		    break;
		  case 4:
		    result = read_4u (ptr);
		    break;
		  case 8:
		    result = read_8u (ptr);
		    break;
		  default:
783
		    gcc_unreachable ();
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
		  }
	      }
	      break;

	    case DW_OP_abs:
	      if ((_Unwind_Sword) result < 0)
		result = -result;
	      break;
	    case DW_OP_neg:
	      result = -result;
	      break;
	    case DW_OP_not:
	      result = ~result;
	      break;
	    case DW_OP_plus_uconst:
799
	      op_ptr = read_uleb128 (op_ptr, &utmp);
800
	      result += (_Unwind_Word)utmp;
801
	      break;
802 803

	    default:
804
	      gcc_unreachable ();
805 806 807 808 809 810 811 812 813 814
	    }
	  break;

	case DW_OP_and:
	case DW_OP_div:
	case DW_OP_minus:
	case DW_OP_mod:
	case DW_OP_mul:
	case DW_OP_or:
	case DW_OP_plus:
815 816 817 818
	case DW_OP_shl:
	case DW_OP_shr:
	case DW_OP_shra:
	case DW_OP_xor:
819 820 821 822 823 824 825 826 827
	case DW_OP_le:
	case DW_OP_ge:
	case DW_OP_eq:
	case DW_OP_lt:
	case DW_OP_gt:
	case DW_OP_ne:
	  {
	    /* Binary operations.  */
	    _Unwind_Word first, second;
828 829
	    gcc_assert (stack_elt >= 2);
	    stack_elt -= 2;
H.J. Lu committed
830

Kazu Hirata committed
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845
	    second = stack[stack_elt];
	    first = stack[stack_elt + 1];

	    switch (op)
	      {
	      case DW_OP_and:
		result = second & first;
		break;
	      case DW_OP_div:
		result = (_Unwind_Sword) second / (_Unwind_Sword) first;
		break;
	      case DW_OP_minus:
		result = second - first;
		break;
	      case DW_OP_mod:
846
		result = second % first;
Kazu Hirata committed
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
		break;
	      case DW_OP_mul:
		result = second * first;
		break;
	      case DW_OP_or:
		result = second | first;
		break;
	      case DW_OP_plus:
		result = second + first;
		break;
	      case DW_OP_shl:
		result = second << first;
		break;
	      case DW_OP_shr:
		result = second >> first;
		break;
	      case DW_OP_shra:
		result = (_Unwind_Sword) second >> first;
		break;
	      case DW_OP_xor:
		result = second ^ first;
		break;
	      case DW_OP_le:
870
		result = (_Unwind_Sword) second <= (_Unwind_Sword) first;
Kazu Hirata committed
871 872
		break;
	      case DW_OP_ge:
873
		result = (_Unwind_Sword) second >= (_Unwind_Sword) first;
Kazu Hirata committed
874 875
		break;
	      case DW_OP_eq:
876
		result = (_Unwind_Sword) second == (_Unwind_Sword) first;
Kazu Hirata committed
877 878
		break;
	      case DW_OP_lt:
879
		result = (_Unwind_Sword) second < (_Unwind_Sword) first;
Kazu Hirata committed
880 881
		break;
	      case DW_OP_gt:
882
		result = (_Unwind_Sword) second > (_Unwind_Sword) first;
Kazu Hirata committed
883 884
		break;
	      case DW_OP_ne:
885
		result = (_Unwind_Sword) second != (_Unwind_Sword) first;
Kazu Hirata committed
886 887 888
		break;

	      default:
889
		gcc_unreachable ();
Kazu Hirata committed
890
	      }
891 892 893 894 895 896 897 898 899 900
	  }
	  break;

	case DW_OP_skip:
	  offset = read_2s (op_ptr);
	  op_ptr += 2;
	  op_ptr += offset;
	  goto no_push;

	case DW_OP_bra:
901 902
	  gcc_assert (stack_elt);
	  stack_elt -= 1;
H.J. Lu committed
903

904 905 906 907 908 909 910 911 912 913
	  offset = read_2s (op_ptr);
	  op_ptr += 2;
	  if (stack[stack_elt] != 0)
	    op_ptr += offset;
	  goto no_push;

	case DW_OP_nop:
	  goto no_push;

	default:
914
	  gcc_unreachable ();
915 916 917
	}

      /* Most things push a result value.  */
918
      gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
919
      stack[stack_elt++] = result;
920 921 922 923 924
    no_push:;
    }

  /* We were executing this program to get a value.  It should be
     at top of stack.  */
925 926
  gcc_assert (stack_elt);
  stack_elt -= 1;
927 928 929 930 931 932 933 934 935
  return stack[stack_elt];
}


/* Decode DWARF 2 call frame information. Takes pointers the
   instruction sequence to decode, current register information and
   CIE info, and the PC range to evaluate.  */

static void
936 937 938 939
execute_cfa_program (const unsigned char *insn_ptr,
		     const unsigned char *insn_end,
		     struct _Unwind_Context *context,
		     _Unwind_FrameState *fs)
940 941 942 943 944 945
{
  struct frame_state_reg_info *unused_rs = NULL;

  /* Don't allow remember/restore between CIE and FDE programs.  */
  fs->regs.prev = NULL;

946 947 948 949 950 951
  /* The comparison with the return address uses < rather than <= because
     we are only interested in the effects of code before the call; for a
     noreturn function, the return address may point to unrelated code with
     a different stack configuration that we are not interested in.  We
     assume that the call itself is unwind info-neutral; if not, or if
     there are delay instructions that adjust the stack, these must be
952 953 954
     reflected at the point immediately before the call insn.
     In signal frames, return address is after last completed instruction,
     so we add 1 to return address to make the comparison <=.  */
955 956
  while (insn_ptr < insn_end
	 && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
957 958
    {
      unsigned char insn = *insn_ptr++;
959 960
      _uleb128_t reg, utmp;
      _sleb128_t offset, stmp;
961

962
      if ((insn & 0xc0) == DW_CFA_advance_loc)
963
	fs->pc += (insn & 0x3f) * fs->code_align;
964
      else if ((insn & 0xc0) == DW_CFA_offset)
965 966
	{
	  reg = insn & 0x3f;
967
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
968
	  offset = (_Unwind_Sword) utmp * fs->data_align;
969 970 971 972 973 974
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	    }
975
	}
976
      else if ((insn & 0xc0) == DW_CFA_restore)
977 978
	{
	  reg = insn & 0x3f;
979 980 981
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    fs->regs.reg[reg].how = REG_UNSAVED;
982 983 984 985
	}
      else switch (insn)
	{
	case DW_CFA_set_loc:
986 987
	  {
	    _Unwind_Ptr pc;
H.J. Lu committed
988

989 990 991 992
	    insn_ptr = read_encoded_value (context, fs->fde_encoding,
					   insn_ptr, &pc);
	    fs->pc = (void *) pc;
	  }
993 994 995
	  break;

	case DW_CFA_advance_loc1:
996
	  fs->pc += read_1u (insn_ptr) * fs->code_align;
997 998 999
	  insn_ptr += 1;
	  break;
	case DW_CFA_advance_loc2:
1000
	  fs->pc += read_2u (insn_ptr) * fs->code_align;
1001 1002 1003
	  insn_ptr += 2;
	  break;
	case DW_CFA_advance_loc4:
1004
	  fs->pc += read_4u (insn_ptr) * fs->code_align;
1005 1006 1007 1008
	  insn_ptr += 4;
	  break;

	case DW_CFA_offset_extended:
1009 1010
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1011
	  offset = (_Unwind_Sword) utmp * fs->data_align;
1012 1013 1014 1015 1016 1017
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	    }
1018 1019 1020
	  break;

	case DW_CFA_restore_extended:
1021
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
Geoffrey Keating committed
1022 1023
	  /* FIXME, this is wrong; the CIE might have said that the
	     register was saved somewhere.  */
1024 1025 1026
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    fs->regs.reg[reg].how = REG_UNSAVED;
1027 1028 1029
	  break;

	case DW_CFA_same_value:
1030
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1031 1032 1033
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    fs->regs.reg[reg].how = REG_UNSAVED;
1034 1035
	  break;

1036 1037
	case DW_CFA_undefined:
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1038 1039 1040
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    fs->regs.reg[reg].how = REG_UNDEFINED;
1041 1042
	  break;

1043 1044 1045 1046 1047
	case DW_CFA_nop:
	  break;

	case DW_CFA_register:
	  {
1048
	    _uleb128_t reg2;
1049 1050
	    insn_ptr = read_uleb128 (insn_ptr, &reg);
	    insn_ptr = read_uleb128 (insn_ptr, &reg2);
1051 1052 1053 1054 1055 1056
	    reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	    if (UNWIND_COLUMN_IN_RANGE (reg))
	      {
	        fs->regs.reg[reg].how = REG_SAVED_REG;
	        fs->regs.reg[reg].loc.reg = (_Unwind_Word)reg2;
	      }
1057 1058
	  }
	  break;
Kazu Hirata committed
1059

1060 1061 1062 1063 1064 1065 1066 1067 1068
	case DW_CFA_remember_state:
	  {
	    struct frame_state_reg_info *new_rs;
	    if (unused_rs)
	      {
		new_rs = unused_rs;
		unused_rs = unused_rs->prev;
	      }
	    else
1069
	      new_rs = alloca (sizeof (struct frame_state_reg_info));
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085

	    *new_rs = fs->regs;
	    fs->regs.prev = new_rs;
	  }
	  break;

	case DW_CFA_restore_state:
	  {
	    struct frame_state_reg_info *old_rs = fs->regs.prev;
	    fs->regs = *old_rs;
	    old_rs->prev = unused_rs;
	    unused_rs = old_rs;
	  }
	  break;

	case DW_CFA_def_cfa:
1086
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1087 1088 1089
	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
	  fs->regs.cfa_offset = (_Unwind_Word)utmp;
1090
	  fs->regs.cfa_how = CFA_REG_OFFSET;
1091 1092 1093
	  break;

	case DW_CFA_def_cfa_register:
1094 1095
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
1096
	  fs->regs.cfa_how = CFA_REG_OFFSET;
1097 1098 1099
	  break;

	case DW_CFA_def_cfa_offset:
1100
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1101
	  fs->regs.cfa_offset = utmp;
1102 1103 1104 1105
	  /* cfa_how deliberately not set.  */
	  break;

	case DW_CFA_def_cfa_expression:
1106 1107
	  fs->regs.cfa_exp = insn_ptr;
	  fs->regs.cfa_how = CFA_EXP;
1108
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1109
	  insn_ptr += utmp;
1110 1111 1112
	  break;

	case DW_CFA_expression:
1113
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1114 1115 1116 1117 1118 1119
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_EXP;
	      fs->regs.reg[reg].loc.exp = insn_ptr;
	    }
1120
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1121
	  insn_ptr += utmp;
1122 1123
	  break;

1124
	  /* Dwarf3.  */
1125
	case DW_CFA_offset_extended_sf:
1126 1127 1128
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
	  offset = stmp * fs->data_align;
1129 1130 1131 1132 1133 1134
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	    }
1135
	  break;
Kazu Hirata committed
1136

1137
	case DW_CFA_def_cfa_sf:
1138 1139 1140 1141
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
	  fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1142 1143
	  fs->regs.cfa_how = CFA_REG_OFFSET;
	  fs->regs.cfa_offset *= fs->data_align;
1144 1145 1146
	  break;

	case DW_CFA_def_cfa_offset_sf:
1147 1148
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
	  fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1149
	  fs->regs.cfa_offset *= fs->data_align;
1150 1151 1152
	  /* cfa_how deliberately not set.  */
	  break;

1153 1154 1155 1156
	case DW_CFA_val_offset:
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
	  offset = (_Unwind_Sword) utmp * fs->data_align;
1157 1158 1159 1160 1161 1162
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	    }
1163 1164 1165 1166 1167 1168
	  break;

	case DW_CFA_val_offset_sf:
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
	  offset = stmp * fs->data_align;
1169 1170 1171 1172 1173 1174
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	    }
1175 1176 1177 1178
	  break;

	case DW_CFA_val_expression:
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1179 1180 1181 1182 1183 1184
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_VAL_EXP;
	      fs->regs.reg[reg].loc.exp = insn_ptr;
	    }
1185 1186 1187 1188
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
	  insn_ptr += utmp;
	  break;

1189
	case DW_CFA_GNU_window_save:
1190
#if defined (__aarch64__) && !defined (__ILP32__)
1191 1192 1193 1194
	  /* This CFA is multiplexed with Sparc.  On AArch64 it's used to toggle
	     return address signing status.  */
	  fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset ^= 1;
#else
1195
	  /* ??? Hardcoded for SPARC register window configuration.  */
1196
	  if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)
1197 1198 1199 1200 1201
	    for (reg = 16; reg < 32; ++reg)
	      {
		fs->regs.reg[reg].how = REG_SAVED_OFFSET;
		fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
	      }
1202
#endif
1203 1204 1205
	  break;

	case DW_CFA_GNU_args_size:
1206 1207
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
	  context->args_size = (_Unwind_Word)utmp;
1208 1209 1210 1211 1212
	  break;

	case DW_CFA_GNU_negative_offset_extended:
	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
	     older PowerPC code.  */
1213 1214
	  insn_ptr = read_uleb128 (insn_ptr, &reg);
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1215
	  offset = (_Unwind_Word) utmp * fs->data_align;
1216 1217 1218 1219 1220 1221
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
	  if (UNWIND_COLUMN_IN_RANGE (reg))
	    {
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
	      fs->regs.reg[reg].loc.offset = -offset;
	    }
1222 1223 1224
	  break;

	default:
1225
	  gcc_unreachable ();
1226 1227 1228 1229
	}
    }
}

Jason Merrill committed
1230 1231 1232 1233 1234
/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
   its caller and decode it into FS.  This function also sets the
   args_size and lsda members of CONTEXT, as they are really information
   about the caller's frame.  */

1235 1236 1237
static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
1238 1239
  const struct dwarf_fde *fde;
  const struct dwarf_cie *cie;
1240
  const unsigned char *aug, *insn, *end;
1241 1242 1243 1244 1245

  memset (fs, 0, sizeof (*fs));
  context->args_size = 0;
  context->lsda = 0;

1246 1247 1248
  if (context->ra == 0)
    return _URC_END_OF_STACK;

1249
  fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
1250
			  &context->bases);
1251 1252
  if (fde == NULL)
    {
1253
#ifdef MD_FALLBACK_FRAME_STATE_FOR
1254 1255
      /* Couldn't find frame unwind info for this function.  Try a
	 target-specific fallback mechanism.  This will necessarily
1256
	 not provide a personality routine or LSDA.  */
1257
      return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
1258 1259 1260 1261 1262
#else
      return _URC_END_OF_STACK;
#endif
    }

1263
  fs->pc = context->bases.func;
1264 1265 1266 1267 1268 1269 1270 1271

  cie = get_cie (fde);
  insn = extract_cie_info (cie, context, fs);
  if (insn == NULL)
    /* CIE contained unknown augmentation.  */
    return _URC_FATAL_PHASE1_ERROR;

  /* First decode all the insns in the CIE.  */
1272
  end = (const unsigned char *) next_fde ((const struct dwarf_fde *) cie);
1273 1274 1275
  execute_cfa_program (insn, end, context, fs);

  /* Locate augmentation for the fde.  */
1276
  aug = (const unsigned char *) fde + sizeof (*fde);
1277
  aug += 2 * size_of_encoded_value (fs->fde_encoding);
1278 1279 1280
  insn = NULL;
  if (fs->saw_z)
    {
1281
      _uleb128_t i;
1282 1283 1284
      aug = read_uleb128 (aug, &i);
      insn = aug + i;
    }
1285
  if (fs->lsda_encoding != DW_EH_PE_omit)
1286 1287
    {
      _Unwind_Ptr lsda;
H.J. Lu committed
1288

1289 1290 1291
      aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
      context->lsda = (void *) lsda;
    }
1292 1293 1294 1295

  /* Then the insns in the FDE up to our target PC.  */
  if (insn == NULL)
    insn = aug;
1296
  end = (const unsigned char *) next_fde (fde);
1297 1298 1299 1300
  execute_cfa_program (insn, end, context, fs);

  return _URC_NO_REASON;
}
1301 1302 1303 1304 1305 1306 1307

typedef struct frame_state
{
  void *cfa;
  void *eh_ptr;
  long cfa_offset;
  long args_size;
1308
  long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1309 1310
  unsigned short cfa_reg;
  unsigned short retaddr_column;
1311
  char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
} frame_state;

struct frame_state * __frame_state_for (void *, struct frame_state *);

/* Called from pre-G++ 3.0 __throw to find the registers to restore for
   a given PC_TARGET.  The caller should allocate a local variable of
   `struct frame_state' and pass its address to STATE_IN.  */

struct frame_state *
__frame_state_for (void *pc_target, struct frame_state *state_in)
{
  struct _Unwind_Context context;
  _Unwind_FrameState fs;
  int reg;

  memset (&context, 0, sizeof (struct _Unwind_Context));
1328 1329
  if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
    context.flags = EXTENDED_CONTEXT_BIT;
1330 1331 1332 1333
  context.ra = pc_target + 1;

  if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
    return 0;
1334

1335 1336
  /* We have no way to pass a location expression for the CFA to our
     caller.  It wouldn't understand it anyway.  */
1337
  if (fs.regs.cfa_how == CFA_EXP)
1338
    return 0;
1339

1340
  for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356
    {
      state_in->saved[reg] = fs.regs.reg[reg].how;
      switch (state_in->saved[reg])
	{
	case REG_SAVED_REG:
	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
	  break;
	case REG_SAVED_OFFSET:
	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
	  break;
	default:
	  state_in->reg_or_offset[reg] = 0;
	  break;
	}
    }

1357 1358
  state_in->cfa_offset = fs.regs.cfa_offset;
  state_in->cfa_reg = fs.regs.cfa_reg;
1359 1360 1361 1362 1363 1364 1365
  state_in->retaddr_column = fs.retaddr_column;
  state_in->args_size = context.args_size;
  state_in->eh_ptr = fs.eh_ptr;

  return state_in;
}

1366 1367 1368 1369
typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;

static inline void
_Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1370
		     _Unwind_SpTmp *tmp_sp)
1371 1372
{
  int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
H.J. Lu committed
1373

1374 1375 1376
  if (size == sizeof(_Unwind_Ptr))
    tmp_sp->ptr = (_Unwind_Ptr) cfa;
  else
1377 1378 1379 1380
    {
      gcc_assert (size == sizeof(_Unwind_Word));
      tmp_sp->word = (_Unwind_Ptr) cfa;
    }
1381 1382 1383
  _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
}

1384 1385 1386 1387 1388 1389 1390
static void
uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
  struct _Unwind_Context orig_context = *context;
  void *cfa;
  long i;

1391
#ifdef __LIBGCC_EH_RETURN_STACKADJ_RTX__
1392 1393 1394 1395 1396 1397 1398 1399 1400
  /* Special handling here: Many machines do not use a frame pointer,
     and track the CFA only through offsets from the stack pointer from
     one frame to the next.  In this case, the stack pointer is never
     stored, so it has no saved address in the context.  What we do
     have is the CFA from the previous stack frame.

     In very special situations (such as unwind info for signal return),
     there may be location expressions that use the stack pointer as well.

1401 1402 1403 1404 1405
     Do this conditionally for one frame.  This allows the unwind info
     for one frame to save a copy of the stack pointer from the previous
     frame, and be able to use much easier CFA mechanisms to do it.
     Always zap the saved stack pointer value for the next frame; carrying
     the value over from one frame to another doesn't make sense.  */
1406

1407
  _Unwind_SpTmp tmp_sp;
1408

1409
  if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1410
    _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1411
  _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1412
#endif
1413

1414
  /* Compute this frame's CFA.  */
1415
  switch (fs->regs.cfa_how)
1416 1417
    {
    case CFA_REG_OFFSET:
1418 1419
      cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
      cfa += fs->regs.cfa_offset;
1420 1421 1422 1423
      break;

    case CFA_EXP:
      {
1424
	const unsigned char *exp = fs->regs.cfa_exp;
1425
	_uleb128_t len;
1426 1427 1428

	exp = read_uleb128 (exp, &len);
	cfa = (void *) (_Unwind_Ptr)
1429
	  execute_stack_op (exp, exp + len, &orig_context, 0);
1430 1431 1432 1433
	break;
      }

    default:
1434
      gcc_unreachable ();
1435 1436 1437 1438
    }
  context->cfa = cfa;

  /* Compute the addresses of all registers saved in this frame.  */
1439
  for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__ + 1; ++i)
1440 1441 1442
    switch (fs->regs.reg[i].how)
      {
      case REG_UNSAVED:
1443
      case REG_UNDEFINED:
1444
	break;
1445

1446
      case REG_SAVED_OFFSET:
1447 1448
	_Unwind_SetGRPtr (context, i,
			  (void *) (cfa + fs->regs.reg[i].loc.offset));
1449
	break;
1450

1451
      case REG_SAVED_REG:
1452 1453 1454 1455 1456 1457 1458 1459
	if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
	  _Unwind_SetGRValue (context, i,
			      _Unwind_GetGR (&orig_context,
					     fs->regs.reg[i].loc.reg));
	else
	  _Unwind_SetGRPtr (context, i,
			    _Unwind_GetGRPtr (&orig_context,
					      fs->regs.reg[i].loc.reg));
1460
	break;
1461

1462 1463
      case REG_SAVED_EXP:
	{
1464
	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
1465
	  _uleb128_t len;
1466 1467 1468 1469 1470
	  _Unwind_Ptr val;

	  exp = read_uleb128 (exp, &len);
	  val = execute_stack_op (exp, exp + len, &orig_context,
				  (_Unwind_Ptr) cfa);
1471
	  _Unwind_SetGRPtr (context, i, (void *) val);
1472 1473
	}
	break;
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483

      case REG_SAVED_VAL_OFFSET:
	_Unwind_SetGRValue (context, i,
			    (_Unwind_Internal_Ptr)
			    (cfa + fs->regs.reg[i].loc.offset));
	break;

      case REG_SAVED_VAL_EXP:
	{
	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
1484
	  _uleb128_t len;
1485 1486 1487 1488 1489 1490 1491 1492
	  _Unwind_Ptr val;

	  exp = read_uleb128 (exp, &len);
	  val = execute_stack_op (exp, exp + len, &orig_context,
				  (_Unwind_Ptr) cfa);
	  _Unwind_SetGRValue (context, i, val);
	}
	break;
1493
      }
1494

1495
  _Unwind_SetSignalFrame (context, fs->signal_frame);
1496

1497
#ifdef MD_FROB_UPDATE_CONTEXT
1498
  MD_FROB_UPDATE_CONTEXT (context, fs);
1499
#endif
1500 1501
}

Jason Merrill committed
1502 1503 1504 1505 1506
/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
   of its caller.  Update CONTEXT to refer to the caller as well.  Note
   that the args_size and lsda members are not updated here, but later in
   uw_frame_state_for.  */

1507 1508 1509 1510 1511
static void
uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
  uw_update_context_1 (context, fs);

1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523
  /* In general this unwinder doesn't make any distinction between
     undefined and same_value rule.  Call-saved registers are assumed
     to have same_value rule by default and explicit undefined
     rule is handled like same_value.  The only exception is
     DW_CFA_undefined on retaddr_column which is supposed to
     mark outermost frame in DWARF 3.  */
  if (fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (fs->retaddr_column)].how
      == REG_UNDEFINED)
    /* uw_frame_state_for uses context->ra == 0 check to find outermost
       stack frame.  */
    context->ra = 0;
  else
1524 1525 1526 1527 1528 1529 1530 1531 1532
    {
      /* Compute the return address now, since the return address column
	 can change from frame to frame.  */
      context->ra = __builtin_extract_return_addr
	(_Unwind_GetPtr (context, fs->retaddr_column));
#ifdef MD_POST_EXTRACT_FRAME_ADDR
      context->ra = MD_POST_EXTRACT_FRAME_ADDR (context, fs, context->ra);
#endif
    }
1533
}
1534 1535 1536 1537 1538 1539

static void
uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
  uw_update_context (context, fs);
}
1540 1541 1542

/* Fill in CONTEXT for top-of-stack.  The only valid registers at this
   level will be the return address and the CFA.  */
Kazu Hirata committed
1543

Kazu Hirata committed
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553
#define uw_init_context(CONTEXT)					   \
  do									   \
    {									   \
      /* Do any necessary initialization to access arbitrary stack frames. \
	 On the SPARC, this means flushing the register windows.  */	   \
      __builtin_unwind_init ();						   \
      uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),		   \
			 __builtin_return_address (0));			   \
    }									   \
  while (0)
1554

1555 1556 1557 1558 1559 1560
static inline void
init_dwarf_reg_size_table (void)
{
  __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
}

1561
static void __attribute__((noinline))
1562 1563 1564 1565
uw_init_context_1 (struct _Unwind_Context *context,
		   void *outer_cfa, void *outer_ra)
{
  void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1566 1567 1568
#ifdef MD_POST_EXTRACT_ROOT_ADDR
  ra = MD_POST_EXTRACT_ROOT_ADDR (ra);
#endif
1569
  _Unwind_FrameState fs;
1570
  _Unwind_SpTmp sp_slot;
1571
  _Unwind_Reason_Code code;
1572 1573 1574

  memset (context, 0, sizeof (struct _Unwind_Context));
  context->ra = ra;
1575 1576
  if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
    context->flags = EXTENDED_CONTEXT_BIT;
1577

1578 1579
  code = uw_frame_state_for (context, &fs);
  gcc_assert (code == _URC_NO_REASON);
1580

1581 1582 1583 1584
#if __GTHREADS
  {
    static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
    if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1585
	&& dwarf_reg_size_table[0] == 0)
1586 1587 1588 1589 1590 1591 1592
      init_dwarf_reg_size_table ();
  }
#else
  if (dwarf_reg_size_table[0] == 0)
    init_dwarf_reg_size_table ();
#endif

1593
  /* Force the frame state to use the known cfa value.  */
1594
  _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1595 1596 1597
  fs.regs.cfa_how = CFA_REG_OFFSET;
  fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
  fs.regs.cfa_offset = 0;
1598 1599 1600 1601 1602 1603 1604

  uw_update_context_1 (context, &fs);

  /* If the return address column was saved in a register in the
     initialization context, then we can't see it in the given
     call frame data.  So have the initialization context tell us.  */
  context->ra = __builtin_extract_return_addr (outer_ra);
1605 1606 1607
#ifdef MD_POST_EXTRACT_ROOT_ADDR
  context->ra = MD_POST_EXTRACT_ROOT_ADDR (context->ra);
#endif
1608 1609
}

1610 1611
static void _Unwind_DebugHook (void *, void *)
  __attribute__ ((__noinline__, __used__, __noclone__));
1612 1613 1614 1615 1616 1617 1618 1619 1620

/* This function is called during unwinding.  It is intended as a hook
   for a debugger to intercept exceptions.  CFA is the CFA of the
   target frame.  HANDLER is the PC to which control will be
   transferred.  */
static void
_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
		   void *handler __attribute__ ((__unused__)))
{
1621 1622 1623 1624 1625
  /* We only want to use stap probes starting with v3.  Earlier
     versions added too much startup cost.  */
#if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
  STAP_PROBE2 (libgcc, unwind, cfa, handler);
#else
1626
  asm ("");
1627
#endif
1628
}
1629

1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
/* Frob exception handler's address kept in TARGET before installing into
   CURRENT context.  */

static inline void *
uw_frob_return_addr (struct _Unwind_Context *current
		     __attribute__ ((__unused__)),
		     struct _Unwind_Context *target)
{
  void *ret_addr = __builtin_frob_return_addr (target->ra);
#ifdef MD_POST_FROB_EH_HANDLER_ADDR
  ret_addr = MD_POST_FROB_EH_HANDLER_ADDR (current, target, ret_addr);
#endif
  return ret_addr;
}

1645 1646 1647 1648
/* Install TARGET into CURRENT so that we can return to it.  This is a
   macro because __builtin_eh_return must be invoked in the context of
   our caller.  */

1649 1650 1651 1652
#define uw_install_context(CURRENT, TARGET)				\
  do									\
    {									\
      long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
1653
      void *handler = uw_frob_return_addr ((CURRENT), (TARGET));	\
1654 1655 1656
      _Unwind_DebugHook ((TARGET)->cfa, handler);			\
      __builtin_eh_return (offset, handler);				\
    }									\
Kazu Hirata committed
1657
  while (0)
1658 1659 1660 1661 1662 1663

static long
uw_install_context_1 (struct _Unwind_Context *current,
		      struct _Unwind_Context *target)
{
  long i;
1664 1665 1666 1667 1668
  _Unwind_SpTmp sp_slot;

  /* If the target frame does not have a saved stack pointer,
     then set up the target's CFA.  */
  if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1669
    _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1670

1671
  for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__; ++i)
1672
    {
1673 1674
      void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
      void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
1675

1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693
      gcc_assert (current->by_value[i] == 0);
      if (target->by_value[i] && c)
	{
	  _Unwind_Word w;
	  _Unwind_Ptr p;
	  if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
	    {
	      w = (_Unwind_Internal_Ptr) t;
	      memcpy (c, &w, sizeof (_Unwind_Word));
	    }
	  else
	    {
	      gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
	      p = (_Unwind_Internal_Ptr) t;
	      memcpy (c, &p, sizeof (_Unwind_Ptr));
	    }
	}
      else if (t && c && t != c)
1694 1695 1696
	memcpy (c, t, dwarf_reg_size_table[i]);
    }

1697 1698 1699 1700 1701 1702
  /* If the current frame doesn't have a saved stack pointer, then we
     need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
     pointer value reloaded.  */
  if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
    {
      void *target_cfa;
1703

1704
      target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1705 1706

      /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
1707
      if (__LIBGCC_STACK_GROWS_DOWNWARD__)
1708 1709 1710 1711
	return target_cfa - current->cfa + target->args_size;
      else
	return current->cfa - target_cfa - target->args_size;
    }
1712
  return 0;
1713 1714 1715 1716 1717
}

static inline _Unwind_Ptr
uw_identify_context (struct _Unwind_Context *context)
{
1718 1719 1720
  /* The CFA is not sufficient to disambiguate the context of a function
     interrupted by a signal before establishing its frame and the context
     of the signal itself.  */
1721
  if (__LIBGCC_STACK_GROWS_DOWNWARD__)
1722 1723 1724
    return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
  else
    return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
1725 1726 1727 1728 1729
}


#include "unwind.inc"

1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748
#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
alias (_Unwind_Backtrace);
alias (_Unwind_DeleteException);
alias (_Unwind_FindEnclosingFunction);
alias (_Unwind_ForcedUnwind);
alias (_Unwind_GetDataRelBase);
alias (_Unwind_GetTextRelBase);
alias (_Unwind_GetCFA);
alias (_Unwind_GetGR);
alias (_Unwind_GetIP);
alias (_Unwind_GetLanguageSpecificData);
alias (_Unwind_GetRegionStart);
alias (_Unwind_RaiseException);
alias (_Unwind_Resume);
alias (_Unwind_Resume_or_Rethrow);
alias (_Unwind_SetGR);
alias (_Unwind_SetIP);
#endif

1749
#endif /* !USING_SJLJ_EXCEPTIONS */