/* DWARF2 exception handling and frame unwind runtime interface routines.
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
- GNU CC 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.
+ 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.
You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with GCC; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
#include "tconfig.h"
#include "tsystem.h"
{
struct {
union {
- unsigned int reg;
+ _Unwind_Word reg;
_Unwind_Sword offset;
const unsigned char *exp;
} loc;
/* The information we care about from the CIE/FDE. */
_Unwind_Personality_Fn personality;
- signed int data_align;
- unsigned int code_align;
+ _Unwind_Sword data_align;
+ _Unwind_Word code_align;
unsigned char retaddr_column;
unsigned char fde_encoding;
unsigned char lsda_encoding;
const unsigned char *aug = cie->augmentation;
const unsigned char *p = aug + strlen (aug) + 1;
const unsigned char *ret = NULL;
- _Unwind_Ptr tmp;
+ _Unwind_Word utmp;
/* g++ v2 "eh" has pointer immediately following augmentation string,
so it must be handled first. */
/* Immediately following the augmentation are the code and
data alignment and return address column. */
- p = read_uleb128 (p, &tmp); fs->code_align = tmp;
- p = read_sleb128 (p, &tmp); fs->data_align = (saddr) tmp;
+ p = read_uleb128 (p, &fs->code_align);
+ p = read_sleb128 (p, &fs->data_align);
fs->retaddr_column = *p++;
fs->lsda_encoding = DW_EH_PE_omit;
the size. */
if (*aug == 'z')
{
- p = read_uleb128 (p, &tmp);
- ret = p + tmp;
+ p = read_uleb128 (p, &utmp);
+ ret = p + utmp;
fs->saw_z = 1;
++aug;
while (op_ptr < op_end)
{
enum dwarf_location_atom op = *op_ptr++;
- _Unwind_Word result, reg;
- _Unwind_Sword offset;
- _Unwind_Ptr ptrtmp;
+ _Unwind_Word result, reg, utmp;
+ _Unwind_Sword offset, stmp;
switch (op)
{
op_ptr += 8;
break;
case DW_OP_constu:
- op_ptr = read_uleb128 (op_ptr, &ptrtmp);
- result = ptrtmp;
+ op_ptr = read_uleb128 (op_ptr, &result);
break;
case DW_OP_consts:
- op_ptr = read_sleb128 (op_ptr, &ptrtmp);
- result = (saddr)ptrtmp;
+ op_ptr = read_sleb128 (op_ptr, &stmp);
+ result = stmp;
break;
case DW_OP_reg0:
result = _Unwind_GetGR (context, op - DW_OP_reg0);
break;
case DW_OP_regx:
- op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
+ op_ptr = read_uleb128 (op_ptr, ®);
result = _Unwind_GetGR (context, reg);
break;
case DW_OP_breg29:
case DW_OP_breg30:
case DW_OP_breg31:
- op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
+ op_ptr = read_sleb128 (op_ptr, &offset);
result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
break;
case DW_OP_bregx:
- op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
- op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
+ op_ptr = read_uleb128 (op_ptr, ®);
+ op_ptr = read_sleb128 (op_ptr, &offset);
result = _Unwind_GetGR (context, reg) + offset;
break;
result = ~result;
break;
case DW_OP_plus_uconst:
- op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
- result += reg;
+ op_ptr = read_uleb128 (op_ptr, &utmp);
+ result += utmp;
break;
+
+ default:
+ abort ();
}
break;
case DW_OP_ne:
result = (_Unwind_Sword)first != (_Unwind_Sword)second;
break;
+
+ default:
+ abort ();
}
}
break;
/* Don't allow remember/restore between CIE and FDE programs. */
fs->regs.prev = NULL;
- while (insn_ptr < insn_end && fs->pc < context->ra)
+ while (insn_ptr < insn_end && fs->pc <= context->ra)
{
unsigned char insn = *insn_ptr++;
- _Unwind_Word reg;
- _Unwind_Sword offset;
- _Unwind_Ptr ptrtmp;
+ _Unwind_Word reg, utmp;
+ _Unwind_Sword offset, stmp;
if (insn & DW_CFA_advance_loc)
fs->pc += (insn & 0x3f) * fs->code_align;
else if (insn & DW_CFA_offset)
{
reg = insn & 0x3f;
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- offset = ptrtmp * fs->data_align;
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ offset = (_Unwind_Sword)utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
}
break;
case DW_CFA_offset_extended:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- offset = ptrtmp * fs->data_align;
+ insn_ptr = read_uleb128 (insn_ptr, ®);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ offset = (_Unwind_Sword)utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
break;
case DW_CFA_restore_extended:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+ insn_ptr = read_uleb128 (insn_ptr, ®);
fs->regs.reg[reg].how = REG_UNSAVED;
break;
case DW_CFA_register:
{
_Unwind_Word reg2;
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;
+ insn_ptr = read_uleb128 (insn_ptr, ®);
+ insn_ptr = read_uleb128 (insn_ptr, ®2);
fs->regs.reg[reg].how = REG_SAVED_REG;
fs->regs.reg[reg].loc.reg = reg2;
}
unused_rs = unused_rs->prev;
}
else
- new_rs = alloca (sizeof (struct frame_state_reg_info));
+ new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
*new_rs = fs->regs;
fs->regs.prev = new_rs;
break;
case DW_CFA_def_cfa:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- fs->cfa_reg = ptrtmp;
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- fs->cfa_offset = ptrtmp;
+ insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ fs->cfa_offset = utmp;
fs->cfa_how = CFA_REG_OFFSET;
break;
case DW_CFA_def_cfa_register:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- fs->cfa_reg = ptrtmp;
+ insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
fs->cfa_how = CFA_REG_OFFSET;
break;
case DW_CFA_def_cfa_offset:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- fs->cfa_offset = ptrtmp;
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ fs->cfa_offset = utmp;
/* cfa_how deliberately not set. */
break;
case DW_CFA_def_cfa_expression:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->cfa_exp = insn_ptr;
fs->cfa_how = CFA_EXP;
- insn_ptr += ptrtmp;
+ insn_ptr += utmp;
break;
case DW_CFA_expression:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+ insn_ptr = read_uleb128 (insn_ptr, ®);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->regs.reg[reg].how = REG_SAVED_EXP;
fs->regs.reg[reg].loc.exp = insn_ptr;
- insn_ptr += ptrtmp;
+ insn_ptr += utmp;
break;
/* From the 2.1 draft. */
case DW_CFA_offset_extended_sf:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
- insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
- offset = (saddr)ptrtmp * fs->data_align;
+ insn_ptr = read_uleb128 (insn_ptr, ®);
+ insn_ptr = read_sleb128 (insn_ptr, &stmp);
+ offset = stmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
break;
case DW_CFA_def_cfa_sf:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- fs->cfa_reg = ptrtmp;
- insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
- fs->cfa_offset = (saddr)ptrtmp;
+ insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+ insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
fs->cfa_how = CFA_REG_OFFSET;
break;
case DW_CFA_def_cfa_offset_sf:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- fs->cfa_offset = ptrtmp;
+ insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
/* cfa_how deliberately not set. */
break;
break;
case DW_CFA_GNU_args_size:
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- context->args_size = ptrtmp;
+ insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
break;
case DW_CFA_GNU_negative_offset_extended:
/* Obsoleted by DW_CFA_offset_extended_sf, but used by
older PowerPC code. */
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
- insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
- offset = ptrtmp * fs->data_align;
+ insn_ptr = read_uleb128 (insn_ptr, ®);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ offset = (_Unwind_Word)utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = -offset;
break;
{
/* Couldn't find frame unwind info for this function. Try a
target-specific fallback mechanism. This will necessarily
- not profide a personality routine or LSDA. */
+ not provide a personality routine or LSDA. */
#ifdef MD_FALLBACK_FRAME_STATE_FOR
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
return _URC_END_OF_STACK;
insn = NULL;
if (fs->saw_z)
{
- _Unwind_Ptr i;
+ _Unwind_Word i;
aug = read_uleb128 (aug, &i);
insn = aug + i;
}
that this will not be a problem. */
{
const unsigned char *exp = fs->cfa_exp;
- _Unwind_Ptr len;
+ _Unwind_Word len;
exp = read_uleb128 (exp, &len);
cfa = (void *) (_Unwind_Ptr)
case REG_SAVED_EXP:
{
const unsigned char *exp = fs->regs.reg[i].loc.exp;
- _Unwind_Ptr len;
+ _Unwind_Word len;
_Unwind_Ptr val;
exp = read_uleb128 (exp, &len);