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>
* config.gcc, config/i386/bsd386.h: Do not directly include
......@@ -327,7 +344,7 @@ Sat Jun 2 06:53:50 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* README: Update references to installation instructions.
2001-06-01 Laurent Guerby <guerby@acm.org>
Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
* doc/install.texi: Define srcdir when sources come from CVS.
Significantly improve markup. Wrap overly long lines
......@@ -481,7 +498,7 @@ Thu May 31 19:09:53 CEST 2001 Jan Hubicka <jh@suse.cz>
2001-05-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* fixinc/fixtests.c: Declare entries in ENV_TABLE.
* fixinc/fixtests.c: Declare entries in ENV_TABLE.
2001-05-27 Bruce Korb <bkorb@gnu.org>
......
......@@ -686,8 +686,6 @@ void FN () \
#undef UNALIGNED_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
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations.
......
......@@ -153,3 +153,17 @@ __enable_execute_stack (addr) \
#define HAS_INIT_SECTION
#define LD_INIT_SWITCH "-init"
#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
#define DW_EH_PE_textrel 0x20
#define DW_EH_PE_datarel 0x30
#define DW_EH_PE_funcrel 0x40
#define DW_EH_PE_aligned 0x50
#define DW_EH_PE_indirect 0x80
......@@ -490,6 +490,7 @@ eh_data_format_name (format)
S(DW_EH_PE_absptr, "absolute")
S(DW_EH_PE_omit, "omit")
S(DW_EH_PE_aligned, "aligned absolute")
S(DW_EH_PE_uleb128, "uleb128")
S(DW_EH_PE_udata2, "udata2")
......@@ -947,6 +948,12 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int 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. */
if (addr == const0_rtx)
assemble_integer (addr, size, 1);
......
......@@ -1820,6 +1820,28 @@ output_call_frame_info (for_eh)
augmentation[0] = 'z';
*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");
......@@ -1909,8 +1931,22 @@ output_call_frame_info (for_eh)
{
if (any_lsda_needed)
{
dw2_asm_output_data_uleb128 (
size_of_encoded_value (lsda_encoding), "Augmentation size");
int size = size_of_encoded_value (lsda_encoding);
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)
{
......@@ -1921,8 +1957,12 @@ output_call_frame_info (for_eh)
"Language Specific Data Area");
}
else
dw2_asm_output_data (size_of_encoded_value (lsda_encoding),
0, "Language Specific Data Area (none)");
{
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),
0, "Language Specific Data Area (none)");
}
}
else
dw2_asm_output_data_uleb128 (0, "Augmentation size");
......
......@@ -233,6 +233,7 @@ base_from_object (unsigned char encoding, struct object *ob)
{
case DW_EH_PE_absptr:
case DW_EH_PE_pcrel:
case DW_EH_PE_aligned:
return 0;
case DW_EH_PE_textrel:
......@@ -270,7 +271,12 @@ get_cie_encoding (struct dwarf_cie *cie)
return *p;
/* Personality encoding and pointer. */
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. */
else if (*aug == 'L')
p++;
......
......@@ -40,12 +40,13 @@
#define DW_EH_PE_textrel 0x20
#define DW_EH_PE_datarel 0x30
#define DW_EH_PE_funcrel 0x40
#define DW_EH_PE_aligned 0x50
#define DW_EH_PE_indirect 0x80
/* Given an encoding, return the number of bytes the format occupies.
This is only defined for fixed-size encodings, and so does not
This is only defined for fixed-size encodings, and so does not
include leb128. */
static unsigned int
......@@ -69,7 +70,7 @@ size_of_encoded_value (unsigned char encoding)
}
/* Given an encoding and an _Unwind_Context, return the base to which
the encoding is relative. This base may then be passed to
the encoding is relative. This base may then be passed to
read_encoded_value_with_base for use when the _Unwind_Context is
not available. */
......@@ -83,6 +84,7 @@ base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
{
case DW_EH_PE_absptr:
case DW_EH_PE_pcrel:
case DW_EH_PE_aligned:
return 0;
case DW_EH_PE_textrel:
......@@ -117,83 +119,94 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
union unaligned *u = (union unaligned *) p;
_Unwind_Ptr result;
switch (encoding & 0x0f)
if (encoding == DW_EH_PE_aligned)
{
case DW_EH_PE_absptr:
result = (_Unwind_Ptr) u->ptr;
p += sizeof (void *);
break;
case DW_EH_PE_uleb128:
{
unsigned int shift = 0;
unsigned char byte;
result = 0;
do
_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)
{
case DW_EH_PE_absptr:
result = (_Unwind_Ptr) u->ptr;
p += sizeof (void *);
break;
case DW_EH_PE_uleb128:
{
byte = *p++;
result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
shift += 7;
unsigned int shift = 0;
unsigned char byte;
result = 0;
do
{
byte = *p++;
result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
}
while (byte & 0x80);
}
break;
case DW_EH_PE_sleb128:
{
unsigned int shift = 0;
unsigned char byte;
break;
result = 0;
do
case DW_EH_PE_sleb128:
{
byte = *p++;
result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
shift += 7;
unsigned int shift = 0;
unsigned char byte;
result = 0;
do
{
byte = *p++;
result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
result |= -(1L << shift);
}
while (byte & 0x80);
if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
result |= -(1L << shift);
}
break;
case DW_EH_PE_udata2:
result = u->u2;
p += 2;
break;
case DW_EH_PE_udata4:
result = u->u4;
p += 4;
break;
case DW_EH_PE_udata8:
result = u->u8;
p += 8;
break;
case DW_EH_PE_sdata2:
result = u->s2;
p += 2;
break;
case DW_EH_PE_sdata4:
result = u->s4;
p += 4;
break;
case DW_EH_PE_sdata8:
result = u->s8;
p += 8;
break;
default:
abort ();
}
if (result != 0)
{
result += ((encoding & 0x70) == DW_EH_PE_pcrel ? (_Unwind_Ptr)u : base);
if (encoding & DW_EH_PE_indirect)
result = *(_Unwind_Ptr *)result;
break;
case DW_EH_PE_udata2:
result = u->u2;
p += 2;
break;
case DW_EH_PE_udata4:
result = u->u4;
p += 4;
break;
case DW_EH_PE_udata8:
result = u->u8;
p += 8;
break;
case DW_EH_PE_sdata2:
result = u->s2;
p += 2;
break;
case DW_EH_PE_sdata4:
result = u->s4;
p += 4;
break;
case DW_EH_PE_sdata8:
result = u->s8;
p += 8;
break;
default:
abort ();
}
if (result != 0)
{
result += ((encoding & 0x70) == DW_EH_PE_pcrel
? (_Unwind_Ptr)u : base);
if (encoding & DW_EH_PE_indirect)
result = *(_Unwind_Ptr *)result;
}
}
*val = result;
......@@ -207,7 +220,7 @@ static inline const unsigned char *
read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
const unsigned char *p, _Unwind_Ptr *val)
{
return read_encoded_value_with_base (encoding,
return read_encoded_value_with_base (encoding,
base_of_encoded_value (encoding, context),
p, val);
}
......
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