Fix gas/gcc unwind/EH discrepancies. And a shared library build problem.
authorJames E. Wilson <wilson@cygnus.com>
Wed, 7 Jun 2000 02:27:51 +0000 (02:27 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Wed, 7 Jun 2000 02:27:51 +0000 (19:27 -0700)
* frame.h (struct unwind_info_ptr): Collapse version, flags, and length
fields into header field.
(IA64_UNW_HDR_LENGTH, IA64_UNW_HDR_FLAGS, IA64_UNW_HDR_VERSION): New
macros to access length, flags, and version info from header field.
* config/ia64/crtbegin.asm (__do_frame_setup_aux): Delete here.
...

From-SVN: r34441

gcc/ChangeLog
gcc/config/ia64/crtbegin.asm
gcc/config/ia64/crtend.asm
gcc/config/ia64/frame-ia64.c
gcc/config/ia64/ia64.c
gcc/frame.h

index a0db4b4f5d6cfd10b17d35879c51285b84d6072c..2f8e558fa82a2621b43f42f0f8d7c90c9554a011 100644 (file)
@@ -1,3 +1,23 @@
+2000-06-06  James E. Wilson  <wilson@cygnus.com>
+
+       * frame.h (struct unwind_info_ptr): Collapse version, flags, and length
+       fields into header field.
+       (IA64_UNW_HDR_LENGTH, IA64_UNW_HDR_FLAGS, IA64_UNW_HDR_VERSION): New
+       macros to access length, flags, and version info from header field.
+       * config/ia64/crtbegin.asm (__do_frame_setup_aux): Delete here.
+       * config/ia64/crtend.asm (__do_frame_setup_aux): Add here.
+       (__do_global_ctors_aux): Fix caller.
+       * config/ia64/frame-ia64.c (get_unwind_record): Change parameter
+       prologue_flag to header.  Pass to read_P_record.
+       (read_P_record): New argument header.  Implement P4 format.
+       Multiply P7_T_SIZE by 16.
+       (execute_one_ia64_descriptor): New static local region_header.  Pass to
+       get_unwind_record.  Copy r to region_header if r is a header record.
+       (print_all_records): Likewise.
+       (__build_ia64_frame_state): Use IA64_UNW_HDR_LENGTH.
+       (__get_personality, __get_except_table): Likewise.
+       * config/ia64/ia64.c (process_set): Do not divide offsets by 4.
+
 2000-06-06  Philipp Thomas  <pthomas@suse.de>
 
         * configure.in (AC_C_INLINE): Added.
index 0e49e20662d3707a8e694c5d5c0deebf9da2a23c..3f2b2f7080a102a739f778255acae279bcf464d0 100644 (file)
@@ -296,38 +296,3 @@ __do_frame_setup:
 #endif
 .weak __deregister_frame_info#
 .weak __register_frame_info#
-
-       .text
-       .align 16
-       .global __do_frame_setup_aux#
-       .proc   __do_frame_setup_aux#
-__do_frame_setup_aux:
-       /*
-               if (__register_frame_info_aux)
-                 __register_frame_info_aux(__EH_FRAME_END__)
-       */
-        alloc loc0 = ar.pfs, 0, 3, 1, 0
-        addl r14 = @ltoff(@fptr(__register_frame_info_aux#)), gp
-        mov loc1 = b0
-        ;;
-       // r16 contains the address of a pointer to __EH_FRAME_END__.
-        ld8 out0 = [r16]
-        ld8 r15 = [r14]
-       mov loc2 = gp
-        ;;
-        cmp.eq p6, p7 = 0, r15
-        (p6) br.cond.dptk 1f
-        ld8 r8 = [r15], 8
-        ;;
-        ld8 gp = [r15]
-        mov b6 = r8
-        ;;
-        br.call.sptk.many b0 = b6
-       ;;
-1:
-       mov gp = loc2
-        mov ar.pfs = loc0
-        mov b0 = loc1
-        br.ret.sptk.many b0
-       .endp   __do_frame_setup#
-.weak __register_frame_info_aux#
index 9216cfc7fb74be3358a59f83343e82bef64009d9..07b71ea5c10db5cc16f13f369fe20b4d887ccc93 100644 (file)
@@ -113,7 +113,6 @@ __do_global_ctors_aux:
 
 .section .init,"ax","progbits"
        { .mlx
-         // __do_frame_setup_aux is in crtbegin.asm
          movl r2 = @gprel(__do_frame_setup_aux#)
          ;;
        }
@@ -123,12 +122,42 @@ __do_global_ctors_aux:
          ;;
          mov b6 = r2
        }
-       { .mib
-         // __do_frame_setup_aux needs the address of __EH_FRAME_END__,
-         // so we pass it in r16.  This is rather evil, but we have no
-         // output registers.
-          addl r16 = @ltoff(__EH_FRAME_END__#), gp
+       { .bbb
          br.call.sptk.many b0 = b6
          ;;
         }
 
+.text
+       .align 16
+       .proc   __do_frame_setup_aux#
+__do_frame_setup_aux:
+       /*
+               if (__register_frame_info_aux)
+                 __register_frame_info_aux(__EH_FRAME_END__)
+       */
+       alloc loc0 = ar.pfs, 0, 3, 1, 0
+       addl r14 = @ltoff(@fptr(__register_frame_info_aux#)), gp
+       mov loc1 = b0
+       ;;
+       ld8 r15 = [r14]
+       addl r16 = @ltoff(__EH_FRAME_END__#), gp
+       mov loc2 = gp
+       ;;
+       cmp.eq p6, p7 = 0, r15
+       (p6) br.cond.dptk 1f
+       ld8 r8 = [r15], 8
+       ld8 out0 = [r16]
+       ;;
+       ld8 gp = [r15]
+       mov b6 = r8
+       ;;
+       br.call.sptk.many b0 = b6
+       ;;
+1:
+       mov gp = loc2
+       mov ar.pfs = loc0
+       mov b0 = loc1
+       br.ret.sptk.many b0
+       .endp   __do_frame_setup_aux#
+
+.weak __register_frame_info_aux#
index 763bc49c0bceb676e6be72f814f5dca1316675bc..4ff78dd4a4dcdd0ac84138bea0274be165c8a27a 100644 (file)
@@ -247,23 +247,22 @@ bad_record (ptr, offset)
 static unsigned char *read_R_record (unwind_record *, unsigned char, unsigned char *);
 static unsigned char *read_X_record (unwind_record *, unsigned char, unsigned char *);
 static unsigned char *read_B_record (unwind_record *, unsigned char, unsigned char *);
-static unsigned char *read_P_record (unwind_record *, unsigned char, unsigned char *);
+static unsigned char *read_P_record (unwind_record *, unsigned char, unsigned char *, unwind_record *);
 
 
 /* This routine will determine what type of record the memory pointer
    is refering to, and fill in the appropriate fields for that record type. 
-   PROLOGUE_FLAG is TRUE if we are currently processing a PROLOGUE
-   body. 
+   HEADER is a pointer to the last region header unwind record.
    DATA is a pointer to an unwind record which will be filled in.
    PTR is a pointer to the current location in the unwind table where we
    will read the next record from.  
    The return value is the start of the next record.  */
 
 extern unsigned char *
-get_unwind_record (prologue_flag, data, ptr)
-    int prologue_flag;
-    unwind_record *data;
-    unsigned char *ptr;
+get_unwind_record (header, data, ptr)
+     unwind_record *header;
+     unwind_record *data;
+     unsigned char *ptr;
 {
   unsigned char val = *ptr++;
 
@@ -275,8 +274,8 @@ get_unwind_record (prologue_flag, data, ptr)
   if (val == UNW_X1 || val == UNW_X2 || val == UNW_X3 || val == UNW_X4)
     return read_X_record (data, val, ptr);
 
-  if (prologue_flag)
-    return read_P_record (data, val, ptr);
+  if (header->type != body)
+    return read_P_record (data, val, ptr, header);
   else
     return read_B_record (data, val, ptr);
 }
@@ -534,10 +533,11 @@ static unsigned char P8_additional_fields [] = {
 
 
 static unsigned char *
-read_P_record (data, val, ptr)
+read_P_record (data, val, ptr, header)
      unwind_record *data;
      unsigned char val;
      unsigned char *ptr;
+     unwind_record *header;
 {
   if ((val & 0xe0) == 0x80)
     {
@@ -575,13 +575,12 @@ read_P_record (data, val, ptr)
 
   if (val == UNW_P4)
     {
-      /* P4 format.  Currently unimplemented.  */
-      int len = 0;  /* TODO.. get prologue rlen. */
-      int size = (len * 2 + 7) / 8;
+      /* P4 format.  */
+      int size = (header->record.r.rlen * 2 + 7) / 8;
 
       data->type = spill_mask;
       data->record.p.imask = (unsigned char *) malloc (size);
-      /* memcpy (data->record.p.imask, ptr, size);  */
+      memcpy (data->record.p.imask, ptr, size);
       return ptr+size;
     }
 
@@ -617,7 +616,7 @@ read_P_record (data, val, ptr)
         {
          case P7_T_SIZE:
            data->record.p.t = read_uleb128 (&ptr);
-           data->record.p.size = read_uleb128 (&ptr);
+           data->record.p.size = read_uleb128 (&ptr) << 4;
            break;
          case P7_T:
            data->record.p.t = read_uleb128 (&ptr);
@@ -733,11 +732,14 @@ execute_one_ia64_descriptor (addr, frame, len)
      long *len;
 {
   unwind_record r;
+  /* The last region_header.  Needed to distinguish between prologue and body
+     descriptors.  Also needed for length of P4 format.  */
+  static unwind_record region_header;
   ia64_reg_loc *loc_ptr = NULL;
   int grmask = 0, frmask = 0;
 
   *len = -1;
-  addr = get_unwind_record (1, &r, addr);
+  addr = get_unwind_record (&region_header, &r, addr);
 
   /* process it in 2 phases, the first phase will either do the work,
      or set up a pointer to the records we care about 
@@ -748,6 +750,7 @@ execute_one_ia64_descriptor (addr, frame, len)
       case prologue:
       case body:
        *len = r.record.r.rlen;
+       memcpy (&region_header, &r, sizeof (unwind_record));
        break;
       case prologue_gr:
         {
@@ -780,6 +783,7 @@ execute_one_ia64_descriptor (addr, frame, len)
              frame->pr.loc_type  = IA64_UNW_LOC_TYPE_GR;
              frame->pr.l.regno = reg++;
            }
+         memcpy (&region_header, &r, sizeof (unwind_record));
          break;
        }
       case mem_stack_f:
@@ -1312,7 +1316,7 @@ __build_ia64_frame_state (pc, frame, bsp, pc_base_ptr)
   start_pc = pc_base + entry->start_offset;
   unw_info_ptr = ((struct unwind_info_ptr *)(pc_base + entry->unwind_offset));
   addr = unw_info_ptr->unwind_descriptors;
-  end = addr + unw_info_ptr->length * 8;
+  end = addr + IA64_UNW_HDR_LENGTH (unw_info_ptr->header) * 8;
   pc_offset = (pc - start_pc) / 16 * 3;
 
   init_ia64_unwind_frame (frame);
@@ -1345,7 +1349,8 @@ __get_personality (ptr)
      unwind_info_ptr *ptr;
 {
   void **p;
-  p = (void **) (ptr->unwind_descriptors + ptr->length * 8);
+  p = (void **) (ptr->unwind_descriptors
+                + IA64_UNW_HDR_LENGTH (ptr->header) * 8);
   return *p;
 }
 
@@ -1354,11 +1359,13 @@ __get_except_table (ptr)
      unwind_info_ptr *ptr;
 {
   void **p, *table;
-  p = (void **) (ptr->unwind_descriptors + ptr->length * 8);
+  p = (void **) (ptr->unwind_descriptors
+                + IA64_UNW_HDR_LENGTH (ptr->header) * 8);
   /* If there is no personality, there is no handler data.  */
   if (*p == 0)
     return 0;
-  table = (void *) (ptr->unwind_descriptors + ptr->length * 8 + 8);
+  table = (void *) (ptr->unwind_descriptors
+                   + IA64_UNW_HDR_LENGTH (ptr->header) * 8 + 8);
   return table;
 }
 
@@ -1595,12 +1602,23 @@ print_all_records (f, mem, size)
 {
   unsigned char *end = mem + size;
   unwind_record r;
+  static unwind_record region_header;
 
   fprintf (f, "UNWIND IMAGE:\n");
   while (mem < end) 
     {
-      mem = get_unwind_record (1, &r, mem);
+      mem = get_unwind_record (&region_header, &r, mem);
       print_record (f, &r);
+      switch (r.type)
+       {
+       case prologue:
+       case body:
+       case prologue_gr:
+         memcpy (region_header, r, sizeof (unwind_record));
+         break;
+       default:
+         break;
+       }
     }
   fprintf (f, "--end unwind image--\n\n");
 }
index 8328d7f9b5604e20a6378970149c7fcb2db0b0c3..e9eade30b93c0e7b42067370ff539a0b9fa0be28 100644 (file)
@@ -3117,8 +3117,7 @@ process_set (asm_out_file, pat)
              if (!spill_offset_emitted)
                {
                  fprintf (asm_out_file, "\t.spill %d\n",
-/*                        (frame_size + 16 - spill_offset ) / 4); */
-                          (-(spill_offset - 8) + 16) / 4);
+                          (-(spill_offset - 8) + 16));
                  spill_offset_emitted = 1;
                }
            }
@@ -3138,10 +3137,10 @@ process_set (asm_out_file, pat)
                  /* register 9 is ar.unat.  */
                  if (tmp_saved == 9)
                    fprintf (asm_out_file, "\t.savesp ar.unat, %d\n",
-                            (sp_offset - 8) / 4);
+                            (sp_offset - 8));
                  else if (tmp_saved == 5)
                    fprintf (asm_out_file, "\t.savesp pr, %d\n",
-                            (sp_offset - 8) / 4);
+                            (sp_offset - 8));
                  else if (tmp_saved >= BR_REG (1) && tmp_saved <= BR_REG (5))
                    {
                      /* BR regs are saved this way too.  */
index 384e5eb66ca80c6b9e535df22b566625ae659b92..85c5e436d5b93a4bf988a4f28121fd1dadbbe134 100644 (file)
@@ -256,12 +256,13 @@ typedef struct ia64_frame_state
 
 typedef struct unwind_info_ptr 
 {
-  unsigned short version;
-  unsigned short flags;
-  unsigned int length;
+  unsigned long header; /* version, flags, & length */
   unsigned char unwind_descriptors[1];
 } unwind_info_ptr;
 
+#define IA64_UNW_HDR_LENGTH(x) ((x) & 0x00000000ffffffffUL)
+#define IA64_UNW_HDR_FLAGS(x)  (((x) >> 32) & 0xffffUL)
+#define IA64_UNW_HDR_VERSION(x)        (((x) >> 48) & 0xffffUL)
 
 extern unwind_info_ptr *__build_ia64_frame_state (unsigned char *, 
                                                  ia64_frame_state *, void *,