Commit e1f9550a by Richard Henderson Committed by Richard Henderson

except.c (eh_data_format_name): Move to ...

	* 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.

From-SVN: r42176
parent f2cf5c14
2001-05-16 Richard Henderson <rth@redhat.com>
* 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.
2001-05-16 Neil Booth <neil@cat.daikokuya.demon.co.uk>
* cppexp.c (lex): Use NODE_NAME and NODE_LEN.
......
......@@ -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,56 +910,54 @@ 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)
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);
return;
}
else
{
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. */
/* 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). */
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;
......@@ -844,7 +998,16 @@ dw2_asm_output_encoded_addr_rtx (encoding, addr)
}
#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);
}
......@@ -48,7 +48,9 @@ extern void dw2_asm_output_addr_rtx PARAMS ((int, rtx,
const char *, ...))
/* ATTRIBUTE_PRINTF_3 */;
extern void dw2_asm_output_encoded_addr_rtx PARAMS ((int, rtx));
extern void dw2_asm_output_encoded_addr_rtx PARAMS ((int, rtx,
const char *, ...))
/* ATTRIBUTE_PRINTF_3 */;
extern void dw2_asm_output_nstring PARAMS ((const char *, size_t,
const char *, ...))
......@@ -73,5 +75,6 @@ extern void dw2_asm_output_delta_sleb128 PARAMS ((const char *, const char *,
extern int size_of_uleb128 PARAMS ((unsigned HOST_WIDE_INT));
extern int size_of_sleb128 PARAMS ((HOST_WIDE_INT));
extern int size_of_encoded_value PARAMS ((int));
extern const char *eh_data_format_name PARAMS ((int));
extern void dw2_output_indirect_constants PARAMS ((void));
......@@ -1649,7 +1649,13 @@ output_cfi (cfi, fde, for_eh)
switch (cfi->dw_cfi_opc)
{
case DW_CFA_set_loc:
dw2_asm_output_addr ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE),
if (for_eh)
dw2_asm_output_encoded_addr_rtx (
ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0),
gen_rtx_SYMBOL_REF (Pmode, cfi->dw_cfi_oprnd1.dw_cfi_addr),
NULL);
else
dw2_asm_output_addr (DWARF2_ADDR_SIZE,
cfi->dw_cfi_oprnd1.dw_cfi_addr, NULL);
break;
case DW_CFA_advance_loc1:
......@@ -1717,6 +1723,10 @@ output_call_frame_info (for_eh)
char l1[20], l2[20];
int any_lsda_needed = 0;
char augmentation[6];
int augmentation_size;
int fde_encoding = DW_EH_PE_absptr;
int per_encoding = DW_EH_PE_absptr;
int lsda_encoding = DW_EH_PE_absptr;
/* If we don't have any functions we'll want to unwind out of, don't
emit any EH unwind information. */
......@@ -1770,20 +1780,46 @@ output_call_frame_info (for_eh)
dw2_asm_output_data (1, DW_CIE_VERSION, "CIE Version");
augmentation[0] = 0;
augmentation_size = 0;
if (for_eh)
{
char *p;
/* Augmentation:
z Indicates that a uleb128 is present to size the
augmentation section.
R Indicates a pointer encoding for CIE and FDE pointers.
P Indicates the presence of a language personality
routine in the CIE augmentation and an LSDA in the
FDE augmentation. */
/* ??? Handle pointer encodings. */
L Indicates the encoding (and thus presence) of
an LSDA pointer in the FDE augmentation.
R Indicates a non-default pointer encoding for
FDE code pointers.
P Indicates the presence of an encoding + language
personality routine in the CIE augmentation. */
fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
p = augmentation + 1;
if (eh_personality_libfunc)
{
*p++ = 'P';
augmentation_size += 1 + size_of_encoded_value (per_encoding);
}
if (any_lsda_needed)
strcpy (augmentation, "zP");
{
*p++ = 'L';
augmentation_size += 1;
}
if (fde_encoding != DW_EH_PE_absptr)
{
*p++ = 'R';
augmentation_size += 1;
}
if (p > augmentation + 1)
{
augmentation[0] = 'z';
*p = '\0';
}
}
dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation");
......@@ -1796,12 +1832,20 @@ output_call_frame_info (for_eh)
if (augmentation[0])
{
dw2_asm_output_data_uleb128 (PTR_SIZE, "Augmentation size");
dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
if (eh_personality_libfunc)
dw2_asm_output_addr_rtx (PTR_SIZE, eh_personality_libfunc,
"Personality");
else
dw2_asm_output_data (PTR_SIZE, 0, "Personality (none)");
{
dw2_asm_output_data (1, per_encoding, "Personality (%s)",
eh_data_format_name (per_encoding));
dw2_asm_output_encoded_addr_rtx (per_encoding,
eh_personality_libfunc, NULL);
}
if (any_lsda_needed)
dw2_asm_output_data (1, lsda_encoding, "LSDA Encoding (%s)",
eh_data_format_name (lsda_encoding));
if (fde_encoding != DW_EH_PE_absptr)
dw2_asm_output_data (1, fde_encoding, "FDE Encoding (%s)",
eh_data_format_name (fde_encoding));
}
for (cfi = cie_cfi_head; cfi != NULL; cfi = cfi->dw_cfi_next)
......@@ -1843,30 +1887,46 @@ output_call_frame_info (for_eh)
stripattributes (FRAME_SECTION),
"FDE CIE offset");
dw2_asm_output_addr ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE),
fde->dw_fde_begin,
if (for_eh)
{
dw2_asm_output_encoded_addr_rtx (fde_encoding,
gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
"FDE initial location");
dw2_asm_output_delta ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE),
fde->dw_fde_end,
fde->dw_fde_begin,
dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
fde->dw_fde_end, fde->dw_fde_begin,
"FDE address range");
}
else
{
dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin,
"FDE initial location");
dw2_asm_output_delta (DWARF2_ADDR_SIZE,
fde->dw_fde_end, fde->dw_fde_begin,
"FDE address range");
}
if (augmentation[0])
{
dw2_asm_output_data_uleb128 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE),
"Augmentation size");
if (any_lsda_needed)
{
dw2_asm_output_data_uleb128 (
size_of_encoded_value (lsda_encoding), "Augmentation size");
if (fde->uses_eh_lsda)
{
ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA", fde->funcdef_number);
dw2_asm_output_offset ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE),
l1, "Language Specific Data Area");
ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA",
fde->funcdef_number);
dw2_asm_output_encoded_addr_rtx (
lsda_encoding, gen_rtx_SYMBOL_REF (Pmode, l1),
"Language Specific Data Area");
}
else
dw2_asm_output_data ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE),
dw2_asm_output_data (size_of_encoded_value (lsda_encoding),
0, "Language Specific Data Area (none)");
}
else
dw2_asm_output_data_uleb128 (0, "Augmentation size");
}
/* Loop through the Call Frame Instructions associated with
this FDE. */
......
......@@ -330,7 +330,6 @@ static int add_call_site PARAMS ((rtx, int));
static void push_uleb128 PARAMS ((varray_type *,
unsigned int));
static void push_sleb128 PARAMS ((varray_type *, int));
static const char *eh_data_format_name PARAMS ((int));
#ifndef HAVE_AS_LEB128
static int dw2_size_of_call_site_table PARAMS ((void));
static int sjlj_size_of_call_site_table PARAMS ((void));
......@@ -3367,133 +3366,6 @@ push_sleb128 (data_area, value)
}
static const char *
eh_data_format_name (format)
int format;
{
switch (format)
{
case DW_EH_PE_absptr: return "absolute";
case DW_EH_PE_omit: return "omit";
case DW_EH_PE_uleb128: return "uleb128";
case DW_EH_PE_udata2: return "udata2";
case DW_EH_PE_udata4: return "udata4";
case DW_EH_PE_udata8: return "udata8";
case DW_EH_PE_sleb128: return "sleb128";
case DW_EH_PE_sdata2: return "sdata2";
case DW_EH_PE_sdata4: return "sdata4";
case DW_EH_PE_sdata8: return "sdata8";
case DW_EH_PE_uleb128 | DW_EH_PE_pcrel: return "pcrel uleb128";
case DW_EH_PE_udata2 | DW_EH_PE_pcrel: return "pcrel udata2";
case DW_EH_PE_udata4 | DW_EH_PE_pcrel: return "pcrel udata4";
case DW_EH_PE_udata8 | DW_EH_PE_pcrel: return "pcrel udata8";
case DW_EH_PE_sleb128 | DW_EH_PE_pcrel: return "pcrel sleb128";
case DW_EH_PE_sdata2 | DW_EH_PE_pcrel: return "pcrel sdata2";
case DW_EH_PE_sdata4 | DW_EH_PE_pcrel: return "pcrel sdata4";
case DW_EH_PE_sdata8 | DW_EH_PE_pcrel: return "pcrel sdata8";
case DW_EH_PE_uleb128 | DW_EH_PE_textrel: return "textrel uleb128";
case DW_EH_PE_udata2 | DW_EH_PE_textrel: return "textrel udata2";
case DW_EH_PE_udata4 | DW_EH_PE_textrel: return "textrel udata4";
case DW_EH_PE_udata8 | DW_EH_PE_textrel: return "textrel udata8";
case DW_EH_PE_sleb128 | DW_EH_PE_textrel: return "textrel sleb128";
case DW_EH_PE_sdata2 | DW_EH_PE_textrel: return "textrel sdata2";
case DW_EH_PE_sdata4 | DW_EH_PE_textrel: return "textrel sdata4";
case DW_EH_PE_sdata8 | DW_EH_PE_textrel: return "textrel sdata8";
case DW_EH_PE_uleb128 | DW_EH_PE_datarel: return "datarel uleb128";
case DW_EH_PE_udata2 | DW_EH_PE_datarel: return "datarel udata2";
case DW_EH_PE_udata4 | DW_EH_PE_datarel: return "datarel udata4";
case DW_EH_PE_udata8 | DW_EH_PE_datarel: return "datarel udata8";
case DW_EH_PE_sleb128 | DW_EH_PE_datarel: return "datarel sleb128";
case DW_EH_PE_sdata2 | DW_EH_PE_datarel: return "datarel sdata2";
case DW_EH_PE_sdata4 | DW_EH_PE_datarel: return "datarel sdata4";
case DW_EH_PE_sdata8 | DW_EH_PE_datarel: return "datarel sdata8";
case DW_EH_PE_uleb128 | DW_EH_PE_funcrel: return "funcrel uleb128";
case DW_EH_PE_udata2 | DW_EH_PE_funcrel: return "funcrel udata2";
case DW_EH_PE_udata4 | DW_EH_PE_funcrel: return "funcrel udata4";
case DW_EH_PE_udata8 | DW_EH_PE_funcrel: return "funcrel udata8";
case DW_EH_PE_sleb128 | DW_EH_PE_funcrel: return "funcrel sleb128";
case DW_EH_PE_sdata2 | DW_EH_PE_funcrel: return "funcrel sdata2";
case DW_EH_PE_sdata4 | DW_EH_PE_funcrel: return "funcrel sdata4";
case DW_EH_PE_sdata8 | DW_EH_PE_funcrel: return "funcrel sdata8";
case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel:
return "indirect pcrel uleb128";
case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel:
return "indirect pcrel udata2";
case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel:
return "indirect pcrel udata4";
case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel:
return "indirect pcrel udata8";
case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel:
return "indirect pcrel sleb128";
case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel:
return "indirect pcrel sdata2";
case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel:
return "indirect pcrel sdata4";
case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel:
return "indirect pcrel sdata8";
case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel:
return "indirect textrel uleb128";
case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel:
return "indirect textrel udata2";
case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel:
return "indirect textrel udata4";
case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel:
return "indirect textrel udata8";
case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel:
return "indirect textrel sleb128";
case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel:
return "indirect textrel sdata2";
case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel:
return "indirect textrel sdata4";
case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel:
return "indirect textrel sdata8";
case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel:
return "indirect datarel uleb128";
case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel:
return "indirect datarel udata2";
case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel:
return "indirect datarel udata4";
case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel:
return "indirect datarel udata8";
case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel:
return "indirect datarel sleb128";
case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel:
return "indirect datarel sdata2";
case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel:
return "indirect datarel sdata4";
case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel:
return "indirect datarel sdata8";
case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel:
return "indirect funcrel uleb128";
case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel:
return "indirect funcrel udata2";
case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel:
return "indirect funcrel udata4";
case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel:
return "indirect funcrel udata8";
case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel:
return "indirect funcrel sleb128";
case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel:
return "indirect funcrel sdata2";
case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel:
return "indirect funcrel sdata4";
case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel:
return "indirect funcrel sdata8";
default:
abort ();
}
}
#ifndef HAVE_AS_LEB128
static int
dw2_size_of_call_site_table ()
......@@ -3767,7 +3639,8 @@ output_function_exception_table ()
dw2_asm_output_encoded_addr_rtx (tt_format,
expand_expr (type, NULL_RTX, VOIDmode,
EXPAND_INITIALIZER));
EXPAND_INITIALIZER),
NULL);
}
#ifdef HAVE_AS_LEB128
......
......@@ -29,15 +29,52 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Describes data used to hold onto one shared object or object file. */
struct fde_vector
{
void *orig_data;
size_t count;
struct dwarf_fde *array[];
};
struct object
{
void *pc_begin;
void *tbase;
void *dbase;
union {
struct dwarf_fde *single;
struct dwarf_fde **array;
struct fde_vector *sort;
} u;
union {
struct {
unsigned long sorted : 1;
unsigned long from_array : 1;
unsigned long mixed_encoding : 1;
unsigned long encoding : 8;
/* ??? Wish there was an easy way to detect a 64-bit host here;
we've got 32 bits left to play with... */
unsigned long count : 21;
} b;
size_t i;
} s;
struct object *next;
};
/* This is the original definition of struct object. While the struct
itself was opaque to users, they did know how large it was, and
allocate one statically in crtbegin for each DSO. Keep this around
so that we're aware of the static size limitations for the new struct. */
struct old_object
{
void *pc_begin;
void *pc_end;
struct dwarf_fde *fde_begin;
struct dwarf_fde **fde_array;
size_t count;
struct object *next;
struct old_object *next;
};
struct dwarf_eh_bases
......@@ -48,8 +85,12 @@ struct dwarf_eh_bases
};
extern void __register_frame_info_bases (void *, struct object *,
void *, void *);
extern void __register_frame_info (void *, struct object *);
extern void __register_frame (void *);
extern void __register_frame_info_table_bases (void *, struct object *,
void *, void *);
extern void __register_frame_info_table (void *, struct object *);
extern void __register_frame_table (void *);
extern void *__deregister_frame_info (void *);
......@@ -97,8 +138,7 @@ struct dwarf_fde
{
uword length;
sword CIE_delta;
void * pc_begin;
uaddr pc_range;
unsigned char pc_begin[];
} __attribute__ ((packed, aligned (__alignof__ (void *))));
typedef struct dwarf_fde fde;
......
......@@ -74,7 +74,7 @@ size_of_encoded_value (unsigned char encoding)
not available. */
static _Unwind_Ptr
base_of_encoded_value (unsigned char encoding, _Unwind_Context *context)
base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
{
if (encoding == DW_EH_PE_omit)
return 0;
......@@ -204,7 +204,7 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
rather than providing it directly. */
static inline const unsigned char *
read_encoded_value (_Unwind_Context *context, unsigned char encoding,
read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
const unsigned char *p, _Unwind_Ptr *val)
{
return read_encoded_value_with_base (encoding,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment