From a9985a921e38ff58d79d624d9d77c72b54337d5e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 31 Aug 2001 05:49:13 -0400 Subject: [PATCH] unwind-pe.h (read_uleb128, [...]): Move actual reading code here. * unwind-pe.h (read_uleb128, read_sleb128): Move actual reading code here. Take _Unwind_{W,Sw}ord*. (read_encoded_value_with_base): Use them. * unwind-dw2.c (_Unwind_FrameState): Make cfa_offset and cfa_reg words. (extract_cie_info): Simplify read_?leb128 handling. (execute_stack_op, execute_cfa_program): Likewise. * unwind-dw2-fde.c (get_cie_encoding): Likewise. * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Simplify leb128 handling. From-SVN: r45315 --- gcc/ChangeLog | 11 +++ gcc/unwind-dw2-fde.c | 8 ++- gcc/unwind-dw2.c | 115 ++++++++++++++----------------- gcc/unwind-pe.h | 99 +++++++++++++++----------- libstdc++-v3/ChangeLog | 5 ++ libstdc++-v3/libsupc++/eh_personality.cc | 14 ++-- 6 files changed, 137 insertions(+), 115 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c3b6bd..3961375 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2001-08-31 Jason Merrill + + * unwind-pe.h (read_uleb128, read_sleb128): Move actual reading + code here. Take _Unwind_{W,Sw}ord*. + (read_encoded_value_with_base): Use them. + * unwind-dw2.c (_Unwind_FrameState): Make cfa_offset and cfa_reg + words. + (extract_cie_info): Simplify read_?leb128 handling. + (execute_stack_op, execute_cfa_program): Likewise. + * unwind-dw2-fde.c (get_cie_encoding): Likewise. + 2001-08-31 Geoffrey Keating * config/stormy16/stormy16.c (stormy16_expand_epilogue): Use diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c index 0ef47c1..5085119 100644 --- a/gcc/unwind-dw2-fde.c +++ b/gcc/unwind-dw2-fde.c @@ -243,18 +243,20 @@ get_cie_encoding (struct dwarf_cie *cie) { const unsigned char *aug, *p; _Unwind_Ptr dummy; + _Unwind_Word utmp; + _Unwind_Sword stmp; aug = cie->augmentation; if (aug[0] != 'z') return DW_EH_PE_absptr; p = aug + strlen (aug) + 1; /* Skip the augmentation string. */ - p = read_uleb128 (p, &dummy); /* Skip code alignment. */ - p = read_sleb128 (p, &dummy); /* Skip data alignment. */ + p = read_uleb128 (p, &utmp); /* Skip code alignment. */ + p = read_sleb128 (p, &stmp); /* Skip data alignment. */ p++; /* Skip return address column. */ aug++; /* Skip 'z' */ - p = read_uleb128 (p, &dummy); /* Skip augmentation length. */ + p = read_uleb128 (p, &utmp); /* Skip augmentation length. */ while (1) { /* This is what we're looking for. */ diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index 1c0ebc3..2160c76 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -68,7 +68,7 @@ typedef struct { struct { union { - unsigned int reg; + _Unwind_Word reg; _Unwind_Sword offset; const unsigned char *exp; } loc; @@ -100,8 +100,8 @@ typedef struct /* 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; @@ -219,7 +219,7 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context, 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. */ @@ -232,8 +232,8 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context, /* 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; @@ -242,8 +242,8 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context, 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; @@ -300,9 +300,8 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end, 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) { @@ -379,12 +378,11 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end, 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: @@ -422,7 +420,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end, 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; @@ -458,12 +456,12 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end, 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; @@ -560,8 +558,8 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end, 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: @@ -705,17 +703,16 @@ execute_cfa_program (const unsigned char *insn_ptr, 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; } @@ -745,15 +742,15 @@ execute_cfa_program (const unsigned char *insn_ptr, 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; @@ -765,8 +762,8 @@ execute_cfa_program (const unsigned char *insn_ptr, 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; } @@ -798,60 +795,55 @@ execute_cfa_program (const unsigned char *insn_ptr, 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; @@ -865,16 +857,15 @@ execute_cfa_program (const unsigned char *insn_ptr, 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; @@ -930,7 +921,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) insn = NULL; if (fs->saw_z) { - _Unwind_Ptr i; + _Unwind_Word i; aug = read_uleb128 (aug, &i); insn = aug + i; } @@ -1039,7 +1030,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) 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) @@ -1067,7 +1058,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) 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); diff --git a/gcc/unwind-pe.h b/gcc/unwind-pe.h index 3155563..74c4e27 100644 --- a/gcc/unwind-pe.h +++ b/gcc/unwind-pe.h @@ -108,6 +108,57 @@ base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context) #endif +/* Read an unsigned leb128 value from P, store the value in VAL, return + P incremented past the value. We assume that a word is large enough to + hold any value so encoded; if it is smaller than a pointer on some target, + pointers should not be leb128 encoded on that target. */ + +static const unsigned char * +read_uleb128 (const unsigned char *p, _Unwind_Word *val) +{ + unsigned int shift = 0; + unsigned char byte; + _Unwind_Word result; + + result = 0; + do + { + byte = *p++; + result |= (byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + *val = result; + return p; +} + +/* Similar, but read a signed leb128 value. */ + +static const unsigned char * +read_sleb128 (const unsigned char *p, _Unwind_Sword *val) +{ + unsigned int shift = 0; + unsigned char byte; + _Unwind_Word result; + + result = 0; + do + { + byte = *p++; + result |= (byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + /* Sign-extend a negative value. */ + if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) + result |= -(1L << shift); + + *val = (_Unwind_Sword) result; + return p; +} + /* Load an encoded value from memory at P. The value is returned in VAL; The function returns P incremented past the value. BASE is as given by base_of_encoded_value for this encoding in the appropriate context. */ @@ -148,36 +199,17 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, case DW_EH_PE_uleb128: { - unsigned int shift = 0; - unsigned char byte; - - result = 0; - do - { - byte = *p++; - result |= (_Unwind_Ptr)(byte & 0x7f) << shift; - shift += 7; - } - while (byte & 0x80); + _Unwind_Word tmp; + p = read_uleb128 (p, &tmp); + result = (_Unwind_Ptr)tmp; } break; case DW_EH_PE_sleb128: { - unsigned int shift = 0; - unsigned char byte; - - result = 0; - do - { - byte = *p++; - result |= (_Unwind_Ptr)(byte & 0x7f) << shift; - shift += 7; - } - while (byte & 0x80); - - if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) - result |= -(1L << shift); + _Unwind_Sword tmp; + p = read_sleb128 (p, &tmp); + result = (_Unwind_Ptr)tmp; } break; @@ -239,20 +271,3 @@ read_encoded_value (struct _Unwind_Context *context, unsigned char encoding, } #endif - -/* Read an unsigned leb128 value from P, store the value in VAL, return - P incremented past the value. */ - -static inline const unsigned char * -read_uleb128 (const unsigned char *p, _Unwind_Ptr *val) -{ - return read_encoded_value_with_base (DW_EH_PE_uleb128, 0, p, val); -} - -/* Similar, but read a signed leb128 value. */ - -static inline const unsigned char * -read_sleb128 (const unsigned char *p, _Unwind_Ptr *val) -{ - return read_encoded_value_with_base (DW_EH_PE_sleb128, 0, p, val); -} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 10e7617..d4227cd 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2001-08-31 Jason Merrill + + * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Simplify + leb128 handling. + 2001-08-28 Loren J. Rittle * include/Makefile.am: Use toplevel_srcdir to refer to src files diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index 0442128..d070ced 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -84,7 +84,7 @@ parse_lsda_header (_Unwind_Context *context, const unsigned char *p, } static const std::type_info * -get_ttype_entry (lsda_header_info *info, long i) +get_ttype_entry (lsda_header_info *info, _Unwind_Word i) { _Unwind_Ptr ptr; @@ -97,14 +97,14 @@ get_ttype_entry (lsda_header_info *info, long i) static bool check_exception_spec (lsda_header_info *info, const std::type_info *throw_type, - long filter_value) + _Unwind_Sword filter_value) { const unsigned char *e = info->TType - filter_value - 1; while (1) { const std::type_info *catch_type; - _Unwind_Ptr tmp; + _Unwind_Word tmp; void *dummy; e = read_uleb128 (e, &tmp); @@ -262,7 +262,7 @@ PERSONALITY_FUNCTION (int version, { // Otherwise we have a catch handler or exception specification. - signed long ar_filter, ar_disp; + _Unwind_Sword ar_filter, ar_disp; const std::type_info *throw_type, *catch_type; bool saw_cleanup = false; bool saw_handler = false; @@ -279,11 +279,9 @@ PERSONALITY_FUNCTION (int version, while (1) { - _Unwind_Ptr tmp; - p = action_record; - p = read_sleb128 (p, &tmp); ar_filter = tmp; - read_sleb128 (p, &tmp); ar_disp = tmp; + p = read_sleb128 (p, &ar_filter); + read_sleb128 (p, &ar_disp); if (ar_filter == 0) { -- 2.7.4