Commit 099c8b17 by Richard Henderson

dwarf2.h (DW_EH_PE_aligned): New.

        * dwarf2.h (DW_EH_PE_aligned): New.
        * dwarf2asm.c (eh_data_format_name): Name it.
        (dw2_asm_output_encoded_addr_rtx): Align for it.
        * dwarf2out.c (output_call_frame_info): Handle it for personality
        routine and LSDA pointers.

        * unwind-pe.h (DW_EH_PE_aligned): New.
        (base_of_encoded_value): Handle it.
        (read_encoded_value_with_base): Likewise.
        * unwind-dw2-fde.c (base_from_object): Likewise.
        (get_cie_encoding): Likewise.

        * config/alpha/elf.h: Remove ecoff commentary.
        * config/alpha/osf.h (ASM_PREFERRED_EH_DATA_FORMAT): New.

From-SVN: r42926
parent c51f6c6b
2001-06-05 Richard Henderson <rth@redhat.com>
* dwarf2.h (DW_EH_PE_aligned): New.
* dwarf2asm.c (eh_data_format_name): Name it.
(dw2_asm_output_encoded_addr_rtx): Align for it.
* dwarf2out.c (output_call_frame_info): Handle it for personality
routine and LSDA pointers.
* unwind-pe.h (DW_EH_PE_aligned): New.
(base_of_encoded_value): Handle it.
(read_encoded_value_with_base): Likewise.
* unwind-dw2-fde.c (base_from_object): Likewise.
(get_cie_encoding): Likewise.
* config/alpha/elf.h: Remove ecoff commentary.
* config/alpha/osf.h (ASM_PREFERRED_EH_DATA_FORMAT): New.
2001-06-05 David O'Brien <obrien@FreeBSD.org> 2001-06-05 David O'Brien <obrien@FreeBSD.org>
* config.gcc, config/i386/bsd386.h: Do not directly include * config.gcc, config/i386/bsd386.h: Do not directly include
......
...@@ -686,8 +686,6 @@ void FN () \ ...@@ -686,8 +686,6 @@ void FN () \
#undef UNALIGNED_INT_ASM_OP #undef UNALIGNED_INT_ASM_OP
#undef UNALIGNED_DOUBLE_INT_ASM_OP #undef UNALIGNED_DOUBLE_INT_ASM_OP
/* ??? This should be possible for ECOFF as well, since the relocations
exist. But the assembler doesn't seem to create them. */
/* Select a format to encode pointers in exception handling data. CODE /* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. true if the symbol may be affected by dynamic relocations.
......
...@@ -153,3 +153,17 @@ __enable_execute_stack (addr) \ ...@@ -153,3 +153,17 @@ __enable_execute_stack (addr) \
#define HAS_INIT_SECTION #define HAS_INIT_SECTION
#define LD_INIT_SWITCH "-init" #define LD_INIT_SWITCH "-init"
#define LD_FINI_SWITCH "-fini" #define LD_FINI_SWITCH "-fini"
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations.
We really ought to be using the SREL32 relocations that ECOFF has,
but no version of the native assembler supports creating such things,
and Compaq has no plans to rectify this. Worse, the dynamic loader
cannot handle unaligned relocations, so we have to make sure that
things get padded appropriately. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
(TARGET_GAS \
? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \
: DW_EH_PE_aligned)
...@@ -580,5 +580,6 @@ enum dwarf_macinfo_record_type ...@@ -580,5 +580,6 @@ enum dwarf_macinfo_record_type
#define DW_EH_PE_textrel 0x20 #define DW_EH_PE_textrel 0x20
#define DW_EH_PE_datarel 0x30 #define DW_EH_PE_datarel 0x30
#define DW_EH_PE_funcrel 0x40 #define DW_EH_PE_funcrel 0x40
#define DW_EH_PE_aligned 0x50
#define DW_EH_PE_indirect 0x80 #define DW_EH_PE_indirect 0x80
...@@ -490,6 +490,7 @@ eh_data_format_name (format) ...@@ -490,6 +490,7 @@ eh_data_format_name (format)
S(DW_EH_PE_absptr, "absolute") S(DW_EH_PE_absptr, "absolute")
S(DW_EH_PE_omit, "omit") S(DW_EH_PE_omit, "omit")
S(DW_EH_PE_aligned, "aligned absolute")
S(DW_EH_PE_uleb128, "uleb128") S(DW_EH_PE_uleb128, "uleb128")
S(DW_EH_PE_udata2, "udata2") S(DW_EH_PE_udata2, "udata2")
...@@ -947,6 +948,12 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding, ...@@ -947,6 +948,12 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
size = size_of_encoded_value (encoding); size = size_of_encoded_value (encoding);
if (encoding == DW_EH_PE_aligned)
{
assemble_align (POINTER_SIZE);
encoding = DW_EH_PE_absptr;
}
/* NULL is _always_ represented as a plain zero. */ /* NULL is _always_ represented as a plain zero. */
if (addr == const0_rtx) if (addr == const0_rtx)
assemble_integer (addr, size, 1); assemble_integer (addr, size, 1);
......
...@@ -1820,6 +1820,28 @@ output_call_frame_info (for_eh) ...@@ -1820,6 +1820,28 @@ output_call_frame_info (for_eh)
augmentation[0] = 'z'; augmentation[0] = 'z';
*p = '\0'; *p = '\0';
} }
/* Ug. Some platforms can't do unaligned dynamic relocations at all. */
if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned)
{
int offset = ( 4 /* Length */
+ 4 /* CIE Id */
+ 1 /* CIE version */
+ strlen (augmentation) + 1 /* Augmentation */
+ size_of_uleb128 (1) /* Code alignment */
+ size_of_sleb128 (DWARF_CIE_DATA_ALIGNMENT)
+ 1 /* RA column */
+ 1 /* Augmentation size */
+ 1 /* Personality encoding */ );
int pad = -offset & (PTR_SIZE - 1);
augmentation_size += pad;
/* Augmentations should be small, so there's scarce need to
iterate for a solution. Die if we exceed one uleb128 byte. */
if (size_of_uleb128 (augmentation_size) != 1)
abort ();
}
} }
dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation"); dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation");
...@@ -1909,8 +1931,22 @@ output_call_frame_info (for_eh) ...@@ -1909,8 +1931,22 @@ output_call_frame_info (for_eh)
{ {
if (any_lsda_needed) if (any_lsda_needed)
{ {
dw2_asm_output_data_uleb128 ( int size = size_of_encoded_value (lsda_encoding);
size_of_encoded_value (lsda_encoding), "Augmentation size");
if (lsda_encoding == DW_EH_PE_aligned)
{
int offset = ( 4 /* Length */
+ 4 /* CIE offset */
+ 2 * size_of_encoded_value (fde_encoding)
+ 1 /* Augmentation size */ );
int pad = -offset & (PTR_SIZE - 1);
size += pad;
if (size_of_uleb128 (size) != 1)
abort ();
}
dw2_asm_output_data_uleb128 (size, "Augmentation size");
if (fde->uses_eh_lsda) if (fde->uses_eh_lsda)
{ {
...@@ -1921,9 +1957,13 @@ output_call_frame_info (for_eh) ...@@ -1921,9 +1957,13 @@ output_call_frame_info (for_eh)
"Language Specific Data Area"); "Language Specific Data Area");
} }
else else
{
if (lsda_encoding == DW_EH_PE_aligned)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
dw2_asm_output_data (size_of_encoded_value (lsda_encoding), dw2_asm_output_data (size_of_encoded_value (lsda_encoding),
0, "Language Specific Data Area (none)"); 0, "Language Specific Data Area (none)");
} }
}
else else
dw2_asm_output_data_uleb128 (0, "Augmentation size"); dw2_asm_output_data_uleb128 (0, "Augmentation size");
} }
......
...@@ -233,6 +233,7 @@ base_from_object (unsigned char encoding, struct object *ob) ...@@ -233,6 +233,7 @@ base_from_object (unsigned char encoding, struct object *ob)
{ {
case DW_EH_PE_absptr: case DW_EH_PE_absptr:
case DW_EH_PE_pcrel: case DW_EH_PE_pcrel:
case DW_EH_PE_aligned:
return 0; return 0;
case DW_EH_PE_textrel: case DW_EH_PE_textrel:
...@@ -270,7 +271,12 @@ get_cie_encoding (struct dwarf_cie *cie) ...@@ -270,7 +271,12 @@ get_cie_encoding (struct dwarf_cie *cie)
return *p; return *p;
/* Personality encoding and pointer. */ /* Personality encoding and pointer. */
else if (*aug == 'P') else if (*aug == 'P')
p = read_encoded_value_with_base (*p & 0xF, 0, p + 1, &dummy); {
/* ??? Avoid dereferencing indirect pointers, since we're
faking the base address. Gotta keep DW_EH_PE_aligned
intact, however. */
p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
}
/* LSDA encoding. */ /* LSDA encoding. */
else if (*aug == 'L') else if (*aug == 'L')
p++; p++;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define DW_EH_PE_textrel 0x20 #define DW_EH_PE_textrel 0x20
#define DW_EH_PE_datarel 0x30 #define DW_EH_PE_datarel 0x30
#define DW_EH_PE_funcrel 0x40 #define DW_EH_PE_funcrel 0x40
#define DW_EH_PE_aligned 0x50
#define DW_EH_PE_indirect 0x80 #define DW_EH_PE_indirect 0x80
...@@ -83,6 +84,7 @@ base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context) ...@@ -83,6 +84,7 @@ base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
{ {
case DW_EH_PE_absptr: case DW_EH_PE_absptr:
case DW_EH_PE_pcrel: case DW_EH_PE_pcrel:
case DW_EH_PE_aligned:
return 0; return 0;
case DW_EH_PE_textrel: case DW_EH_PE_textrel:
...@@ -117,6 +119,15 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, ...@@ -117,6 +119,15 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
union unaligned *u = (union unaligned *) p; union unaligned *u = (union unaligned *) p;
_Unwind_Ptr result; _Unwind_Ptr result;
if (encoding == DW_EH_PE_aligned)
{
_Unwind_Ptr a = (_Unwind_Ptr)p;
a = (a + sizeof (void *) - 1) & - sizeof(void *);
result = *(_Unwind_Ptr *) a;
p = (const unsigned char *)(a + sizeof (void *));
}
else
{
switch (encoding & 0x0f) switch (encoding & 0x0f)
{ {
case DW_EH_PE_absptr: case DW_EH_PE_absptr:
...@@ -191,10 +202,12 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, ...@@ -191,10 +202,12 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
if (result != 0) if (result != 0)
{ {
result += ((encoding & 0x70) == DW_EH_PE_pcrel ? (_Unwind_Ptr)u : base); result += ((encoding & 0x70) == DW_EH_PE_pcrel
? (_Unwind_Ptr)u : base);
if (encoding & DW_EH_PE_indirect) if (encoding & DW_EH_PE_indirect)
result = *(_Unwind_Ptr *)result; result = *(_Unwind_Ptr *)result;
} }
}
*val = result; *val = result;
return p; return p;
......
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