diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-05-16 22:42:36 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-05-16 22:42:36 +0000 |
commit | 9b84bf7de848cc4e27b88354c441e4a2bc41abb6 (patch) | |
tree | 0115a87b72de59adf0b97d879e1d5d59187631ab /gcc/dwarf2asm.c | |
parent | 6a0bf73304d36070da7e0a443ebc5b6a1f503d4f (diff) | |
download | gcc-9b84bf7de848cc4e27b88354c441e4a2bc41abb6.tar.gz |
* except.c (eh_data_format_name): Move to ...
* dwarf2asm.c: ... here. Use designated initializers if available.
(dw2_asm_output_encoded_addr_rtx): Accept varargs commentary.
* dwarf2asm.h: Update declarations.
* dwarf2out.c (output_cfi) [DW_CFA_set_loc]: If for_eh, mind
ASM_PREFERRED_EH_DATA_FORMAT.
(output_call_frame_info): Likewise. Use 'L' augmentation for
the LSDA encoding.
* unwind-dw2-fde.h (struct fde_vector): New.
(struct old_object): Rename from struct object.
(struct object): New.
(__register_frame_info_bases): Declare.
(__register_frame_info_table_bases): Declare.
(struct dwarf_fde): Remove explicit pc_begin/pc_range members.
* unwind-dw2-fde.c (objects): Remove.
(unseen_objects, seen_objects): New.
(__register_frame_info_bases): New.
(__register_frame_info): Use it.
(__register_frame_info_table_bases): New.
(__register_frame_info_table): Use it.
(__deregister_frame_info): Rewrite for changed object struct.
(base_from_object, get_cie_encoding, get_fde_encoding): New.
(fde_unencoded_compare): Rename from fde_compare; uninline.
(fde_single_encoding_compare, fde_mixed_encoding_compare): New.
(start_fde_sort): Adjust for new definition of fde_vector.
(fde_insert): Likewise.
(end_fde_sort): Likewise. Select comparison function based
on properties of the object.
(fde_split): Take object and fde_compare_t arguments.
(frame_heapsort, fde_merge): Likewise.
(classify_object_over_fdes): Rename from count_fdes. Handle
encoded pointers. Collect encoding, mixed_encoding, and pc_begin
for the object.
(add_fdes): Handle encoded pointers.
(init_object): Rename from frame_init. Update for new struct object.
(linear_search_fdes): Rename from search_fdes. Handle encoded
pointers.
(binary_search_unencoded_fdes): Broken out from _Unwind_Find_FDE.
(binary_search_single_encoding_fdes): New.
(binary_search_mixed_encoding_fdes): New.
(search_object): New.
(_Unwind_Find_FDE): Update for new struct object. Fill in
the dwarf_eh_bases.
* unwind-dw2.c: Include unwind-pe.h. Constify all pointers
iterating over EH data.
(_Unwind_FrameState): Remove saw_lsda, addr_encoding. Add
fde_encoding, lsda_encoding.
(read_uleb128, read_sleb128): Remove.
(read_encoded_pointer): Remove. All callers use read_encoded_value.
(extract_cie_info): Set lsda_encoding from 'L' augmentation.
(uw_frame_state_for): Don't set bases.func. Handle encoded fde
pointers.
* unwind-pe.h: Add "struct" to _Unwind_Context references.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@42176 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/dwarf2asm.c')
-rw-r--r-- | gcc/dwarf2asm.c | 295 |
1 files changed, 229 insertions, 66 deletions
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c index a18607aaf82..eff9a77a509 100644 --- a/gcc/dwarf2asm.c +++ b/gcc/dwarf2asm.c @@ -470,6 +470,152 @@ size_of_encoded_value (encoding) abort (); } +/* Yield a name for a given pointer encoding. */ + +const char * +eh_data_format_name (format) + int format; +{ +#if HAVE_DESIGNATED_INITIALIZERS +#define S(p, v) [p] = v, +#else +#define S(p, v) case p: return v; +#endif + +#if HAVE_DESIGNATED_INITIALIZERS + __extension__ static const char * const format_names[256] = { +#else + switch (format) { +#endif + + S(DW_EH_PE_absptr, "absolute") + S(DW_EH_PE_omit, "omit") + + S(DW_EH_PE_uleb128, "uleb128") + S(DW_EH_PE_udata2, "udata2") + S(DW_EH_PE_udata4, "udata4") + S(DW_EH_PE_udata8, "udata8") + S(DW_EH_PE_sleb128, "sleb128") + S(DW_EH_PE_sdata2, "sdata2") + S(DW_EH_PE_sdata4, "sdata4") + S(DW_EH_PE_sdata8, "sdata8") + + S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128") + S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2") + S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4") + S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8") + S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128") + S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2") + S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4") + S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8") + + S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128") + S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2") + S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4") + S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8") + S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128") + S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2") + S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4") + S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8") + + S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128") + S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2") + S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4") + S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8") + S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128") + S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2") + S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4") + S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8") + + S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128") + S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2") + S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4") + S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8") + S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128") + S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2") + S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4") + S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8") + + S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel, + "indirect pcrel uleb128") + S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel, + "indirect pcrel udata2") + S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel, + "indirect pcrel udata4") + S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel, + "indirect pcrel udata8") + S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel, + "indirect pcrel sleb128") + S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel, + "indirect pcrel sdata2") + S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel, + "indirect pcrel sdata4") + S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel, + "indirect pcrel sdata8") + + S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel, + "indirect textrel uleb128") + S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel, + "indirect textrel udata2") + S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel, + "indirect textrel udata4") + S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel, + "indirect textrel udata8") + S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel, + "indirect textrel sleb128") + S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel, + "indirect textrel sdata2") + S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel, + "indirect textrel sdata4") + S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel, + "indirect textrel sdata8") + + S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel, + "indirect datarel uleb128") + S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel, + "indirect datarel udata2") + S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel, + "indirect datarel udata4") + S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel, + "indirect datarel udata8") + S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel, + "indirect datarel sleb128") + S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel, + "indirect datarel sdata2") + S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel, + "indirect datarel sdata4") + S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel, + "indirect datarel sdata8") + + S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel, + "indirect funcrel uleb128") + S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel, + "indirect funcrel udata2") + S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel, + "indirect funcrel udata4") + S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel, + "indirect funcrel udata8") + S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel, + "indirect funcrel sleb128") + S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel, + "indirect funcrel sdata2") + S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel, + "indirect funcrel sdata4") + S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel, + "indirect funcrel sdata8") + +#if HAVE_DESIGNATED_INITIALIZERS + }; + + if (format < 0 || format > 0xff || format_names[format] == NULL) + abort (); + return format_names[format]; +#else + } + abort (); +#endif +} + /* Output an unsigned LEB128 quantity. */ void @@ -682,6 +828,11 @@ static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *)); static splay_tree indirect_pool; +/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated + memory. Differs from force_const_mem in that a single pool is used for + the entire unit of translation, and the memory is not guaranteed to be + "near" the function in any interesting sense. */ + static rtx dw2_force_const_mem (x) rtx x; @@ -718,6 +869,9 @@ dw2_force_const_mem (x) return gen_rtx_SYMBOL_REF (Pmode, const_sym); } +/* A helper function for dw2_output_indirect_constants called through + splay_tree_foreach. Emit one queued constant to memory. */ + static int dw2_output_indirect_constant_1 (node, data) splay_tree_node node; @@ -736,6 +890,8 @@ dw2_output_indirect_constant_1 (node, data) return 0; } +/* Emit the constants queued through dw2_force_const_mem. */ + void dw2_output_indirect_constants () { @@ -754,97 +910,104 @@ dw2_output_indirect_constants () splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL); } +/* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */ + void -dw2_asm_output_encoded_addr_rtx (encoding, addr) - int encoding; - rtx addr; +dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding, + rtx addr, + const char *comment, ...)) { +#ifndef ANSI_PROTOTYPES + int encoding; + rtx addr; + const char *comment; +#endif + va_list ap; 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 (); - } + VA_START (ap, comment); + +#ifndef ANSI_PROTOTYPES + encoding = va_arg (ap, int); + addr = va_arg (ap, rtx); + comment = va_arg (ap, const char *); +#endif + + size = size_of_encoded_value (encoding); /* NULL is _always_ represented as a plain zero. */ if (addr == const0_rtx) + assemble_integer (addr, size, 1); + else { - 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. */ + 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); + 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; - } + /* 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: + 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); + fputs (unaligned_integer_asm_op (size), asm_out_file); + output_addr_const (asm_out_file, addr); #else - assemble_integer (addr, size, 1); + assemble_integer (addr, size, 1); #endif - break; + break; - case DW_EH_PE_pcrel: - if (GET_CODE (addr) != SYMBOL_REF) - abort (); + 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)); + 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); + 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 (); + abort (); #endif #endif - break; + break; - default: - /* Other encodings should have been handled by - ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */ - abort (); - } + default: + /* Other encodings should have been handled by + ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */ + abort (); + } #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX - done: + done:; #endif + } + + if (flag_debug_asm && comment) + { + fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); + vfprintf (asm_out_file, comment, ap); + } fputc ('\n', asm_out_file); + + va_end (ap); } |