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
This commit is contained in:
parent
f2cf5c14d8
commit
e1f9550a64
|
@ -1,3 +1,60 @@
|
|||
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.
|
||||
|
|
225
gcc/dwarf2asm.c
225
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,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));
|
||||
|
|
108
gcc/dwarf2out.c
108
gcc/dwarf2out.c
|
@ -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. */
|
||||
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. */
|
||||
|
||||
/* ??? Handle pointer encodings. */
|
||||
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. */
|
||||
|
|
131
gcc/except.c
131
gcc/except.c
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
207
gcc/unwind-dw2.c
207
gcc/unwind-dw2.c
|
@ -22,6 +22,7 @@
|
|||
#include "tsystem.h"
|
||||
#include "dwarf2.h"
|
||||
#include "unwind.h"
|
||||
#include "unwind-pe.h"
|
||||
#include "unwind-dw2-fde.h"
|
||||
#include "gthr.h"
|
||||
|
||||
|
@ -69,7 +70,7 @@ typedef struct
|
|||
union {
|
||||
unsigned int reg;
|
||||
_Unwind_Sword offset;
|
||||
unsigned char *exp;
|
||||
const unsigned char *exp;
|
||||
} loc;
|
||||
enum {
|
||||
REG_UNSAVED,
|
||||
|
@ -87,7 +88,7 @@ typedef struct
|
|||
location expression. */
|
||||
_Unwind_Sword cfa_offset;
|
||||
_Unwind_Word cfa_reg;
|
||||
unsigned char *cfa_exp;
|
||||
const unsigned char *cfa_exp;
|
||||
enum {
|
||||
CFA_UNSET,
|
||||
CFA_REG_OFFSET,
|
||||
|
@ -102,57 +103,11 @@ typedef struct
|
|||
signed int data_align;
|
||||
unsigned int code_align;
|
||||
unsigned char retaddr_column;
|
||||
unsigned char addr_encoding;
|
||||
unsigned char fde_encoding;
|
||||
unsigned char lsda_encoding;
|
||||
unsigned char saw_z;
|
||||
unsigned char saw_lsda;
|
||||
} _Unwind_FrameState;
|
||||
|
||||
/* Decode the unsigned LEB128 constant at BUF into the variable pointed to
|
||||
by R, and return the new value of BUF. */
|
||||
|
||||
static unsigned char *
|
||||
read_uleb128 (unsigned char *buf, _Unwind_Word *r)
|
||||
{
|
||||
unsigned shift = 0;
|
||||
_Unwind_Word result = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
unsigned char byte = *buf++;
|
||||
result |= (byte & 0x7f) << shift;
|
||||
if ((byte & 0x80) == 0)
|
||||
break;
|
||||
shift += 7;
|
||||
}
|
||||
*r = result;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Decode the signed LEB128 constant at BUF into the variable pointed to
|
||||
by R, and return the new value of BUF. */
|
||||
|
||||
static unsigned char *
|
||||
read_sleb128 (unsigned char *buf, _Unwind_Sword *r)
|
||||
{
|
||||
unsigned shift = 0;
|
||||
_Unwind_Sword result = 0;
|
||||
unsigned char byte;
|
||||
|
||||
while (1)
|
||||
{
|
||||
byte = *buf++;
|
||||
result |= (byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
if ((byte & 0x80) == 0)
|
||||
break;
|
||||
}
|
||||
if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
|
||||
result |= - (1 << shift);
|
||||
|
||||
*r = result;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Read unaligned data from the instruction buffer. */
|
||||
|
||||
union unaligned
|
||||
|
@ -167,107 +122,31 @@ union unaligned
|
|||
} __attribute__ ((packed));
|
||||
|
||||
static inline void *
|
||||
read_pointer (void *p) { union unaligned *up = p; return up->p; }
|
||||
read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
|
||||
|
||||
static inline int
|
||||
read_1u (void *p) { return *(unsigned char *)p; }
|
||||
read_1u (const void *p) { return *(const unsigned char *)p; }
|
||||
|
||||
static inline int
|
||||
read_1s (void *p) { return *(signed char *)p; }
|
||||
read_1s (const void *p) { return *(const signed char *)p; }
|
||||
|
||||
static inline int
|
||||
read_2u (void *p) { union unaligned *up = p; return up->u2; }
|
||||
read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
|
||||
|
||||
static inline int
|
||||
read_2s (void *p) { union unaligned *up = p; return up->s2; }
|
||||
read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
|
||||
|
||||
static inline unsigned int
|
||||
read_4u (void *p) { union unaligned *up = p; return up->u4; }
|
||||
read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
|
||||
|
||||
static inline int
|
||||
read_4s (void *p) { union unaligned *up = p; return up->s4; }
|
||||
read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
|
||||
|
||||
static inline unsigned long
|
||||
read_8u (void *p) { union unaligned *up = p; return up->u8; }
|
||||
read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
|
||||
|
||||
static inline unsigned long
|
||||
read_8s (void *p) { union unaligned *up = p; return up->s8; }
|
||||
|
||||
static unsigned char *
|
||||
read_encoded_pointer (unsigned char *p, unsigned char encoding,
|
||||
struct dwarf_eh_bases *bases, void **pptr)
|
||||
{
|
||||
signed long val;
|
||||
unsigned char *ret;
|
||||
|
||||
switch (encoding & 0x0f)
|
||||
{
|
||||
case DW_EH_PE_absptr:
|
||||
val = (_Unwind_Ptr) read_pointer (p);
|
||||
ret = p + sizeof (void *);
|
||||
break;
|
||||
|
||||
case DW_EH_PE_uleb128:
|
||||
ret = read_uleb128 (p, &val);
|
||||
break;
|
||||
case DW_EH_PE_sleb128:
|
||||
ret = read_sleb128 (p, &val);
|
||||
break;
|
||||
|
||||
case DW_EH_PE_udata2:
|
||||
val = read_2u (p);
|
||||
ret = p + 2;
|
||||
break;
|
||||
case DW_EH_PE_udata4:
|
||||
val = read_4u (p);
|
||||
ret = p + 4;
|
||||
break;
|
||||
case DW_EH_PE_udata8:
|
||||
val = read_8u (p);
|
||||
ret = p + 8;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_sdata2:
|
||||
val = read_2s (p);
|
||||
ret = p + 2;
|
||||
break;
|
||||
case DW_EH_PE_sdata4:
|
||||
val = read_4s (p);
|
||||
ret = p + 4;
|
||||
break;
|
||||
case DW_EH_PE_sdata8:
|
||||
val = read_8s (p);
|
||||
ret = p + 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (val != 0)
|
||||
switch (encoding & 0xf0)
|
||||
{
|
||||
case DW_EH_PE_absptr:
|
||||
break;
|
||||
case DW_EH_PE_pcrel:
|
||||
val += (_Unwind_Ptr) p;
|
||||
break;
|
||||
case DW_EH_PE_textrel:
|
||||
val += (_Unwind_Ptr) bases->tbase;
|
||||
break;
|
||||
case DW_EH_PE_datarel:
|
||||
val += (_Unwind_Ptr) bases->dbase;
|
||||
break;
|
||||
case DW_EH_PE_funcrel:
|
||||
val += (_Unwind_Ptr) bases->func;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
*pptr = (void *) (_Unwind_Ptr) val;
|
||||
return ret;
|
||||
}
|
||||
read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
|
||||
|
||||
/* Get the value of register REG as saved in CONTEXT. */
|
||||
|
||||
|
@ -332,13 +211,13 @@ _Unwind_GetTextRelBase (struct _Unwind_Context *context)
|
|||
unit F belongs to. Return a pointer to the byte after the augmentation,
|
||||
or NULL if we encountered an undecipherable augmentation. */
|
||||
|
||||
static unsigned char *
|
||||
static const unsigned char *
|
||||
extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
unsigned char *aug = cie->augmentation;
|
||||
unsigned char *p = aug + strlen (aug) + 1;
|
||||
unsigned char *ret = NULL;
|
||||
const unsigned char *aug = cie->augmentation;
|
||||
const unsigned char *p = aug + strlen (aug) + 1;
|
||||
const unsigned char *ret = NULL;
|
||||
_Unwind_Word code_align;
|
||||
_Unwind_Sword data_align;
|
||||
|
||||
|
@ -349,6 +228,7 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
|
|||
fs->code_align = code_align;
|
||||
fs->data_align = data_align;
|
||||
fs->retaddr_column = *p++;
|
||||
fs->lsda_encoding = DW_EH_PE_omit;
|
||||
|
||||
/* If the augmentation starts with 'z', then a uleb128 immediately
|
||||
follows containing the length of the augmentation field following
|
||||
|
@ -373,20 +253,25 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
|
|||
aug += 2;
|
||||
}
|
||||
|
||||
/* "R" indicates a byte indicating how addresses are encoded. */
|
||||
else if (aug[0] == 'R')
|
||||
/* "L" indicates a byte showing how the LSDA pointer is encoded. */
|
||||
else if (aug[0] == 'L')
|
||||
{
|
||||
fs->addr_encoding = *p++;
|
||||
fs->lsda_encoding = *p++;
|
||||
aug += 1;
|
||||
}
|
||||
|
||||
/* "P" indicates a personality routine in the CIE augmentation
|
||||
and an lsda pointer in the FDE augmentation. */
|
||||
/* "R" indicates a byte indicating how FDE addresses are encoded. */
|
||||
else if (aug[0] == 'R')
|
||||
{
|
||||
fs->fde_encoding = *p++;
|
||||
aug += 1;
|
||||
}
|
||||
|
||||
/* "P" indicates a personality routine in the CIE augmentation. */
|
||||
else if (aug[0] == 'P')
|
||||
{
|
||||
p = read_encoded_pointer (p, fs->addr_encoding, &context->bases,
|
||||
(void **) &fs->personality);
|
||||
fs->saw_lsda = 1;
|
||||
p = read_encoded_value (context, *p, p + 1,
|
||||
(_Unwind_Ptr *) &fs->personality);
|
||||
aug += 1;
|
||||
}
|
||||
|
||||
|
@ -404,7 +289,7 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
|
|||
onto the stack to start. */
|
||||
|
||||
static _Unwind_Word
|
||||
execute_stack_op (unsigned char *op_ptr, unsigned char *op_end,
|
||||
execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
|
||||
struct _Unwind_Context *context, _Unwind_Word initial)
|
||||
{
|
||||
_Unwind_Word stack[64]; /* ??? Assume this is enough. */
|
||||
|
@ -800,8 +685,10 @@ execute_stack_op (unsigned char *op_ptr, unsigned char *op_end,
|
|||
CIE info, and the PC range to evaluate. */
|
||||
|
||||
static void
|
||||
execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end,
|
||||
struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
execute_cfa_program (const unsigned char *insn_ptr,
|
||||
const unsigned char *insn_end,
|
||||
struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
struct frame_state_reg_info *unused_rs = NULL;
|
||||
|
||||
|
@ -832,8 +719,8 @@ execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end,
|
|||
else switch (insn)
|
||||
{
|
||||
case DW_CFA_set_loc:
|
||||
insn_ptr = read_encoded_pointer (insn_ptr, fs->addr_encoding,
|
||||
&context->bases, &fs->pc);
|
||||
insn_ptr = read_encoded_value (context, fs->fde_encoding,
|
||||
insn_ptr, (_Unwind_Ptr *) &fs->pc);
|
||||
break;
|
||||
|
||||
case DW_CFA_advance_loc1:
|
||||
|
@ -989,7 +876,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
|||
{
|
||||
struct dwarf_fde *fde;
|
||||
struct dwarf_cie *cie;
|
||||
unsigned char *aug, *insn, *end;
|
||||
const unsigned char *aug, *insn, *end;
|
||||
|
||||
memset (fs, 0, sizeof (*fs));
|
||||
context->args_size = 0;
|
||||
|
@ -1011,8 +898,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
|||
#endif
|
||||
}
|
||||
|
||||
context->bases.func = fde->pc_begin;
|
||||
fs->pc = fde->pc_begin;
|
||||
fs->pc = context->bases.func;
|
||||
|
||||
cie = get_cie (fde);
|
||||
insn = extract_cie_info (cie, context, fs);
|
||||
|
@ -1026,6 +912,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
|||
|
||||
/* Locate augmentation for the fde. */
|
||||
aug = (unsigned char *)fde + sizeof (*fde);
|
||||
aug += 2 * size_of_encoded_value (fs->fde_encoding);
|
||||
insn = NULL;
|
||||
if (fs->saw_z)
|
||||
{
|
||||
|
@ -1033,9 +920,9 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
|||
aug = read_uleb128 (aug, &i);
|
||||
insn = aug + i;
|
||||
}
|
||||
if (fs->saw_lsda)
|
||||
aug = read_encoded_pointer (aug, fs->addr_encoding,
|
||||
&context->bases, &context->lsda);
|
||||
if (fs->lsda_encoding != DW_EH_PE_omit)
|
||||
aug = read_encoded_value (context, fs->lsda_encoding, aug,
|
||||
(_Unwind_Ptr *) &context->lsda);
|
||||
|
||||
/* Then the insns in the FDE up to our target PC. */
|
||||
if (insn == NULL)
|
||||
|
@ -1076,7 +963,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
|||
CFA calculation is so complicated as to require a stack program
|
||||
that this will not be a problem. */
|
||||
{
|
||||
unsigned char *exp = fs->cfa_exp;
|
||||
const unsigned char *exp = fs->cfa_exp;
|
||||
_Unwind_Word len;
|
||||
|
||||
exp = read_uleb128 (exp, &len);
|
||||
|
@ -1104,7 +991,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
|||
break;
|
||||
case REG_SAVED_EXP:
|
||||
{
|
||||
unsigned char *exp = fs->regs.reg[i].loc.exp;
|
||||
const unsigned char *exp = fs->regs.reg[i].loc.exp;
|
||||
_Unwind_Word len;
|
||||
_Unwind_Ptr val;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue