This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Extensions to the .eh_frame linker code


The patch below lets the linker convert from absolute to relative
FDE encodings in cases where the original CIEs have no explicit 'R'
augmentation.  I've been meaning to do this for a while now, but finally
got spurred into action after having a glibc change rejected. ;)

This feature is useful on MIPS targets because every relocatable object
uses the default DW_EH_PE_absptr FDE encoding.  Although it would be
nice if relocatable PIC objects could use DW_EH_PE_pcrel from the
outset, the ABIs don't define a suitable relocation.


The idea of the patch is pretty simple.  First of all, we need to allow
the final CIEs and FDEs to be bigger than the originals.  The patch
supports this by adding two new eh_cie_fde fields: "growth", the number
of extra useful bytes, and "new_size", the properly-rounded size of the
output CIE or FDE.

Second, it must be possible for _bfd_elf_discard_section_eh_frame to
decide once and for all whether the FDE encoding will change or not.
At the moment, the function simply sets "make_relative" if the
transformation would be useful and leaves the final decision to
_bfd_elf_eh_frame_section_offset.

The make_relative/need_relative distinction was a result of Alan's
fix for ld/418.  As I understand it, the important part of that change
was really the make_lsda_relative/need_lsda_relative split (because we
don't know for sure what the LSDA actually contains).  It looks like
the make_relative/need_relative part was done more for consistency
than anything.

Since the meaning of the "initial PC" field is fixed, I hope it's
OK to go back to having just make_relative for the FDE encoding.

With those two changes, we can extend the following code:

	  if (info->shared
	      && (get_elf_backend_data (abfd)
		  ->elf_backend_can_make_relative_eh_frame
		  (abfd, info, sec))
	      && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
	    cie.make_relative = 1;

to include CIEs that have no 'R' augmentation (cie.fde_encoding ==
DW_EH_PE_omit at this point).  We then need to reserve space for the
new 'R' augmentation and FDE encoding byte.  If the augmentation string
was originally empty, we also need to add a 'z' augmentation and
associated length.  Adding a 'z' augmentation will affect the FDEs
as well, of course.

The patch records this information in two new eh_cie_fde fields:
"add_augmentation_size", which says whether a new 'z' augmentation
is needed, and "add_fde_encoding", which says whether a new 'R'
augmentation is needed.

Some other notes:

  (1) I've moved the block starting:

          if (cie.lsda_encoding != DW_EH_PE_omit)

      into the preceding else clause so that it only applies to FDEs
      that are not being removed.  This is because the following code:

          else if (last_cie_inf->add_augmentation_size)
            this_inf->growth += 1;

      must not be run in that case.

      The patch gets a bit unreadable here, but it's really just
      reindentation followed by the new "else if" quoted above.

  (2) At the moment, _bfd_elf_write_section_eh_frame makes a single pass
      over the section data.  This pass updates the contents of each
      entry and then moves it to its final offset.

      Since offsets can now grow as well as shrink, we need to move the
      entries in two passes, one forward, one backward.  It's also easier
      to adjust the contents of growing entries if we know that everything
      already starts at its final offset.  The patch therefore moves all
      the entries before doing any detailed updates.

  (3) The new "add_augmentation_size" field is logically separate from
      the "add_fde_encoding" field, and we might want to set it when
      adding other types of augmentation in future.  Until that happens
      though, it seems more natural for _bfd_elf_write_section_eh_frame
      to handle the two together, as per the following block:

              if (ent->add_fde_encoding)
                {
                  BFD_ASSERT (action & 1);
                  if (ent->add_augmentation_size)
                    ...
                  else
                    ...
                  *aug++ = 'R';
                  *buf++ = DW_EH_PE_pcrel;
                  action &= ~1;
                }

      I wasn't sure what structure the code would have if we ever tried
      to add several non-'z' augmentations and I didn't want to generalise
      things too far.

  (4) There's a missed optimisation opportunity:

          /* Round the size up the next alignment boundary and adjust
             the section size accordingly.

             ??? It would be better to trim any existing padding first.  */

      I hope to implement this soon, but I thought the patch was already
      getting to the difficult-to-review stage as it was.

      I've tried to bullet-proof the testcase against such an optimisation
      by padding each CIE and FDE with non-nops.  The type of padding is
      parameterised, so once the optimisation is implemented, it should
      just be a case of attaching new .d files to the same .s file
      and setting "fill" to 0.

Patch tested by bootstrapping & regression testing gcc on
i686-pc-linux-gnu and mips64-linux-gnu.  Also tested against
the gas/ld/binutils testsuite for:

    sparc-linux-gnu
    sparc64-linux-gnu
    i386-linux-gnu
    x86_64-linux-gnu
    powerpc-linux-gnu
    powerpc64-linux-gnu
    sh-linux-gnu
    mips64-elf
    mipsisa64-elf
    mips64-linux-gnu

OK to install?

Richard


bfd/
	* elf-bfd.h (eh_cie_fde): Add new fields: growth, new_size,
	add_augmentation_size and add_fde_encoding.  Remove need_relative.
	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Allow the CIEs
	and FDEs to grow as well as shrink.  Consider changing the FDE encoding
	in cases where the CIE has no explicit 'R' augmentation.
	(_bfd_elf_eh_frame_section_offset): Remove need_relative handling.
	Add the growth field to the returned offset.
	(_bfd_elf_write_section_eh_frame): Rework so that the entries are
	moved before being modified.  Pad growing entries with DW_CFA_nops.
	Add 'z' and 'R' augmentations as directed by add_augmentation_size
	and add_fde_encoding.

ld/testsuite
	* ld-mips-elf/eh-frame1.{s,ld},
	* ld-mips-elf/eh-frame1-{n32,n64},d: New test.
	* ld-mips-elf/mips-elf.exp: Run it.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.162
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.162 elf-bfd.h
--- bfd/elf-bfd.h	14 Oct 2004 23:38:08 -0000	1.162
+++ bfd/elf-bfd.h	13 Nov 2004 09:55:38 -0000
@@ -289,6 +289,8 @@ struct eh_cie_fde
   /* For FDEs, this points to the CIE used.  */
   struct eh_cie_fde *cie_inf;
   unsigned int size;
+  unsigned int growth;
+  unsigned int new_size;
   unsigned int offset;
   unsigned int new_offset;
   unsigned char fde_encoding;
@@ -296,9 +298,10 @@ struct eh_cie_fde
   unsigned char lsda_offset;
   unsigned int cie : 1;
   unsigned int removed : 1;
+  unsigned int add_augmentation_size : 1;
+  unsigned int add_fde_encoding : 1;
   unsigned int make_relative : 1;
   unsigned int make_lsda_relative : 1;
-  unsigned int need_relative : 1;
   unsigned int need_lsda_relative : 1;
   unsigned int per_encoding_relative : 1;
 };
Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.35
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.35 elf-eh-frame.c
--- bfd/elf-eh-frame.c	14 Oct 2004 23:38:08 -0000	1.35
+++ bfd/elf-eh-frame.c	13 Nov 2004 09:55:38 -0000
@@ -380,7 +380,7 @@ #define GET_RELOC(buf)					\
 		   && cie_compare (&cie, &hdr_info->last_cie) == 0)
 		  || cie_usage_count == 0)
 		{
-		  new_size -= cie.hdr.length + 4;
+		  new_size -= last_cie_inf->new_size;
 		  last_cie_inf->removed = 1;
 		}
 	      else
@@ -514,9 +514,33 @@ #define GET_RELOC(buf)					\
 	  if (info->shared
 	      && (get_elf_backend_data (abfd)
 		  ->elf_backend_can_make_relative_eh_frame
-		  (abfd, info, sec))
-	      && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
-	    cie.make_relative = 1;
+		  (abfd, info, sec)))
+	    {
+	      if ((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
+		cie.make_relative = 1;
+	      /* If the CIE doesn't already have an 'R' entry, it's fairly
+		 easy to add one, provided that there's no aligned data
+		 after the augmentation string.  */
+	      else if (cie.fde_encoding == DW_EH_PE_omit
+		       && (cie.per_encoding & 0xf0) != DW_EH_PE_aligned)
+		{
+		  cie.make_relative = 1;
+
+		  /* If the augmentation string is currently empty, record
+		     that we want to add 'z' to it and a length byte to the
+		     associated data.  */
+		  if (*cie.augmentation == 0)
+		    {
+		      this_inf->add_augmentation_size = 1;
+		      this_inf->growth += 2;
+		    }
+
+		  /* Record that we need to add 'R' to the augmentation
+		     string and an FDE encoding to the augmentation data.  */
+		  this_inf->add_fde_encoding = 1;
+		  this_inf->growth += 2;
+		}
+	    }
 
 	  if (info->shared
 	      && (get_elf_backend_data (abfd)
@@ -574,23 +598,36 @@ #define GET_RELOC(buf)					\
 		}
 	      cie_usage_count++;
 	      hdr_info->fde_count++;
-	    }
-	  if (cie.lsda_encoding != DW_EH_PE_omit)
-	    {
-	      unsigned int dummy;
+	      if (cie.lsda_encoding != DW_EH_PE_omit)
+		{
+		  unsigned int dummy;
 
-	      aug = buf;
-	      buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
-	      if (cie.augmentation[0] == 'z')
-		read_uleb128 (dummy, buf);
-	      /* If some new augmentation data is added before LSDA
-		 in FDE augmentation area, this need to be adjusted.  */
-	      this_inf->lsda_offset = (buf - aug);
+		  aug = buf;
+		  buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
+		  if (cie.augmentation[0] == 'z')
+		    read_uleb128 (dummy, buf);
+		  /* If some new augmentation data is added before LSDA
+		     in FDE augmentation area, this need to be adjusted.  */
+		  this_inf->lsda_offset = (buf - aug);
+		}
+	      else if (last_cie_inf->add_augmentation_size)
+		this_inf->growth += 1;
 	    }
 	  buf = last_fde + 4 + hdr.length;
 	  SKIP_RELOCS (buf);
 	}
 
+      this_inf->new_size = this_inf->size + this_inf->growth;
+      if (this_inf->growth > 0)
+	{
+	  /* Round the size up the next alignment boundary and adjust
+	     the section size accordingly.
+
+	     ??? It would be better to trim any existing padding first.  */
+	  this_inf->new_size = (this_inf->new_size + ptr_size - 1) & -ptr_size;
+	  new_size += this_inf->new_size - this_inf->size;
+	}
+
       this_inf->fde_encoding = cie.fde_encoding;
       this_inf->lsda_encoding = cie.lsda_encoding;
       sec_info->count++;
@@ -606,7 +643,7 @@ #define GET_RELOC(buf)					\
     if (!ent->removed)
       {
 	ent->new_offset = offset;
-	offset += ent->size;
+	offset += ent->new_size;
 	if (ent->cie)
 	  last_cie_inf = ent;
 	else
@@ -614,7 +651,7 @@ #define GET_RELOC(buf)					\
       }
   hdr_info->last_cie_inf = last_cie_inf;
 
-  /* Shrink the sec as needed.  */
+  /* Resize the sec as needed.  */
   sec->rawsize = sec->size;
   sec->size = new_size;
   if (sec->size == 0)
@@ -759,13 +796,8 @@ _bfd_elf_eh_frame_section_offset (bfd *o
      relocation against FDE's initial_location field.  */
   if (!sec_info->entry[mid].cie
       && sec_info->entry[mid].cie_inf->make_relative
-      && offset == sec_info->entry[mid].offset + 8
-      && (sec_info->entry[mid].cie_inf->need_relative
-	  || !hdr_info->offsets_adjusted))
-    {
-      sec_info->entry[mid].cie_inf->need_relative = 1;
-      return (bfd_vma) -2;
-    }
+      && offset == sec_info->entry[mid].offset + 8)
+    return (bfd_vma) -2;
 
   /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
      for run-time relocation against LSDA field.  */
@@ -782,8 +814,11 @@ _bfd_elf_eh_frame_section_offset (bfd *o
 
   if (hdr_info->offsets_adjusted)
     offset -= sec->output_offset;
+  /* If the new entry is bigger than the original, all the new bytes
+     will be inserted before the first relocation.  */
   return (offset + sec_info->entry[mid].new_offset
-	  - sec_info->entry[mid].offset);
+	  - sec_info->entry[mid].offset
+	  + sec_info->entry[mid].growth);
 }
 
 /* Write out .eh_frame section.  This is called with the relocated
@@ -798,7 +833,6 @@ _bfd_elf_write_section_eh_frame (bfd *ab
   struct eh_frame_sec_info *sec_info;
   struct elf_link_hash_table *htab;
   struct eh_frame_hdr_info *hdr_info;
-  bfd_byte *p, *buf;
   unsigned int leb128_tmp;
   unsigned int ptr_size;
   struct eh_cie_fde *ent;
@@ -851,7 +885,21 @@ _bfd_elf_write_section_eh_frame (bfd *ab
   if (hdr_info->array == NULL)
     hdr_info = NULL;
 
-  p = contents;
+  /* The new offsets can be bigger or smaller than the original offsets.
+     We therefore need to make two passes over the section: one backward
+     pass to move entries up and one forward pass to move entries down.
+     The two passes won't interfere with each other because the entries
+     are not reordered  */
+  for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
+    if (!ent->removed && ent->new_offset > ent->offset)
+      memmove (contents + ent->new_offset - sec->output_offset,
+	       contents + ent->offset - sec->output_offset, ent->size);
+
+  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
+    if (!ent->removed && ent->new_offset < ent->offset)
+      memmove (contents + ent->new_offset - sec->output_offset,
+	       contents + ent->offset - sec->output_offset, ent->size);
+
   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
     {
       if (ent->removed)
@@ -860,20 +908,27 @@ _bfd_elf_write_section_eh_frame (bfd *ab
       if (ent->cie)
 	{
 	  /* CIE */
-	  if (ent->need_relative
+	  if (ent->make_relative
 	      || ent->need_lsda_relative
 	      || ent->per_encoding_relative)
 	    {
-	      unsigned char *aug;
+	      unsigned char *buf, *aug, *end;
 	      unsigned int action;
 	      unsigned int dummy, per_width, per_encoding;
 
 	      /* Need to find 'R' or 'L' augmentation's argument and modify
 		 DW_EH_PE_* value.  */
-	      action = ((ent->need_relative ? 1 : 0)
+	      action = ((ent->make_relative ? 1 : 0)
 			| (ent->need_lsda_relative ? 2 : 0)
 			| (ent->per_encoding_relative ? 4 : 0));
-	      buf = contents + ent->offset - sec->output_offset;
+	      buf = contents + ent->new_offset - sec->output_offset;
+	      end = buf + ent->size;
+
+	      /* Install the new size, filling the extra bytes with
+		 DW_CFA_nops.  */
+	      memset (end, 0, ent->new_size - ent->size);
+	      bfd_put_32 (abfd, ent->new_size - 4, buf);
+
 	      /* Skip length, id and version.  */
 	      buf += 9;
 	      aug = buf;
@@ -883,10 +938,46 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 	      read_uleb128 (dummy, buf);
 	      if (*aug == 'z')
 		{
+		  /* Bump the size if we're adding an FDE encoding byte.
+		     The uleb128 will always be a single byte for the
+		     kind of augmentation strings that we're prepared
+		     to handle.  */
+		  if (ent->add_fde_encoding)
+		    *buf += 1;
 		  read_uleb128 (dummy, buf);
 		  aug++;
 		}
 
+	      if (ent->add_fde_encoding)
+		{
+		  BFD_ASSERT (action & 1);
+		  if (ent->add_augmentation_size)
+		    {
+		      /* We need to insert 'zR' into the augmentation
+			 string and add two bytes to the augmentation data.
+			 Shuffle everything appropriately and move BUF to
+			 account for the new string length.  */
+		      memmove (buf + 4, buf, end - buf);
+		      memmove (aug + 2, aug, buf - aug);
+		      buf += 2;
+
+		      *aug++ = 'z';
+		      *buf++ = 1;
+		    }
+		  else
+		    {
+		      /* As above, but we only need to insert 'R' into
+			 the augmentation string and we only need to
+			 add one byte to the data.  */
+		      memmove (buf + 2, buf, end - buf);
+		      memmove (aug + 1, aug, buf - aug);
+		      buf++;
+		    }
+		  *aug++ = 'R';
+		  *buf++ = DW_EH_PE_pcrel;
+		  action &= ~1;
+		}
+
 	      while (action)
 		switch (*aug++)
 		  {
@@ -915,7 +1006,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 
 			val = read_value (abfd, buf, per_width,
 					  get_DW_EH_PE_signed (per_encoding));
-			val += ent->offset - ent->new_offset;
+			val += ent->offset - ent->new_offset - ent->growth;
 			write_value (abfd, buf, val, per_width);
 			action &= ~4;
 		      }
@@ -938,10 +1029,18 @@ _bfd_elf_write_section_eh_frame (bfd *ab
       else if (ent->size > 4)
 	{
 	  /* FDE */
+	  bfd_byte *buf, *end;
 	  bfd_vma value, address;
 	  unsigned int width;
 
-	  buf = contents + ent->offset - sec->output_offset;
+	  buf = contents + ent->new_offset - sec->output_offset;
+	  end = buf + ent->size;
+
+	  /* Install the new size, filling the extra bytes with
+	     DW_CFA_nops.  */
+	  memset (end, 0, ent->new_size - ent->size);
+	  bfd_put_32 (abfd, ent->new_size - 4, buf);
+
 	  /* Skip length.  */
 	  buf += 4;
 	  value = ent->new_offset + 4 - ent->cie_inf->new_offset;
@@ -972,7 +1071,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 		  address += sec->output_section->vma + ent->offset + 8;
 		  break;
 		}
-	      if (ent->cie_inf->need_relative)
+	      if (ent->cie_inf->make_relative)
 		value -= sec->output_section->vma + ent->new_offset + 8;
 	      write_value (abfd, buf, value, width);
 	    }
@@ -1001,14 +1100,18 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 		  write_value (abfd, buf, value, width);
 		}
 	    }
+	  else if (ent->cie_inf->add_augmentation_size)
+	    {
+	      /* Skip the PC and length and insert a zero byte for the
+		 augmentation size.  */
+	      buf += width * 2;
+	      memmove (buf + 1, buf, end - buf);
+	      *buf = 0;
+	    }
 	}
       else
 	/* Terminating FDE must be at the end of .eh_frame section only.  */
 	BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
-
-      BFD_ASSERT (p == contents + ent->new_offset - sec->output_offset);
-      memmove (p, contents + ent->offset - sec->output_offset, ent->size);
-      p += ent->size;
     }
 
     {
@@ -1021,6 +1124,8 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 	  && ((sec->output_offset + sec->size + pad)
 	      <= sec->output_section->size))
 	{
+	  bfd_byte *buf;
+
 	  /* Find the last CIE/FDE.  */
 	  ent = sec_info->entry + sec_info->count;
 	  while (--ent != sec_info->entry)
@@ -1035,20 +1140,17 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 
 	  buf = contents + ent->new_offset - sec->output_offset;
 
-	  /* Update length.  */
-	  ent->size += pad;
-	  bfd_put_32 (abfd, ent->size - 4, buf);
-
 	  /* Pad it with DW_CFA_nop  */
-	  memset (p, 0, pad);
-	  p += pad;
+	  memset (buf + ent->new_size, 0, pad);
+
+	  /* Update length.  */
+	  ent->new_size += pad;
+	  bfd_put_32 (abfd, ent->new_size - 4, buf);
 
 	  sec->size += pad;
 	}
     }
 
-  BFD_ASSERT ((bfd_size_type) (p - contents) == sec->size);
-
   return bfd_set_section_contents (abfd, sec->output_section,
 				   contents, (file_ptr) sec->output_offset,
 				   sec->size);
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mips-elf/mips-elf.exp,v
retrieving revision 1.18
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.18 mips-elf.exp
--- ld/testsuite/ld-mips-elf/mips-elf.exp	8 Jul 2004 15:43:00 -0000	1.18
+++ ld/testsuite/ld-mips-elf/mips-elf.exp	13 Nov 2004 09:55:38 -0000
@@ -75,3 +75,7 @@ if $has_newabi {
 }
 run_dump_test "reloc-2"
 run_dump_test "reloc-merge-lo16"
+if {$has_newabi && $linux_gnu} {
+    run_dump_test "eh-frame1-n32"
+    run_dump_test "eh-frame1-n64"
+}
diff -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1-n32.d
--- /dev/null	Fri Apr 23 00:21:55 2004
+++ ld/testsuite/ld-mips-elf/eh-frame1-n32.d	Sat Nov 13 09:43:09 2004
@@ -0,0 +1,263 @@
+#name: MIPS eh-frame 1, n32
+#source: eh-frame1.s
+#source: eh-frame1.s
+#as: -EB -n32 --defsym alignment=2 --defsym fill=0x40
+#readelf: --relocs -wf
+#ld: -shared -melf32btsmipn32 -Teh-frame1.ld
+
+Relocation section '\.rel\.dyn' .*:
+# Initial PCs for the FDEs attached to CIE 0xbc
+#...
+000300dc  00000003 R_MIPS_REL32     
+000300f0  00000003 R_MIPS_REL32     
+# Likewise CIE 0x220
+#...
+00030240  00000003 R_MIPS_REL32     
+00030254  00000003 R_MIPS_REL32     
+#...
+0003008b  00000503 R_MIPS_REL32      00000000   foo
+000300d0  00000503 R_MIPS_REL32      00000000   foo
+0003010e  00000503 R_MIPS_REL32      00000000   foo
+000301ef  00000503 R_MIPS_REL32      00000000   foo
+00030234  00000503 R_MIPS_REL32      00000000   foo
+00030272  00000503 R_MIPS_REL32      00000000   foo
+The section \.eh_frame contains:
+
+00000000 00000010 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+
+00000014 00000010 00000018 FDE cie=00000000 pc=00020000..00020010
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000028 00000010 0000002c FDE cie=00000000 pc=00020010..00020030
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic2 removed
+0000003c 00000010 00000040 FDE cie=00000000 pc=00020030..00020060
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic3 removed
+00000050 00000010 00000054 FDE cie=00000000 pc=00020060..000200a0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic4 removed
+00000064 00000010 00000068 FDE cie=00000000 pc=000200a0..000200f0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000078 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zRP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10 00 00 00 00 00
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000094 00000010 00000020 FDE cie=00000078 pc=000200f0..00020100
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+
+000000a8 00000010 00000034 FDE cie=00000078 pc=00020100..00020120
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+
+000000bc 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     50 00 00 00 00 00 00 00
+
+
+000000d4 00000010 0000001c FDE cie=000000bc pc=00020120..00020130
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+
+000000e8 00000010 00000030 FDE cie=000000bc pc=00020130..00020150
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+
+000000fc 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zPR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     00 00 00 00 00 10
+
+  DW_CFA_advance_loc: 0 to 00000000
+
+00000114 00000010 0000001c FDE cie=000000fc pc=00020150..00020160
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+
+# FDE for .discard removed
+# zPR2 removed
+00000128 00000010 00000030 FDE cie=000000fc pc=00020160..00020190
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+
+0000013c 00000010 00000044 FDE cie=000000fc pc=00020190..000201d0
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+
+00000150 00000010 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+
+00000164 00000010 00000018 FDE cie=00000150 pc=000201d0..000201e0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic1 removed, followed by repeat of above
+00000178 00000010 0000002c FDE cie=00000150 pc=000201e0..000201f0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0000018c 00000010 00000040 FDE cie=00000150 pc=000201f0..00020210
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000001a0 00000010 00000054 FDE cie=00000150 pc=00020210..00020240
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000001b4 00000010 00000068 FDE cie=00000150 pc=00020240..00020280
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000001c8 00000010 0000007c FDE cie=00000150 pc=00020280..000202d0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000001dc 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zRP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10 00 00 00 00 00
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_nop
+  DW_CFA_nop
+
+000001f8 00000010 00000020 FDE cie=000001dc pc=000202d0..000202e0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+
+0000020c 00000010 00000034 FDE cie=000001dc pc=000202e0..00020300
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+
+00000220 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     50 00 00 00 00 00 00 00
+
+
+00000238 00000010 0000001c FDE cie=00000220 pc=00020300..00020310
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+
+0000024c 00000010 00000030 FDE cie=00000220 pc=00020310..00020330
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+
+00000260 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zPR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     00 00 00 00 00 10
+
+  DW_CFA_advance_loc: 0 to 00000000
+
+00000278 00000010 0000001c FDE cie=00000260 pc=00020330..00020340
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+
+0000028c 00000010 00000030 FDE cie=00000260 pc=00020340..00020370
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+
+000002a0 00000010 00000044 FDE cie=00000260 pc=00020370..000203b0
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+
+000002b4 00000010 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+
+000002c8 00000010 00000018 FDE cie=000002b4 pc=000203b0..000203c0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
diff -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1-n64.d
--- /dev/null	Fri Apr 23 00:21:55 2004
+++ ld/testsuite/ld-mips-elf/eh-frame1-n64.d	Sat Nov 13 09:43:09 2004
@@ -0,0 +1,423 @@
+#name: MIPS eh-frame 1, n64
+#source: eh-frame1.s
+#source: eh-frame1.s
+#as: -EB -64 --defsym alignment=3 --defsym fill=0x40
+#readelf: --relocs -wf
+#ld: -shared -melf64btsmip -Teh-frame1.ld
+
+Relocation section '\.rel\.dyn' .*:
+# Initial PCs for the FDEs attached to CIE 0x120
+#...
+000000030148  000000001203 R_MIPS_REL32 *
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+000000030168  000000001203 R_MIPS_REL32 *
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+# Likewise CIE 0x340
+#...
+000000030368  000000001203 R_MIPS_REL32 *
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+000000030388  000000001203 R_MIPS_REL32 *
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+#...
+0000000300cb  000500001203 R_MIPS_REL32      0000000000000000 foo
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+000000030138  000500001203 R_MIPS_REL32      0000000000000000 foo
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+000000030192  000500001203 R_MIPS_REL32      0000000000000000 foo
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+0000000302eb  000500001203 R_MIPS_REL32      0000000000000000 foo
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+000000030358  000500001203 R_MIPS_REL32      0000000000000000 foo
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+0000000303b2  000500001203 R_MIPS_REL32      0000000000000000 foo
+ *Type2: R_MIPS_64 *
+ *Type3: R_MIPS_NONE *
+The section \.eh_frame contains:
+
+00000000 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0000001c 0000001c FDE cie=00000000 pc=00020000..00020010
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000038 0000001c 0000003c FDE cie=00000000 pc=00020010..00020030
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic2 removed
+00000058 0000001c 0000005c FDE cie=00000000 pc=00020030..00020060
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic3 removed
+00000078 0000001c 0000007c FDE cie=00000000 pc=00020060..000200a0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic4 removed
+00000098 0000001c 0000009c FDE cie=00000000 pc=000200a0..000200f0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000000b8 00000024 00000000 CIE
+  Version:               1
+  Augmentation:          "zRP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10 00 00 00 00 00 00 00 00 00
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000000e0 0000001c 0000002c FDE cie=000000b8 pc=000200f0..00020100
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+  DW_CFA_advance_loc: 0 to 000200f0
+
+00000100 0000001c 0000004c FDE cie=000000b8 pc=00020100..00020120
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+  DW_CFA_advance_loc: 0 to 00020100
+
+00000120 0000001c 00000000 CIE
+  Version:               1
+  Augmentation:          "zP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+00000140 0000001c 00000024 FDE cie=00000120 pc=00020120..00020130
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+  DW_CFA_advance_loc: 0 to 00020120
+
+00000160 0000001c 00000044 FDE cie=00000120 pc=00020130..00020150
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+  DW_CFA_advance_loc: 0 to 00020130
+
+00000180 0000001c 00000000 CIE
+  Version:               1
+  Augmentation:          "zPR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     00 00 00 00 00 00 00 00 00 10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+
+000001a0 0000001c 00000024 FDE cie=00000180 pc=00020150..00020160
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+  DW_CFA_advance_loc: 0 to 00020150
+
+# FDE for .discard removed
+# zPR2 removed
+000001c0 0000001c 00000044 FDE cie=00000180 pc=00020160..00020190
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+  DW_CFA_advance_loc: 0 to 00020160
+
+000001e0 0000001c 00000064 FDE cie=00000180 pc=00020190..000201d0
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+  DW_CFA_advance_loc: 0 to 00020190
+
+00000200 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000218 0000001c 0000001c FDE cie=00000200 pc=000201d0..000201e0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+# basic1 removed, followed by repeat of above
+00000238 0000001c 0000003c FDE cie=00000200 pc=000201e0..000201f0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000258 0000001c 0000005c FDE cie=00000200 pc=000201f0..00020210
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000278 0000001c 0000007c FDE cie=00000200 pc=00020210..00020240
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000298 0000001c 0000009c FDE cie=00000200 pc=00020240..00020280
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000002b8 0000001c 000000bc FDE cie=00000200 pc=00020280..000202d0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+000002d8 00000024 00000000 CIE
+  Version:               1
+  Augmentation:          "zRP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10 00 00 00 00 00 00 00 00 00
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000300 0000001c 0000002c FDE cie=000002d8 pc=000202d0..000202e0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+  DW_CFA_advance_loc: 0 to 000202d0
+
+00000320 0000001c 0000004c FDE cie=000002d8 pc=000202e0..00020300
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+  DW_CFA_advance_loc: 0 to 000202e0
+
+00000340 0000001c 00000000 CIE
+  Version:               1
+  Augmentation:          "zP"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+00000360 0000001c 00000024 FDE cie=00000340 pc=00020300..00020310
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+  DW_CFA_advance_loc: 0 to 00020300
+
+00000380 0000001c 00000044 FDE cie=00000340 pc=00020310..00020330
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+  DW_CFA_advance_loc: 0 to 00020310
+
+000003a0 0000001c 00000000 CIE
+  Version:               1
+  Augmentation:          "zPR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     00 00 00 00 00 00 00 00 00 10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+
+000003c0 0000001c 00000024 FDE cie=000003a0 pc=00020330..00020340
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+  DW_CFA_advance_loc: 0 to 00020330
+
+000003e0 0000001c 00000044 FDE cie=000003a0 pc=00020340..00020370
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+  DW_CFA_advance_loc: 0 to 00020340
+
+00000400 0000001c 00000064 FDE cie=000003a0 pc=00020370..000203b0
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+  DW_CFA_advance_loc: 0 to 00020370
+
+00000420 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: 4
+  Return address column: 31
+  Augmentation data:     10
+
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_advance_loc: 0 to 00000000
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000438 0000001c 0000001c FDE cie=00000420 pc=000203b0..000203c0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
diff -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1.ld
--- /dev/null	Fri Apr 23 00:21:55 2004
+++ ld/testsuite/ld-mips-elf/eh-frame1.ld	Sat Nov 13 09:43:09 2004
@@ -0,0 +1,18 @@
+SECTIONS
+{
+  . = 0x10000;
+  .dynamic : { *(.dynamic) }
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .rel.dyn : { *(.rel.dyn) }
+
+  . = 0x20000;
+  .text : { *(.text) }
+
+  . = 0x30000;
+  .eh_frame : { *(.eh_frame) }
+  .got : { *(.got) }
+
+  /DISCARD/ : { *(*) }
+}
diff -u /dev/null ld/testsuite/ld-mips-elf/eh-frame1.s
--- /dev/null	Fri Apr 23 00:21:55 2004
+++ ld/testsuite/ld-mips-elf/eh-frame1.s	Sat Nov 13 09:43:09 2004
@@ -0,0 +1,148 @@
+#----------------------------------------------------------------------------
+# Macros
+#----------------------------------------------------------------------------
+
+	mask = (1 << alignment) - 1
+
+	# Output VALUE as an unaligned pointer-sized quantity.
+	.macro pbyte value
+	.if alignment == 2
+	.4byte		\value
+	.else
+	.8byte		\value
+	.endif
+	.endm
+
+
+	# Start a new CIE, and emit everything up to the augmentation data.
+	# Use LABEL to mark the start of the entry and AUG as the augmentation
+	# string.
+	.macro start_cie label,aug
+	.section	.eh_frame,"aw",@progbits
+\label:
+	.word		2f-1f		# Length
+1:
+	.word		0		# Identifier
+	.byte		1		# Version
+	.string		"\aug"		# Augmentation
+	.byte		1		# Code alignment
+	.byte		4		# Data alignment
+	.byte		31		# Return address column
+	.endm
+
+
+	# Create a dummy function of SIZE bytes in SECTION and emit the
+	# first four entries of an FDE for it (total 16 bytes).
+	.macro start_fde cie,section,size
+	.section	\section,"ax",@progbits
+3:
+	.rept		\size / 4
+	nop
+	.endr
+4:
+	.section	.eh_frame,"aw",@progbits
+	.word		2f-1f		# Length
+1:
+	.word		.-\cie		# CIE offset
+	pbyte		3b		# Initial PC
+	pbyte		4b-3b		# Size of code
+	.endm
+
+
+	# Finish a CIE or FDE entry.
+	.macro end_entry
+	.p2align	alignment,fill
+2:
+	.endm
+
+
+	# Start the augmentation data for a CIE that has a 'P' entry
+	# followed by EXTRA bytes.  AUGLEN is the length of augmentation
+	# string (including zero terminator), ENCODING is the encoding to
+	# use for the personality routine and VALUE is the value it
+	# should have.
+	.macro		persaug auglen,extra,encoding,value
+	.if (\encoding & 0xf0) == 0x50
+	.byte		(-(9 + \auglen + 3 + 2) & mask) + 2 + mask + \extra
+	.byte		\encoding
+	.fill		-(9 + \auglen + 3 + 2) & mask,1,0
+	.else
+	.byte		2 + mask + \extra
+	.byte		\encoding
+	.endif
+	pbyte		\value
+	.endm
+
+
+	.macro cie_basic label
+	start_cie	\label,""
+	end_entry
+	.endm
+
+	.macro fde_basic cie,section,size
+	start_fde	\cie,\section,\size
+	end_entry
+	.endm
+
+
+	.macro cie_zP label,encoding,value
+	start_cie	 \label,"zP"
+	persaug		3,0,\encoding,\value
+	end_entry
+	.endm
+
+	.macro fde_zP cie,section,size
+	start_fde	 \cie,\section,\size
+	.byte		 0		# Augmentation length
+	end_entry
+	.endm
+
+
+	.macro cie_zPR label,encoding,value
+	start_cie	 \label,"zPR"
+	persaug		4,1,\encoding,\value
+	.byte		0		# FDE enconding
+	end_entry
+	.endm
+
+	.macro fde_zPR cie,section,size
+	start_fde	\cie,\section,\size
+	.byte		0		# Augmentation length
+	end_entry
+	.endm
+
+#----------------------------------------------------------------------------
+# Test code
+#----------------------------------------------------------------------------
+
+	cie_basic	basic1
+	fde_basic	basic1,.text,0x10
+	fde_basic	basic1,.text,0x20
+
+	cie_basic	basic2
+	fde_basic	basic2,.text,0x30
+
+	cie_basic	basic3
+	fde_basic	basic3,.text,0x40
+
+	cie_basic	basic4
+	fde_basic	basic4,.text,0x50
+
+	cie_zP		zP_unalign1,0x00,foo
+	fde_zP		zP_unalign1,.text,0x10
+	fde_zP		zP_unalign1,.text,0x20
+
+	cie_zP		zP_align1,0x50,foo
+	fde_zP		zP_align1,.text,0x10
+	fde_zP		zP_align1,.text,0x20
+
+	cie_zPR		zPR1,0x00,foo
+	fde_zPR		zPR1,.text,0x10
+	fde_zPR		zPR1,.discard,0x20
+
+	cie_zPR		zPR2,0x00,foo
+	fde_zPR		zPR2,.text,0x30
+	fde_zPR		zPR2,.text,0x40
+
+	cie_basic	basic5
+	fde_basic	basic5,.text,0x10


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]