* 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
+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
* 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
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>
#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.
#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)
#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
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")
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);
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");
{
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)
{
"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");
{
case DW_EH_PE_absptr:
case DW_EH_PE_pcrel:
+ case DW_EH_PE_aligned:
return 0;
case DW_EH_PE_textrel:
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++;
#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
\f
/* 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
}
/* 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. */
{
case DW_EH_PE_absptr:
case DW_EH_PE_pcrel:
+ case DW_EH_PE_aligned:
return 0;
case DW_EH_PE_textrel:
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;
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);
}