#include "tm.h"
#include "dwarf2.h"
#include "unwind.h"
+#ifdef __USING_SJLJ_EXCEPTIONS__
+# define NO_SIZE_OF_ENCODED_VALUE
+#endif
#include "unwind-pe.h"
#include "unwind-dw2-fde.h"
#include "gthr.h"
-
+#include "unwind-dw2.h"
#ifndef __USING_SJLJ_EXCEPTIONS__
#define STACK_GROWS_DOWNWARD 1
#endif
-/* A target can override (perhaps for backward compatibility) how
- many dwarf2 columns are unwound. */
-#ifndef DWARF_FRAME_REGISTERS
-#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
-#endif
-
/* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
\f
-/* The result of interpreting the frame unwind info for a frame.
- This is all symbolic at this point, as none of the values can
- be resolved until the target pc is located. */
-typedef struct
-{
- /* Each register save state can be described in terms of a CFA slot,
- another register, or a location expression. */
- struct frame_state_reg_info
- {
- struct {
- union {
- _Unwind_Word reg;
- _Unwind_Sword offset;
- const unsigned char *exp;
- } loc;
- enum {
- REG_UNSAVED,
- REG_SAVED_OFFSET,
- REG_SAVED_REG,
- REG_SAVED_EXP,
- } how;
- } reg[DWARF_FRAME_REGISTERS+1];
-
- /* Used to implement DW_CFA_remember_state. */
- struct frame_state_reg_info *prev;
- } regs;
-
- /* The CFA can be described in terms of a reg+offset or a
- location expression. */
- _Unwind_Sword cfa_offset;
- _Unwind_Word cfa_reg;
- const unsigned char *cfa_exp;
- enum {
- CFA_UNSET,
- CFA_REG_OFFSET,
- CFA_EXP,
- } cfa_how;
-
- /* The PC described by the current frame state. */
- void *pc;
-
- /* The information we care about from the CIE/FDE. */
- _Unwind_Personality_Fn personality;
- _Unwind_Sword data_align;
- _Unwind_Word code_align;
- unsigned char retaddr_column;
- unsigned char fde_encoding;
- unsigned char lsda_encoding;
- unsigned char saw_z;
- void *eh_ptr;
-} _Unwind_FrameState;
-\f
/* Read unaligned data from the instruction buffer. */
union unaligned
void *ptr;
index = DWARF_REG_TO_UNWIND_COLUMN (index);
- if (index >= sizeof(dwarf_reg_size_table))
+ if (index >= (int) sizeof(dwarf_reg_size_table))
abort ();
size = dwarf_reg_size_table[index];
ptr = context->reg[index];
void *ptr;
index = DWARF_REG_TO_UNWIND_COLUMN (index);
- if (index >= sizeof(dwarf_reg_size_table))
+ if (index >= (int) sizeof(dwarf_reg_size_table))
abort ();
size = dwarf_reg_size_table[index];
ptr = context->reg[index];
_Unwind_FindEnclosingFunction (void *pc)
{
struct dwarf_eh_bases bases;
- struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
+ const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
if (fde)
return bases.func;
else
or NULL if we encountered an undecipherable augmentation. */
static const unsigned char *
-extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
+extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
const unsigned char *aug = cie->augmentation;
data alignment and return address column. */
p = read_uleb128 (p, &fs->code_align);
p = read_sleb128 (p, &fs->data_align);
- fs->retaddr_column = *p++;
+ if (cie->version == 1)
+ fs->retaddr_column = *p++;
+ else
+ p = read_uleb128 (p, &fs->retaddr_column);
fs->lsda_encoding = DW_EH_PE_omit;
/* If the augmentation starts with 'z', then a uleb128 immediately
case DW_CFA_restore_extended:
insn_ptr = read_uleb128 (insn_ptr, ®);
+ /* FIXME, this is wrong; the CIE might have said that the
+ register was saved somewhere. */
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
break;
case DW_CFA_undefined:
case DW_CFA_same_value:
insn_ptr = read_uleb128 (insn_ptr, ®);
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
break;
case DW_CFA_nop:
static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
- struct dwarf_fde *fde;
- struct dwarf_cie *cie;
+ const struct dwarf_fde *fde;
+ const struct dwarf_cie *cie;
const unsigned char *aug, *insn, *end;
memset (fs, 0, sizeof (*fs));