bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 19 Sep 2009 08:06:11 +0000 (08:06 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sat, 19 Sep 2009 08:06:11 +0000 (08:06 +0000)
* elf-bfd.h (eh_cie_fde): Add personality_offset and
make_per_encoding_relative to the CIE structure.  Add a padding field.
* elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Use 0x70
rather than 0xf0 when masking out the base address encoding
Record the offset of personality data from the start of the CIE.
Remove a repeated elf_backend_can_make_relative_eh_frame check.
(find_merged_cie): Take an info argument.  If the personality
binds locally, try converting an absolute personality into
a local one.
(_bfd_elf_discard_section_eh_frame): Use 0x70 rather than 0xf0
when masking out the base address encoding.  Update the call to
find_merged_cie.
(_bfd_elf_eh_frame_section_offset): Discard relocations against
the personality data if we are converting into PC-relative form.
(_bfd_elf_write_section_eh_frame): Use 0x70 rather than 0xf0
when masking out the base address encoding.  Handle
make_per_encoding_relative.

ld/testsuite/
* ld-mips-elf/eh-frame5.s, ld-mips-elf/eh-frame5.ld,
ld-mips-elf/eh-frame5.d: New test.
* ld-mips-elf/mips-elf.exp: Run it.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf-eh-frame.c
ld/testsuite/ChangeLog
ld/testsuite/ld-mips-elf/eh-frame5.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/eh-frame5.ld [new file with mode: 0644]
ld/testsuite/ld-mips-elf/eh-frame5.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips-elf.exp

index a00939905690bcb91c8c2f2260ecad52db2bf161..a4f99e79f4d11ecf90db2dba4c6299e5b5483316 100644 (file)
@@ -1,3 +1,23 @@
+2009-09-19  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * elf-bfd.h (eh_cie_fde): Add personality_offset and
+       make_per_encoding_relative to the CIE structure.  Add a padding field.
+       * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Use 0x70
+       rather than 0xf0 when masking out the base address encoding
+       Record the offset of personality data from the start of the CIE.
+       Remove a repeated elf_backend_can_make_relative_eh_frame check.
+       (find_merged_cie): Take an info argument.  If the personality
+       binds locally, try converting an absolute personality into
+       a local one.
+       (_bfd_elf_discard_section_eh_frame): Use 0x70 rather than 0xf0
+       when masking out the base address encoding.  Update the call to
+       find_merged_cie.
+       (_bfd_elf_eh_frame_section_offset): Discard relocations against
+       the personality data if we are converting into PC-relative form.
+       (_bfd_elf_write_section_eh_frame): Use 0x70 rather than 0xf0
+       when masking out the base address encoding.  Handle
+       make_per_encoding_relative.
+
 2009-09-18  Alan Modra  <amodra@bigpond.net.au>
 
        PR ld/10406
index 82c7c774d5f9645cfe1ec39cd13fd52b7a9960a5..3f2d52864b4e55d057a9891d7495e39330b62006 100644 (file)
@@ -305,6 +305,10 @@ struct eh_cie_fde
        asection *sec;
       } u;
 
+      /* The offset of the personality data from the start of the CIE,
+        or 0 if the CIE doesn't have any.  */
+      unsigned int personality_offset : 8;
+
       /* True if we have marked relocations associated with this CIE.  */
       unsigned int gc_mark : 1;
 
@@ -312,8 +316,13 @@ struct eh_cie_fde
         a PC-relative one.  */
       unsigned int make_lsda_relative : 1;
 
-      /* True if the CIE contains personality data and if that data
-        uses a PC-relative encoding.  */
+      /* True if we have decided to turn an absolute personality
+        encoding into a PC-relative one.  */
+      unsigned int make_per_encoding_relative : 1;
+
+      /* True if the CIE contains personality data and if that
+        data uses a PC-relative encoding.  Always true when
+        make_per_encoding_relative is.  */
       unsigned int per_encoding_relative : 1;
 
       /* True if we need to add an 'R' (FDE encoding) entry to the
@@ -322,6 +331,9 @@ struct eh_cie_fde
 
       /* True if we have merged this CIE with another.  */
       unsigned int merged : 1;
+
+      /* Unused bits.  */
+      unsigned int pad1 : 18;
     } cie;
   } u;
   unsigned int reloc_index;
index 5525d2041de74e209a3f858f4b26e82dcdae4a3b..4ea96273426f706d20e6f9c13259fdb8ab0f5b2d 100644 (file)
@@ -675,11 +675,12 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
                      per_width = get_DW_EH_PE_width (cie->per_encoding,
                                                      ptr_size);
                      REQUIRE (per_width);
-                     if ((cie->per_encoding & 0xf0) == DW_EH_PE_aligned)
+                     if ((cie->per_encoding & 0x70) == DW_EH_PE_aligned)
                        {
                          length = -(buf - ehbuf) & (per_width - 1);
                          REQUIRE (skip_bytes (&buf, end, length));
                        }
+                     this_inf->u.cie.personality_offset = buf - start;
                      ENSURE_NO_RELOCS (buf);
                      /* Ensure we have a reloc here.  */
                      REQUIRE (GET_RELOC (buf));
@@ -705,27 +706,23 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
                  ->elf_backend_can_make_relative_eh_frame
                  (abfd, info, sec)))
            {
-             if ((cie->fde_encoding & 0xf0) == DW_EH_PE_absptr)
+             if ((cie->fde_encoding & 0x70) == DW_EH_PE_absptr)
                this_inf->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->per_encoding & 0x70) != DW_EH_PE_aligned)
                {
                  if (*cie->augmentation == 0)
                    this_inf->add_augmentation_size = 1;
                  this_inf->u.cie.add_fde_encoding = 1;
                  this_inf->make_relative = 1;
                }
-           }
 
-         if (info->shared
-             && (get_elf_backend_data (abfd)
-                 ->elf_backend_can_make_lsda_relative_eh_frame
-                 (abfd, info, sec))
-             && (cie->lsda_encoding & 0xf0) == DW_EH_PE_absptr)
-           cie->can_make_lsda_relative = 1;
+             if ((cie->lsda_encoding & 0x70) == DW_EH_PE_absptr)
+               cie->can_make_lsda_relative = 1;
+           }
 
          /* If FDE encoding was not specified, it defaults to
             DW_EH_absptr.  */
@@ -843,7 +840,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
          cie->length -= end - insns_end;
        }
       if (set_loc_count
-         && ((cie->fde_encoding & 0xf0) == DW_EH_PE_pcrel
+         && ((cie->fde_encoding & 0x70) == DW_EH_PE_pcrel
              || this_inf->make_relative))
        {
          unsigned int cnt;
@@ -963,7 +960,7 @@ _bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec,
    relocations in REL.  */
 
 static struct eh_cie_fde *
-find_merged_cie (bfd *abfd, asection *sec,
+find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
                 struct eh_frame_hdr_info *hdr_info,
                 struct elf_reloc_cookie *cookie,
                 struct eh_cie_fde *cie_inf)
@@ -993,6 +990,8 @@ find_merged_cie (bfd *abfd, asection *sec,
 
   if (cie->per_encoding != DW_EH_PE_omit)
     {
+      bfd_boolean per_binds_local;
+
       /* Work out the address of personality routine, either as an absolute
         value or as a symbol.  */
       rel = cookie->rels + cie->personality.reloc_index;
@@ -1016,6 +1015,7 @@ find_merged_cie (bfd *abfd, asection *sec,
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
          cie->personality.h = h;
+         per_binds_local = SYMBOL_REFERENCES_LOCAL (info, h);
        }
       else
        {
@@ -1036,6 +1036,17 @@ find_merged_cie (bfd *abfd, asection *sec,
          cie->personality.val = (sym->st_value
                                  + sym_sec->output_offset
                                  + sym_sec->output_section->vma);
+         per_binds_local = TRUE;
+       }
+
+      if (per_binds_local
+         && info->shared
+         && (cie->per_encoding & 0x70) == DW_EH_PE_absptr
+         && (get_elf_backend_data (abfd)
+             ->elf_backend_can_make_relative_eh_frame (abfd, info, sec)))
+       {
+         cie_inf->u.cie.make_per_encoding_relative = 1;
+         cie_inf->u.cie.per_encoding_relative = 1;
        }
     }
 
@@ -1110,9 +1121,9 @@ _bfd_elf_discard_section_eh_frame
        if (!(*reloc_symbol_deleted_p) (ent->offset + 8, cookie))
          {
            if (info->shared
-               && (((ent->fde_encoding & 0xf0) == DW_EH_PE_absptr
+               && (((ent->fde_encoding & 0x70) == DW_EH_PE_absptr
                     && ent->make_relative == 0)
-                   || (ent->fde_encoding & 0xf0) == DW_EH_PE_aligned))
+                   || (ent->fde_encoding & 0x70) == DW_EH_PE_aligned))
              {
                /* If a shared library uses absolute pointers
                   which we cannot turn into PC relative,
@@ -1125,8 +1136,8 @@ _bfd_elf_discard_section_eh_frame
              }
            ent->removed = 0;
            hdr_info->fde_count++;
-           ent->u.fde.cie_inf = find_merged_cie (abfd, sec, hdr_info, cookie,
-                                                 ent->u.fde.cie_inf);
+           ent->u.fde.cie_inf = find_merged_cie (abfd, info, sec, hdr_info,
+                                                 cookie, ent->u.fde.cie_inf);
          }
       }
 
@@ -1276,6 +1287,14 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (sec_info->entry[mid].removed)
     return (bfd_vma) -1;
 
+  /* If converting personality pointers to DW_EH_PE_pcrel, there will be
+     no need for run-time relocation against the personality field.  */
+  if (sec_info->entry[mid].cie
+      && sec_info->entry[mid].u.cie.make_per_encoding_relative
+      && offset == (sec_info->entry[mid].offset + 8
+                   + sec_info->entry[mid].u.cie.personality_offset))
+    return (bfd_vma) -2;
+
   /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
      relocation against FDE's initial_location field.  */
   if (!sec_info->entry[mid].cie
@@ -1452,12 +1471,14 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
                    buf++;
                    break;
                  case 'P':
+                   if (ent->u.cie.make_per_encoding_relative)
+                     *buf |= DW_EH_PE_pcrel;
                    per_encoding = *buf++;
                    per_width = get_DW_EH_PE_width (per_encoding, ptr_size);
                    BFD_ASSERT (per_width != 0);
                    BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
                                == ent->u.cie.per_encoding_relative);
-                   if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
+                   if ((per_encoding & 0x70) == DW_EH_PE_aligned)
                      buf = (contents
                             + ((buf - contents + per_width - 1)
                                & ~((bfd_size_type) per_width - 1)));
@@ -1467,8 +1488,15 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
 
                        val = read_value (abfd, buf, per_width,
                                          get_DW_EH_PE_signed (per_encoding));
-                       val += (bfd_vma) ent->offset - ent->new_offset;
-                       val -= extra_string + extra_data;
+                       if (ent->u.cie.make_per_encoding_relative)
+                         val -= (sec->output_section->vma
+                                 + sec->output_offset
+                                 + (buf - contents));
+                       else
+                         {
+                           val += (bfd_vma) ent->offset - ent->new_offset;
+                           val -= extra_string + extra_data;
+                         }
                        write_value (abfd, buf, val, per_width);
                        action &= ~4;
                      }
@@ -1511,9 +1539,8 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
          address = value;
          if (value)
            {
-             switch (ent->fde_encoding & 0xf0)
+             switch (ent->fde_encoding & 0x70)
                {
-               case DW_EH_PE_indirect:
                case DW_EH_PE_textrel:
                  BFD_ASSERT (hdr_info == NULL);
                  break;
@@ -1550,7 +1577,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
                   + ent->new_offset);
            }
 
-         if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel
+         if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel
              || cie->u.cie.make_lsda_relative)
            {
              buf += ent->lsda_offset;
@@ -1559,7 +1586,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
                                  get_DW_EH_PE_signed (ent->lsda_encoding));
              if (value)
                {
-                 if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel)
+                 if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
                    value += (bfd_vma) ent->offset - ent->new_offset;
                  else if (cie->u.cie.make_lsda_relative)
                    value -= (sec->output_section->vma
@@ -1598,7 +1625,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
                  if (!value)
                    continue;
 
-                 if ((ent->fde_encoding & 0xf0) == DW_EH_PE_pcrel)
+                 if ((ent->fde_encoding & 0x70) == DW_EH_PE_pcrel)
                    value += (bfd_vma) ent->offset + 8 - new_offset;
                  if (ent->make_relative)
                    value -= (sec->output_section->vma
index e19919a5b88e49b9c0e5ea9a7ab363436172d120..abcda78fc2791bed3eb50e6a0787bffc8b665a81 100644 (file)
@@ -1,3 +1,9 @@
+2009-09-19  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * ld-mips-elf/eh-frame5.s, ld-mips-elf/eh-frame5.ld,
+       ld-mips-elf/eh-frame5.d: New test.
+       * ld-mips-elf/mips-elf.exp: Run it.
+
 2009-09-18  Alan Modra  <amodra@bigpond.net.au>
 
        * ld-powerpc/tlsso.d: Update.
diff --git a/ld/testsuite/ld-mips-elf/eh-frame5.d b/ld/testsuite/ld-mips-elf/eh-frame5.d
new file mode 100644 (file)
index 0000000..9720890
--- /dev/null
@@ -0,0 +1,278 @@
+
+Relocation section '.rel.dyn' at offset 0x101f0 contains 8 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+00000000  .* R_MIPS_NONE *
+#
+# The order of the relocations doesn't really matter, but they must
+# be some permutation of the list below.
+#
+00010008  .* R_MIPS_REL32      00000000   pers3
+00000c7b  .* R_MIPS_REL32      00000828   global_pers
+00000d7f  .* R_MIPS_REL32      00000000   extern_indirect_ptr
+00010000  .* R_MIPS_REL32      00000000   pers1
+00010004  .* R_MIPS_REL32      00000000   pers2
+00000caf  .* R_MIPS_REL32      00000000   extern_pers
+00000d4b  .* R_MIPS_REL32      00010008   global_indirect_ptr
+Contents of the \.eh_frame section:
+
+# Text addresses
+# --------------
+# f1 = 0x800
+# f2 = 0x804
+# f3 = 0x808
+# f4 = 0x80c
+# f5 = 0x810
+# f6 = 0x814
+# f7 = 0x818
+# f8 = 0x81c
+# local_pers = 0x820
+# hidden_pers = 0x824
+# global_pers = 0x828
+
+# Data addresses
+# --------------
+# local_indirect_ptr = 0x10000
+# hidden_indirect_ptr = 0x10004
+# global_indirect_ptr = 0x10008
+# LSDA = 0x1000c
+
+#-------------------------------------------------------------------------
+# f1
+#-------------------------------------------------------------------------
+00000000 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xc12: DW_EH_PE_pcrel for personality encoding
+# 0xc13: 0x820 - 0xc13 (local_pers - .)
+# 0xc17: DW_EH_PE_pcrel for LDSA encoding
+# 0xc18: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     10 ff ff fc 0d 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+0000001c 00000014 00000020 FDE cie=00000000 pc=00000800..00000804
+#
+# 0xc2d: 0x1000c - 0xc2d (LDSA - .)
+#
+  Augmentation data:     00 00 f3 df
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+#-------------------------------------------------------------------------
+# f2
+#-------------------------------------------------------------------------
+00000034 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xc46: DW_EH_PE_pcrel for personality encoding
+# 0xc47: 0x824 - 0xc47 (hidden_pers - .)
+# 0xc4d: DW_EH_PE_pcrel for LDSA encoding
+# 0xc4e: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     10 ff ff fb dd 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+00000050 00000014 00000020 FDE cie=00000034 pc=00000804..00000808
+#
+# 0xc61: 0x1000c - 0xc61 (LDSA - .)
+#
+  Augmentation data:     00 00 f3 ab
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+#-------------------------------------------------------------------------
+# f3
+#-------------------------------------------------------------------------
+00000068 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xc7a: DW_EH_PE_absptr for personality encoding
+# 0xc7b: global_pers (reloc above)
+# 0xc7f: DW_EH_PE_pcrel for LDSA encoding
+# 0xc80: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     00 00 00 00 00 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+00000084 00000014 00000020 FDE cie=00000068 pc=00000808..0000080c
+#
+# 0xc95: 0x1000c - 0xc95 (LDSA - .)
+#
+  Augmentation data:     00 00 f3 77
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+#-------------------------------------------------------------------------
+# f4
+#-------------------------------------------------------------------------
+0000009c 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xcae: DW_EH_PE_absptr for personality encoding
+# 0xcaf: extern_pers (reloc above)
+# 0xcb3: DW_EH_PE_pcrel for LDSA encoding
+# 0xcb4: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     00 00 00 00 00 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+000000b8 00000014 00000020 FDE cie=0000009c pc=0000080c..00000810
+#
+# 0xcc9: 0x1000c - 0xcc9 (LDSA - .)
+#
+  Augmentation data:     00 00 f3 43
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+#-------------------------------------------------------------------------
+# f5
+#-------------------------------------------------------------------------
+000000d0 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xce2: DW_EH_PE_indirect | DW_EH_PE_pcrel for personality encoding
+# 0xce3: 0x10000 - 0xce3 (local_indirect_ptr - .)
+# 0xce7: DW_EH_PE_pcrel for LDSA encoding
+# 0xce8: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     90 00 00 f3 1d 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+000000ec 00000014 00000020 FDE cie=000000d0 pc=00000810..00000814
+#
+# 0xcfd: 0x1000c - 0xcfd (LDSA - .)
+#
+  Augmentation data:     00 00 f3 0f
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+#-------------------------------------------------------------------------
+# f6
+#-------------------------------------------------------------------------
+00000104 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xd16: DW_EH_PE_pcrel for personality encoding
+# 0xd17: 0x10004 - 0xd17 (hidden_indirect_ptr - .)
+# 0xd1d: DW_EH_PE_pcrel for LDSA encoding
+# 0xd1e: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     90 00 00 f2 ed 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+00000120 00000014 00000020 FDE cie=00000104 pc=00000814..00000818
+#
+# 0xd31: 0x1000c - 0xd31 (LDSA - .)
+#
+  Augmentation data:     00 00 f2 db
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+#-------------------------------------------------------------------------
+# f7
+#-------------------------------------------------------------------------
+00000138 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xd4a: DW_EH_PE_indirect | DW_EH_PE_absptr for personality encoding
+# 0xd4b: global_indirect_ptr (reloc above)
+# 0xd4f: DW_EH_PE_pcrel for LDSA encoding
+# 0xd50: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     80 00 00 00 00 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+00000154 00000014 00000020 FDE cie=00000138 pc=00000818..0000081c
+#
+# 0xd65: 0x1000c - 0xd65 (LDSA - .)
+#
+  Augmentation data:     00 00 f2 a7
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+#-------------------------------------------------------------------------
+# f8
+#-------------------------------------------------------------------------
+0000016c 00000018 00000000 CIE
+  Version:               1
+  Augmentation:          "zPLR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 31
+#
+# 0xd7e: DW_EH_PE_indirect | DW_EH_PE_absptr for personality encoding
+# 0xd7f: extern_indirect_ptr (reloc above)
+# 0xd83: DW_EH_PE_pcrel for LDSA encoding
+# 0xd84: DW_EH_PE_pcrel | DW_EH_PE_sdata4 for FDE encoding
+#
+  Augmentation data:     80 00 00 00 00 10 1b
+
+  DW_CFA_def_cfa_register: r29
+  DW_CFA_nop
+
+00000188 00000014 00000020 FDE cie=0000016c pc=0000081c..00000820
+#
+# 0xd99: 0x1000c - 0xd99 (LDSA - .)
+#
+  Augmentation data:     00 00 f2 73
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
diff --git a/ld/testsuite/ld-mips-elf/eh-frame5.ld b/ld/testsuite/ld-mips-elf/eh-frame5.ld
new file mode 100644 (file)
index 0000000..f00cb27
--- /dev/null
@@ -0,0 +1,18 @@
+SECTIONS
+{
+  . = 0;
+  .reginfo : { *(.reginfo) }
+  .dynamic : { *(.dynamic) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .rel.dyn : { *(.rel.dyn) }
+  . = 0x800;
+  .text : { *(.text) }
+  . = 0xc00;
+  .eh_frame : { *(.eh_frame) }
+  . = 0x10000;
+  .data : { *(.data) }
+  . = 0x10400;
+  _gp = . + 0x7ff0;
+  .got : { *(.got) }
+}
diff --git a/ld/testsuite/ld-mips-elf/eh-frame5.s b/ld/testsuite/ld-mips-elf/eh-frame5.s
new file mode 100644 (file)
index 0000000..741a021
--- /dev/null
@@ -0,0 +1,107 @@
+       .cfi_startproc
+       .cfi_personality 0x0,local_pers
+       .cfi_lsda 0x0,LSDA
+       .ent    f1
+f1:
+       nop
+       .end    f1
+       .cfi_endproc
+
+       .cfi_startproc
+       .cfi_personality 0x0,hidden_pers
+       .cfi_lsda 0x0,LSDA
+       .ent    f2
+f2:
+       nop
+       .end    f2
+       .cfi_endproc
+
+       .cfi_startproc
+       .cfi_personality 0x0,global_pers
+       .cfi_lsda 0x0,LSDA
+       .ent    f3
+f3:
+       nop
+       .end    f3
+       .cfi_endproc
+
+       .cfi_startproc
+       .cfi_personality 0x0,extern_pers
+       .cfi_lsda 0x0,LSDA
+       .ent    f4
+f4:
+       nop
+       .end    f4
+       .cfi_endproc
+
+       .cfi_startproc
+       .cfi_personality 0x80,local_indirect_ptr
+       .cfi_lsda 0x0,LSDA
+       .ent    f5
+f5:
+       nop
+       .end    f5
+       .cfi_endproc
+
+       .cfi_startproc
+       .cfi_personality 0x80,hidden_indirect_ptr
+       .cfi_lsda 0x0,LSDA
+       .ent    f6
+f6:
+       nop
+       .end    f6
+       .cfi_endproc
+
+       .cfi_startproc
+       .cfi_personality 0x80,global_indirect_ptr
+       .cfi_lsda 0x0,LSDA
+       .ent    f7
+f7:
+       nop
+       .end    f7
+       .cfi_endproc
+
+       .cfi_startproc
+       .cfi_personality 0x80,extern_indirect_ptr
+       .cfi_lsda 0x0,LSDA
+       .ent    f8
+f8:
+       nop
+       .end    f8
+       .cfi_endproc
+
+
+       .ent    local_pers
+local_pers:
+       nop
+       .end    local_pers
+
+       .globl  hidden_pers
+       .hidden hidden_pers
+       .ent    hidden_pers
+hidden_pers:
+       nop
+       .end    hidden_pers
+
+       .globl  global_pers
+       .ent    global_pers
+global_pers:
+       nop
+       .end    global_pers
+
+       .section .data,"aw",@progbits
+
+local_indirect_ptr:
+       .4byte  pers1
+
+       .globl hidden_indirect_ptr
+       .hidden hidden_indirect_ptr
+hidden_indirect_ptr:
+       .4byte  pers2
+
+       .globl global_indirect_ptr
+global_indirect_ptr:
+       .4byte  pers3
+
+LSDA:
+       .4byte  0
index bd06d2025a328b7be80ebdec10efbee12a43b68b..7622ac3ebcc8ad3198c1dc51f1b749ef6e5d0aba 100644 (file)
@@ -304,6 +304,17 @@ if {$embedded_elf} {
     run_dump_test "eh-frame3"
     run_dump_test "eh-frame4"
 }
+if {$linux_gnu} {
+    set eh_frame5_test {
+       {"MIPS eh-frame 5"
+        "-melf32btsmip -shared -Teh-frame5.ld"
+        "-32 -EB"
+        {eh-frame5.s}
+        {{readelf {--relocs -wf} eh-frame5.d}}
+        "eh-frame5.so"}
+    }
+    run_ld_link_tests $eh_frame5_test
+}
 
 run_dump_test "jaloverflow"
 run_dump_test "jaloverflow-2"