From 5442cf157b9baa37766aae56711a5e598d025ab2 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Thu, 19 Jul 2001 20:20:49 +0200 Subject: [PATCH] unwind-dw2.c (_Unwind_FrameState): Add eh_ptr. * unwind-dw2.c (_Unwind_FrameState): Add eh_ptr. (extract_cie_info): Handle "eh" augmentation properly, remember eh_ptr. (struct frame_state, __frame_state_for): New. Co-Authored-By: Jakub Jelinek From-SVN: r44155 --- gcc/ChangeLog | 8 +++++ gcc/unwind-dw2.c | 80 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 88ab499e226..9d23e01d3d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2001-07-19 Mark Kettenis + Jakub Jelinek + + * unwind-dw2.c (_Unwind_FrameState): Add eh_ptr. + (extract_cie_info): Handle "eh" augmentation properly, + remember eh_ptr. + (struct frame_state, __frame_state_for): New. + 2001-07-19 Rainer Orth * config/alpha/osf.h (ASM_OUTPUT_WEAK_ALIAS, ASM_WEAKEN_LABEL, diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index 3011bc7341f..c1aa67fdb5a 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -106,6 +106,7 @@ typedef struct unsigned char fde_encoding; unsigned char lsda_encoding; unsigned char saw_z; + void *eh_ptr; } _Unwind_FrameState; /* Read unaligned data from the instruction buffer. */ @@ -220,6 +221,15 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context, const unsigned char *ret = NULL; _Unwind_Ptr tmp; + /* 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; + } + /* Immediately following the augmentation are the code and data alignment and return address column. */ p = read_uleb128 (p, &tmp); fs->code_align = tmp; @@ -242,15 +252,8 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context, /* Iterate over recognized augmentation subsequences. */ while (*aug != '\0') { - /* "eh" was used by g++ v2; recognize and skip. */ - if (aug[0] == 'e' && aug[1] == 'h') - { - p += sizeof (void *); - aug += 2; - } - /* "L" indicates a byte showing how the LSDA pointer is encoded. */ - else if (aug[0] == 'L') + if (aug[0] == 'L') { fs->lsda_encoding = *p++; aug += 1; @@ -937,8 +940,69 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) return _URC_NO_REASON; } + +typedef struct frame_state +{ + void *cfa; + void *eh_ptr; + long cfa_offset; + long args_size; + long reg_or_offset[DWARF_FRAME_REGISTERS+1]; + unsigned short cfa_reg; + unsigned short retaddr_column; + char saved[DWARF_FRAME_REGISTERS+1]; +} 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)); + context.ra = pc_target + 1; + + if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON) + return 0; + /* We have no way to pass a location expression for the CFA to our + caller. It wouldn't understand it anyway. */ + if (fs.cfa_how == CFA_EXP) + return 0; + for (reg = 0; reg < DWARF_FRAME_REGISTERS + 1; reg++) + { + 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; + } + } + + state_in->cfa_offset = fs.cfa_offset; + state_in->cfa_reg = fs.cfa_reg; + state_in->retaddr_column = fs.retaddr_column; + state_in->args_size = context.args_size; + state_in->eh_ptr = fs.eh_ptr; + + return state_in; +} + static void uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) { -- 2.30.2