crtstuff.c (__register_frame_info_bases): Declare.
authorRichard Henderson <rth@redhat.com>
Tue, 22 May 2001 16:57:40 +0000 (09:57 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 22 May 2001 16:57:40 +0000 (09:57 -0700)
        * crtstuff.c (__register_frame_info_bases): Declare.
        (frame_dummy): Use it, if CRT_GET_RFIB_TEXT or CRT_GET_RFIB_DATA.
        (__do_global_dtors_aux, __do_global_dtors): Streamline.

        * config/i386/linux.h (ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): New.
        (CRT_GET_RFIB_DATA): New.
        * config/i386/sysv4.h: Likewise.
        * config/i386/sco5.h: Likewise.
        (ASM_PREFERRED_EH_DATA_FORMAT): New.

From-SVN: r42453

gcc/ChangeLog
gcc/config/i386/linux.h
gcc/config/i386/sco5.h
gcc/config/i386/sysv4.h
gcc/crtstuff.c

index 86dedd1ea9a36afd1d93c87f9401109be3a84928..148f682ea4221ca5d5e1f9b8de5ee6aeec7fb9a6 100644 (file)
@@ -1,3 +1,15 @@
+2001-05-22  Richard Henderson  <rth@redhat.com>
+
+       * crtstuff.c (__register_frame_info_bases): Declare.
+       (frame_dummy): Use it, if CRT_GET_RFIB_TEXT or CRT_GET_RFIB_DATA.
+       (__do_global_dtors_aux, __do_global_dtors): Streamline.
+
+       * config/i386/linux.h (ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): New.
+       (CRT_GET_RFIB_DATA): New.
+       * config/i386/sysv4.h: Likewise.
+       * config/i386/sco5.h: Likewise.
+       (ASM_PREFERRED_EH_DATA_FORMAT): New.
+
 2001-05-22  Richard Henderson  <rth@redhat.com>
 
        * rtl.c (read_string): Break out from ...
index 108a6fbaac8f469cb8dbd33b27b2914a57e0e148..c80a3feb5a06dc5d45b34f827e8b6bb465bbfadf 100644 (file)
@@ -194,6 +194,39 @@ Boston, MA 02111-1307, USA.  */
   while (0)
 #endif
 
+/* Handle special EH pointer encodings.  Absolute, pc-relative, and
+   indirect are handled automatically.  */
+#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
+  do {                                                                 \
+    if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_datarel)                \
+      {                                                                        \
+        fputs (UNALIGNED_INT_ASM_OP, FILE);                            \
+        assemble_name (FILE, XSTR (ADDR, 0));                          \
+       fputs (((ENCODING) & DW_EH_PE_indirect ? "@GOT" : "@GOTOFF"), FILE); \
+        goto DONE;                                                     \
+      }                                                                        \
+  } while (0)
+
+/* Used by crtstuff.c to initialize the base of data-relative relocations.
+   These are GOT relative on x86, so return the pic register.  */
+#ifdef __PIC__
+#define CRT_GET_RFIB_DATA(BASE)                        \
+  {                                            \
+    register void *ebx_ __asm__("ebx");                \
+    BASE = ebx_;                               \
+  }
+#else
+#define CRT_GET_RFIB_DATA(BASE)                                                \
+  __asm__ ("call\t.LPR%=\n"                                            \
+          ".LPR%=:\n\t"                                                \
+          "popl\t%0\n\t"                                               \
+          /* Due to a GAS bug, this cannot use EAX.  That encodes      \
+             smaller than the traditional EBX, which results in the    \
+             offset being off by one.  */                              \
+          "addl\t$_GLOBAL_OFFSET_TABLE_+[.-.LPR%=],%0"                 \
+          : "=d"(BASE))
+#endif
+
 /* Do code reading to identify a signal frame, and set the frame
    state data appropriately.  See unwind-dw2.c for the structs.  */
 
index 33a512d81376c3902c76f38014d62770f292e3ec..19cbcf12066d002e356a1a1f2e0e54c60b4b1a52 100644 (file)
@@ -951,3 +951,44 @@ do {                                                                       \
 } while (0)
 # endif /* ! _SCO_ELF */
 #endif /* CRT_BEGIN !! CRT_END */
+
+/* Handle special EH pointer encodings.  Absolute, pc-relative, and
+   indirect are handled automatically.  */
+#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
+  do {                                                                 \
+    if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_datarel)                \
+      {                                                                        \
+        fputs (UNALIGNED_INT_ASM_OP, FILE);                            \
+        assemble_name (FILE, XSTR (ADDR, 0));                          \
+       fputs (((ENCODING) & DW_EH_PE_indirect ? "@GOT" : "@GOTOFF"), FILE); \
+        goto DONE;                                                     \
+      }                                                                        \
+  } while (0)
+
+/* Used by crtstuff.c to initialize the base of data-relative relocations.
+   These are GOT relative on x86, so return the pic register.  */
+#ifdef __PIC__
+#define CRT_GET_RFIB_DATA(BASE)                        \
+  {                                            \
+    register void *ebx_ __asm__("ebx");                \
+    BASE = ebx_;                               \
+  }
+#else
+#define CRT_GET_RFIB_DATA(BASE)                                                \
+  __asm__ ("call\t.LPR%=\n"                                            \
+          ".LPR%=:\n\t"                                                \
+          "popl\t%0\n\t"                                               \
+          /* Due to a GAS bug, this cannot use EAX.  That encodes      \
+             smaller than the traditional EBX, which results in the    \
+             offset being off by one.  */                              \
+          "addl\t$_GLOBAL_OFFSET_TABLE_+[.-.LPR%=],%0"                 \
+          : "=d"(BASE))
+#endif
+
+/* 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.  */
+#undef ASM_PREFERRED_EH_DATA_FORMAT
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)                      \
+  (flag_pic ? (GLOBAL ? DW_EH_PE_indirect : 0) | DW_EH_PE_datarel      \
+   : DW_EH_PE_absptr)
index a61018828c2da54c03e8cc93504b831050bb88dc..f56d58326c0f12747ab4dbe9f702713be6937aa0 100644 (file)
@@ -179,3 +179,36 @@ do { long value[3];                                                        \
 
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
   asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+/* Handle special EH pointer encodings.  Absolute, pc-relative, and
+   indirect are handled automatically.  */
+#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
+  do {                                                                 \
+    if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_datarel)                \
+      {                                                                        \
+        fputs (UNALIGNED_INT_ASM_OP, FILE);                            \
+        assemble_name (FILE, XSTR (ADDR, 0));                          \
+       fputs (((ENCODING) & DW_EH_PE_indirect ? "@GOT" : "@GOTOFF"), FILE); \
+        goto DONE;                                                     \
+      }                                                                        \
+  } while (0)
+
+/* Used by crtstuff.c to initialize the base of data-relative relocations.
+   These are GOT relative on x86, so return the pic register.  */
+#ifdef __PIC__
+#define CRT_GET_RFIB_DATA(BASE)                        \
+  {                                            \
+    register void *ebx_ __asm__("ebx");                \
+    BASE = ebx_;                               \
+  }
+#else
+#define CRT_GET_RFIB_DATA(BASE)                                                \
+  __asm__ ("call\t.LPR%=\n"                                            \
+          ".LPR%=:\n\t"                                                \
+          "popl\t%0\n\t"                                               \
+          /* Due to a GAS bug, this cannot use EAX.  That encodes      \
+             smaller than the traditional EBX, which results in the    \
+             offset being off by one.  */                              \
+          "addl\t$_GLOBAL_OFFSET_TABLE_+[.-.LPR%=],%0"                 \
+          : "=d"(BASE))
+#endif
index b8f6df588f8d8cd19ae1cc7c19b79965f5b77815..1897185f3d1a3bfbfbf1f032686cdbf351053a27 100644 (file)
@@ -90,7 +90,9 @@ Boston, MA 02111-1307, USA.  */
    be weak in this file if at all possible.  */
 extern void __register_frame_info (void *, struct object *)
                                  TARGET_ATTRIBUTE_WEAK;
-
+extern void __register_frame_info_bases (void *, struct object *,
+                                        void *, void *)
+                                 TARGET_ATTRIBUTE_WEAK;
 extern void *__deregister_frame_info (void *)
                                     TARGET_ATTRIBUTE_WEAK;
 
@@ -190,9 +192,10 @@ static void
 __do_global_dtors_aux (void)
 {
   static func_ptr *p = __DTOR_LIST__ + 1;
-  static int completed = 0;
+  static int completed;
+  func_ptr f;
 
-  if (completed)
+  if (__builtin_expect (completed, 0))
     return;
 
 #ifdef CRTSTUFFS_O
@@ -200,10 +203,10 @@ __do_global_dtors_aux (void)
     __cxa_finalize (__dso_handle);
 #endif
 
-  while (*p)
+  while ((f = *p))
     {
       p++;
-      (*(p-1)) ();
+      f ();
     }
 
 #ifdef EH_FRAME_SECTION_ASM_OP
@@ -236,8 +239,24 @@ static void
 frame_dummy (void)
 {
   static struct object object;
+#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
+  void *tbase, *dbase;
+#ifdef CRT_GET_RFIB_TEXT
+  CRT_GET_RFIB_TEXT (tbase);
+#else
+  tbase = 0;
+#endif
+#ifdef CRT_GET_RFIB_DATA
+  CRT_GET_RFIB_DATA (dbase);
+#else
+  dbase = 0;
+#endif
+  if (__register_frame_info_bases)
+    __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
+#else
   if (__register_frame_info)
     __register_frame_info (__EH_FRAME_BEGIN__, &object);
+#endif
 }
 
 static void __attribute__ ((__unused__))
@@ -317,9 +336,9 @@ static func_ptr __DTOR_LIST__[];
 void
 __do_global_dtors (void)
 {
-  func_ptr *p;
-  for (p = __DTOR_LIST__ + 1; *p; p++)
-    (*p) ();
+  func_ptr *p, f;
+  for (p = __DTOR_LIST__ + 1; (f = *p); p++)
+    f ();
 
 #ifdef EH_FRAME_SECTION_ASM_OP
   if (__deregister_frame_info)