diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-05-12 06:03:20 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-05-12 06:03:20 +0000 |
commit | ad5818ae60984b32185d5eed7a39444eec439055 (patch) | |
tree | 41492fd525139d18c6f3c8bd8894fcdf4cbcd139 /gcc/unwind-pe.h | |
parent | b69208e6b2b66f0bbb71ad6a8168566c688bb2db (diff) | |
download | gcc-ad5818ae60984b32185d5eed7a39444eec439055.tar.gz |
* defaults.h (ASM_PREFERRED_EH_DATA_FORMAT): New.
* dwarf2asm.c (dw2_force_const_mem, dw2_output_indirect_constant_1,
dw2_output_indirect_constants, dw2_asm_output_encoded_addr_rtx): New.
* dwarf2asm.h (dw2_asm_output_encoded_addr_rtx): Prototype.
(dw2_output_indirect_constants): Prototype.
* dwarf2out.c (dwarf2out_begin_prologue): Generate
current_function_func_begin_label if we'll need it for EH. Exit
early for IA64_UNWIND_INFO.
* except.c: Get DW_EH_PE_* defines from dwarf2.h.
(eh_data_format_name): Update for indirect references.
(output_function_exception_table): Care for IA64_UNWIND_INFO.
Handle ASM_PREFERRED_EH_DATA_FORMAT.
* except.h (MUST_USE_SJLJ_EXCEPTIONS): IA64_UNWIND_INFO needn't
define HAVE_eh_return etc.
* final.c (final_start_function): Always call dwarf2out_begin_prologue.
(final_end_function): Don't call output_function_exception_table.
* toplev.c (compile_file): Call dw2_output_indirect_constants.
(rest_of_compilation): Invoke output_function_exception_table
for ia64 before assemble_end_function.
* tm.texi (ASM_PREFERRED_EH_DATA_FORMAT): Document.
(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): Document.
* unwind-dw2.c (_Unwind_GetTextRelBase, _Unwind_GetDataRelBase): New.
* unwind.h: Declare them.
* libgcc-std.ver: Export them.
* unwind-pe.h: New file.
* config/alpha/elf.h (ASM_PREFERRED_EH_DATA_FORMAT): New.
* config/ia64/fde-glibc.c: Use "struct unw_table_entry"
instead of "fde".
(find_fde_for_dso): Extract DT_PLTGOT.
(_Unwind_FindTableEntry): Rename from __ia64_find_fde; return
the segment and gp as well.
* config/ia64/frame-ia64.c: Remove file.
* config/ia64/frame-ia64.h: Remove file.
* config/ia64/unwind-ia64.c: New file.
* config/ia64/unwind-ia64.h: New file.
* config/ia64/ia64.h (ASM_OUTPUT_EH_CHAR): Remove.
(ASM_OUTPUT_EH_SHORT, ASM_OUTPUT_EH_INT): Remove.
(ASM_OUTPUT_EH_DOUBLE_INT): Remove.
(ASM_PREFERRED_EH_DATA_FORMAT): New.
(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): New.
(IA64_UNWIND_INFO): Re-enable.
(HANDLER_SECTION): Remove.
(EH_RETURN_DATA_REGNO): New.
* config/ia64/ia64.md (exception_receiver): Remove.
* config/ia64/t-glibc (LIB2ADDEH): Re-enable.
* config/ia64/t-ia64 (LIB2ADDEH): Re-enable.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41981 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/unwind-pe.h')
-rw-r--r-- | gcc/unwind-pe.h | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/gcc/unwind-pe.h b/gcc/unwind-pe.h new file mode 100644 index 00000000000..9eda448b432 --- /dev/null +++ b/gcc/unwind-pe.h @@ -0,0 +1,208 @@ +/* Exception handling and frame unwind runtime interface routines. + Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU CC. + + 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 + 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. + + 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. */ + +/* @@@ Really this should be out of line, but this also causes link + compatibility problems with the base ABI. This is slightly better + than duplicating code, however. */ + +/* Pointer encodings, from dwarf2.h. */ +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_omit 0xff + +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_signed 0x08 + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 + +#define DW_EH_PE_indirect 0x80 + +static unsigned int +size_of_encoded_value (unsigned char encoding) +{ + if (encoding == DW_EH_PE_omit) + return 0; + + switch (encoding & 0x07) + { + case DW_EH_PE_absptr: + return sizeof (void *); + case DW_EH_PE_udata2: + return 2; + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + } + abort (); +} + +static _Unwind_Ptr +base_of_encoded_value (unsigned char encoding, _Unwind_Context *context) +{ + if (encoding == DW_EH_PE_omit) + return 0; + + switch (encoding & 0x70) + { + case DW_EH_PE_absptr: + case DW_EH_PE_pcrel: + return 0; + + case DW_EH_PE_textrel: + return _Unwind_GetTextRelBase (context); + case DW_EH_PE_datarel: + return _Unwind_GetDataRelBase (context); + case DW_EH_PE_funcrel: + return _Unwind_GetRegionStart (context); + } + abort (); +} + +static const unsigned char * +read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, + const unsigned char *p, _Unwind_Ptr *val) +{ + union unaligned + { + void *ptr; + 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__)); + + union unaligned *u = (union unaligned *) p; + _Unwind_Ptr result; + + switch (encoding & 0x0f) + { + case DW_EH_PE_absptr: + result = (_Unwind_Ptr) u->ptr; + p += sizeof (void *); + break; + + 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); + } + 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); + } + break; + + case DW_EH_PE_udata2: + result = u->u2; + p += 2; + break; + case DW_EH_PE_udata4: + result = u->u4; + p += 4; + break; + case DW_EH_PE_udata8: + result = u->u8; + p += 8; + break; + + case DW_EH_PE_sdata2: + result = u->s2; + p += 2; + break; + case DW_EH_PE_sdata4: + result = u->s4; + p += 4; + break; + case DW_EH_PE_sdata8: + result = u->s8; + p += 8; + break; + + default: + abort (); + } + + if (result != 0) + { + result += ((encoding & 0x70) == DW_EH_PE_pcrel ? (_Unwind_Ptr)u : base); + if (encoding & DW_EH_PE_indirect) + result = *(_Unwind_Ptr *)result; + } + + *val = result; + return p; +} + +static inline const unsigned char * +read_encoded_value (_Unwind_Context *context, unsigned char encoding, + const unsigned char *p, _Unwind_Ptr *val) +{ + return read_encoded_value_with_base (encoding, + base_of_encoded_value (encoding, context), + p, val); +} + +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); +} + +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); +} |