summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-06 01:57:49 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-06 01:57:49 +0000
commit9a4d22ba1e8fcbd07ad2306af585edcfc2a9e4cc (patch)
tree7d58db2a4f6ec00eb20b149b79bc6fbe2e8c5a80
parent4490d2f1bca8aabc8c13a2dbbcd5f07ec0c4999b (diff)
downloadgcc-9a4d22ba1e8fcbd07ad2306af585edcfc2a9e4cc.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@42926 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/alpha/elf.h2
-rw-r--r--gcc/config/alpha/osf.h14
-rw-r--r--gcc/dwarf2.h1
-rw-r--r--gcc/dwarf2asm.c7
-rw-r--r--gcc/dwarf2out.c48
-rw-r--r--gcc/unwind-dw2-fde.c8
-rw-r--r--gcc/unwind-pe.h161
8 files changed, 179 insertions, 83 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5c342bdd316..0dc127dad57 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+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>
diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h
index fd0874eee94..78642e678df 100644
--- a/gcc/config/alpha/elf.h
+++ b/gcc/config/alpha/elf.h
@@ -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.
diff --git a/gcc/config/alpha/osf.h b/gcc/config/alpha/osf.h
index 1d1109b3c2f..b6e80d02bbf 100644
--- a/gcc/config/alpha/osf.h
+++ b/gcc/config/alpha/osf.h
@@ -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)
diff --git a/gcc/dwarf2.h b/gcc/dwarf2.h
index e6148a36766..800bda2dc01 100644
--- a/gcc/dwarf2.h
+++ b/gcc/dwarf2.h
@@ -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
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index 98b557202a8..15ae68dd212 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -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);
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index d72ecc2c347..5d561840e6a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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");
diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c
index c486f50b176..6da2c7384fd 100644
--- a/gcc/unwind-dw2-fde.c
+++ b/gcc/unwind-dw2-fde.c
@@ -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++;
diff --git a/gcc/unwind-pe.h b/gcc/unwind-pe.h
index 264aa1821d8..e952b7f83e4 100644
--- a/gcc/unwind-pe.h
+++ b/gcc/unwind-pe.h
@@ -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);
}