summaryrefslogtreecommitdiff
path: root/gcc/dwarf2asm.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-05-16 22:42:36 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-05-16 22:42:36 +0000
commit9b84bf7de848cc4e27b88354c441e4a2bc41abb6 (patch)
tree0115a87b72de59adf0b97d879e1d5d59187631ab /gcc/dwarf2asm.c
parent6a0bf73304d36070da7e0a443ebc5b6a1f503d4f (diff)
downloadgcc-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.c295
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);
}