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/dwarf2asm.c | |
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/dwarf2asm.c')
-rw-r--r-- | gcc/dwarf2asm.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c index 98667350efb..104879e4660 100644 --- a/gcc/dwarf2asm.c +++ b/gcc/dwarf2asm.c @@ -22,9 +22,13 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" #include "flags.h" +#include "tree.h" #include "rtl.h" #include "output.h" #include "dwarf2asm.h" +#include "dwarf2.h" +#include "splay-tree.h" +#include "ggc.h" #include "tm_p.h" @@ -647,3 +651,175 @@ dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED, va_end (ap); } + +static rtx dw2_force_const_mem PARAMS ((rtx)); +static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *)); + +static splay_tree indirect_pool; + +static rtx +dw2_force_const_mem (x) + rtx x; +{ + splay_tree_node node; + const char *const_sym; + + if (! indirect_pool) + indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL); + + if (GET_CODE (x) != SYMBOL_REF) + abort (); + node = splay_tree_lookup (indirect_pool, (splay_tree_key) XSTR (x, 0)); + if (node) + const_sym = (const char *) node->value; + else + { + extern int const_labelno; + char label[32]; + tree id; + + ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno); + ++const_labelno; + const_sym = ggc_strdup (label); + + id = maybe_get_identifier (XSTR (x, 0)); + if (id) + TREE_SYMBOL_REFERENCED (id) = 1; + + splay_tree_insert (indirect_pool, (splay_tree_key) XSTR (x, 0), + (splay_tree_value) const_sym); + } + + return gen_rtx_SYMBOL_REF (Pmode, const_sym); +} + +static int +dw2_output_indirect_constant_1 (node, data) + splay_tree_node node; + void* data ATTRIBUTE_UNUSED; +{ + const char *label, *sym; + rtx sym_ref; + + label = (const char *) node->value; + sym = (const char *) node->key; + sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym); + + ASM_OUTPUT_LABEL (asm_out_file, label); + assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, 1); + + return 0; +} + +void +dw2_output_indirect_constants () +{ + if (! indirect_pool) + return; + + /* Assume that the whole reason we're emitting these symbol references + indirectly is that they contain dynamic relocations, and are thus + read-write. If there was no possibility of a dynamic relocation, we + might as well have used a direct relocation. */ + data_section (); + + /* Everything we're emitting is a pointer. Align appropriately. */ + assemble_align (POINTER_SIZE); + + splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL); +} + +void +dw2_asm_output_encoded_addr_rtx (encoding, addr) + int encoding; + rtx addr; +{ + int size; + + switch (encoding & 0x07) + { + case DW_EH_PE_absptr: + size = POINTER_SIZE / BITS_PER_UNIT; + break; + case DW_EH_PE_udata2: + size = 2; + break; + case DW_EH_PE_udata4: + size = 4; + break; + case DW_EH_PE_udata8: + size = 8; + break; + default: + abort (); + } + + /* NULL is _always_ represented as a plain zero. */ + if (addr == const0_rtx) + { + assemble_integer (addr, size, 1); + return; + } + + restart: + + /* Allow the target first crack at emitting this. Some of the + special relocations require special directives instead of + just ".4byte" or whatever. */ +#ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX + ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(asm_out_file, encoding, size, addr, done); +#endif + + /* Indirection is used to get dynamic relocations out of a read-only + section. */ + if (encoding & DW_EH_PE_indirect) + { + /* It is very tempting to use force_const_mem so that we share data + with the normal constant pool. However, we've already emitted + the constant pool for this function. Moreover, we'd like to share + these constants across the entire unit of translation, or better, + across the entire application (or DSO). */ + addr = dw2_force_const_mem (addr); + encoding &= ~DW_EH_PE_indirect; + goto restart; + } + + switch (encoding & 0xF0) + { + case DW_EH_PE_absptr: +#ifdef UNALIGNED_INT_ASM_OP + fputs (unaligned_integer_asm_op (size), asm_out_file); + output_addr_const (asm_out_file, addr); +#else + assemble_integer (addr, size, 1); +#endif + break; + + case DW_EH_PE_pcrel: + if (GET_CODE (addr) != SYMBOL_REF) + abort (); +#ifdef ASM_OUTPUT_DWARF_PCREL + ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0)); +#else +#ifdef UNALIGNED_INT_ASM_OP + fputs (unaligned_integer_asm_op (size), asm_out_file); + assemble_name (asm_out_file, XSTR (addr, 0)); + fputc ('-', asm_out_file); + fputc ('.', asm_out_file); +#else + abort (); +#endif +#endif + break; + + default: + /* Other encodings should have been handled by + ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */ + abort (); + } + +#ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX + done: +#endif + fputc ('\n', asm_out_file); +} |