dwarf2.h (DW_EH_PE_aligned): New.
authorRichard Henderson <rth@gcc.gnu.org>
Wed, 6 Jun 2001 01:57:49 +0000 (18:57 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 6 Jun 2001 01:57:49 +0000 (18:57 -0700)
        * 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

gcc/ChangeLog
gcc/config/alpha/elf.h
gcc/config/alpha/osf.h
gcc/dwarf2.h
gcc/dwarf2asm.c
gcc/dwarf2out.c
gcc/unwind-dw2-fde.c
gcc/unwind-pe.h

index 5c342bdd3161ad29d8b1d05d0c244ed5bbd84ddd..0dc127dad57c70fda60a30c60e44a8496f4965fc 100644 (file)
@@ -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>
 
index fd0874eee94de91e65c56ccc3a379a747d27b308..78642e678dfda3fd0ee44ad11c435eea1cbe193c 100644 (file)
@@ -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.
index 1d1109b3c2fa5eced148a4fe22bbda67537f53ec..b6e80d02bbf2ad290ff03ba2fd5ce192970915b4 100644 (file)
@@ -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)
index e6148a367663c0418a84d034c58a73bbc32941e6..800bda2dc01b2f5329be37b02211e48f14311399 100644 (file)
@@ -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
index 98b557202a8d40a2ef1157b010ddd6723e9e7312..15ae68dd21284f5c4c786d05384df649036b8754 100644 (file)
@@ -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);
index d72ecc2c347c824aa4973ea81efe5d97bdd285c8..5d561840e6a1255eab896c7a95f16b46aa6ca1d7 100644 (file)
@@ -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");
index c486f50b176942c2bc5e4610bc3ac1ed012367cc..6da2c7384fd3169ceb6e28de46fa36d8f6342de3 100644 (file)
@@ -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++;
index 264aa1821d84443b44690ab6c4350f0ee7c1c07d..e952b7f83e453f8c4bb8a30d42f81fe6c16beea8 100644 (file)
 #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
@@ -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);
 }