* config/tc-mn10300.c (mn10300_force_relocation): Force a reloc to be generated for...
authorNick Clifton <nickc@redhat.com>
Tue, 13 Nov 2007 10:40:29 +0000 (10:40 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 13 Nov 2007 10:40:29 +0000 (10:40 +0000)
* config/tc-mn10300.h (TC_FORCE_RELOCATION): Call mn10300_force_relocation.
* elf-m10300.c (mn10300_elf_final_link_relocate): Prevent the accidental termination of DWARF location list entries.
  (mn10300_elf_relax_delete_bytes): Stop deletion if an align reloc is encountered that is larger than or not a mutliple of the number of bytes being deleted.
  When adjusting symbols, any symbols inside the region being deleted must be moved to the end of the region.
  Move align relocs forward if there is room for them after the deletion of the region.

bfd/ChangeLog
bfd/elf-m10300.c
gas/ChangeLog
gas/config/tc-mn10300.c
gas/config/tc-mn10300.h
ld/testsuite/ChangeLog
ld/testsuite/ld-mn10300/i127740.d [new file with mode: 0644]
ld/testsuite/ld-mn10300/i127740.s [new file with mode: 0644]
ld/testsuite/ld-mn10300/i135409-3.d [new file with mode: 0644]
ld/testsuite/ld-mn10300/i135409-3.s [new file with mode: 0644]
ld/testsuite/ld-mn10300/mn10300.exp

index be08948dfb3f86fddcbf93a17470bb8fe3557964..6a7fe8dcb9cab84415c1d949096d17300de13908 100644 (file)
@@ -1,3 +1,15 @@
+2007-11-13  Nick Clifton  <nickc@redhat.com>
+
+       * elf-m10300.c (mn10300_elf_final_link_relocate): Prevent the
+       accidental termination of DWARF location list entries.
+       (mn10300_elf_relax_delete_bytes): Stop deletion if an align reloc
+       is encountered that is larger than or not a mutliple of the number
+       of bytes being deleted.
+       When adjusting symbols, any symbols inside the region being
+       deleted must be moved to the end of the region.
+       Move align relocs forward if there is room for them after the
+       deletion of the region.
+
 2007-11-13  Alan Modra  <amodra@bigpond.net.au>
 
        PR 5233
index 7c51498aa1e8ce229cef3ddf9acae40885d71995..9a75b7c76761126d0ac8b44f13a09244df29e4f9 100644 (file)
@@ -1039,6 +1039,17 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
        case R_MN10300_16:
        case R_MN10300_8:
          value -= sym_diff_value;
+         /* If we are computing a 32-bit value for the location lists
+            and the result is 0 then we add one to the value.  A zero
+            value can result because of linker relaxation deleteing
+            prologue instructions and using a value of 1 (for the begin
+            and end offsets in the location list entry) results in a
+            nul entry which does not prevent the following entries from
+            being parsed.  */
+         if (r_type == R_MN10300_32
+             && value == 0
+             && strcmp (input_section->name, ".debug_loc") == 0)
+           value = 1;
          sym_diff_section = NULL;
          is_sym_diff_reloc = TRUE;
          break;
@@ -1856,17 +1867,23 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
        --irelend;
       
       /* The deletion must stop at the next ALIGN reloc for an aligment
-        power larger than the number of bytes we are deleting.  */
+        power larger than, or not a multiple of, the number of bytes we
+        are deleting.  */
       for (; irel < irelend; irel++)
-       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
-           && irel->r_offset > addr
-           && irel->r_offset < toaddr
-           && count < (1 << irel->r_addend))
-         {
-           irelalign = irel;
-           toaddr = irel->r_offset;
-           break;
-         }
+       {
+         int alignment = 1 << irel->r_addend;
+
+         if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
+             && irel->r_offset > addr
+             && irel->r_offset < toaddr
+             && (count < alignment
+                 || alignment % count != 0))
+           {
+             irelalign = irel;
+             toaddr = irel->r_offset;
+             break;
+           }
+       }
     }
 
   /* Actually delete the bytes.  */
@@ -1898,11 +1915,17 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
     {
       /* Get the new reloc address.  */
       if ((irel->r_offset > addr
-          && irel->r_offset < toaddr))
+          && irel->r_offset < toaddr)
+         || (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
+             && irel->r_offset == toaddr))
        irel->r_offset -= count;
     }
 
-  /* Adjust the local symbols defined in this section.  */
+  /* Adjust the local symbols in the section, reducing their value
+     by the number of bytes deleted.  Note - symbols within the deleted
+     region are moved to the address of the start of the region, which
+     actually means that they will address the byte beyond the end of
+     the region once the deletion has been completed.  */
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
@@ -1910,7 +1933,12 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
       if (isym->st_shndx == sec_shndx
          && isym->st_value > addr
          && isym->st_value < toaddr)
-       isym->st_value -= count;
+       {
+         if (isym->st_value < addr + count)
+           isym->st_value = addr;
+         else
+           isym->st_value -= count;
+       }
       /* Adjust the function symbol's size as well.  */
       else if (isym->st_shndx == sec_shndx
               && ELF_ST_TYPE (isym->st_info) == STT_FUNC
@@ -1933,7 +1961,12 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
          && sym_hash->root.u.def.section == sec
          && sym_hash->root.u.def.value > addr
          && sym_hash->root.u.def.value < toaddr)
-       sym_hash->root.u.def.value -= count;
+       {
+         if (sym_hash->root.u.def.value < addr + count)
+           sym_hash->root.u.def.value = addr;
+         else
+           sym_hash->root.u.def.value -= count;
+       }
       /* Adjust the function symbol's size as well.  */
       else if (sym_hash->root.type == bfd_link_hash_defined
               && sym_hash->root.u.def.section == sec
@@ -1943,6 +1976,26 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
        sym_hash->size -= count;
     }
 
+  /* See if we can move the ALIGN reloc forward.
+     We have adjusted r_offset for it already.  */
+  if (irelalign != NULL)
+    {
+      bfd_vma alignto, alignaddr;
+
+      if ((int) irelalign->r_addend > 0)
+       {
+         /* This is the old address.  */
+         alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_addend);
+         /* This is where the align points to now.  */
+         alignaddr = BFD_ALIGN (irelalign->r_offset,
+                                1 << irelalign->r_addend);
+         if (alignaddr < alignto)
+           /* Tail recursion.  */
+           return mn10300_elf_relax_delete_bytes (abfd, sec, alignaddr,
+                                                  (int) (alignto - alignaddr));
+       }
+    }
+
   return TRUE;
 }
 
index 3b640e7703d581c39e56c7d28b6cbd26b91bc07c..06fd9d111daf9fc4ffe50d81465b7b9a53f9bc51 100644 (file)
@@ -1,3 +1,10 @@
+2007-11-13  Nick Clifton  <nickc@redhat.com>
+
+       * config/tc-mn10300.c (mn10300_force_relocation): Force a reloc to
+       be generated for alignment fixups.
+       * config/tc-mn10300.h (TC_FORCE_RELOCATION): Call
+       mn10300_force_relocation.
+
 2007-11-12  Nick Clifton  <nickc@redhat.com>
 
        PR gas/5269
index e16a7649073edcf97ba9427f40a019a5eee5bf7f..5d21cb5be5ba2768c832e0dcaf5a07d455e2fea8 100644 (file)
@@ -2571,11 +2571,9 @@ mn10300_allow_local_subtract (expressionS * left, expressionS * right, segT sect
 void
 mn10300_handle_align (fragS *frag)
 {
-  if (! linkrelax)
-    return;
-
-  if ((frag->fr_type == rs_align
-       || frag->fr_type == rs_align_code)
+  if (linkrelax
+      && (frag->fr_type == rs_align
+         || frag->fr_type == rs_align_code)
       && frag->fr_address + frag->fr_fix > 0
       && frag->fr_offset > 1
       && now_seg != bss_section
@@ -2590,3 +2588,14 @@ mn10300_handle_align (fragS *frag)
     fix_new (frag, frag->fr_fix, 0, & abs_symbol, frag->fr_offset, FALSE,
             BFD_RELOC_MN10300_ALIGN);
 }
+
+bfd_boolean
+mn10300_force_relocation (struct fix * fixp)
+{
+  if (linkrelax
+      && (fixp->fx_pcrel
+         || fixp->fx_r_type == BFD_RELOC_MN10300_ALIGN))
+    return TRUE;
+
+  return generic_force_reloc (fixp);
+}
index ca51eda7a34f375749e8755bdfddd502fafdde4f..63ca74ae1d4853d73c2cae48640d8d520ea8ba6f 100644 (file)
@@ -26,8 +26,8 @@
 #define DIFF_EXPR_OK
 #define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
 
-#define TC_FORCE_RELOCATION(FIX)                       \
-  (generic_force_reloc (FIX))
+#define TC_FORCE_RELOCATION(FIX) mn10300_force_relocation (FIX)
+extern bfd_boolean mn10300_force_relocation (struct fix *);
 
 #define TC_FORCE_RELOCATION_LOCAL(FIX)                 \
   (!(FIX)->fx_pcrel                                    \
    || (FIX)->fx_r_type == BFD_RELOC_32_GOT_PCREL       \
    || TC_FORCE_RELOCATION (FIX))
 
-#define md_parse_name(name, exprP, mode, nextcharP) \
-    mn10300_parse_name ((name), (exprP), (mode), (nextcharP))
-int mn10300_parse_name PARAMS ((char const *, expressionS *,
-                               enum expr_mode, char *));
+#define md_parse_name(NAME, EXPRP, MODE, NEXTCHARP) \
+    mn10300_parse_name ((NAME), (EXPRP), (MODE), (NEXTCHARP))
+int mn10300_parse_name (char const *, expressionS *, enum expr_mode, char *);
 
 #define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
      mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP))
-void mn10300_cons_fix_new PARAMS ((fragS *, int, int, expressionS *));
+void mn10300_cons_fix_new (fragS *, int, int, expressionS *);
 
 /* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
    symbols.  The relocation type is stored in X_md.  */
index 08052995ef5818ffad5f8e0ced481981f4afa536..83fce111928601b5ea64d87cca54188dc9f71ee3 100644 (file)
@@ -1,3 +1,11 @@
+2007-11-13  Nick Clifton  <nickc@redhat.com>
+
+       * ld-mn10300/i127740.s: New test: Checks relaxation and alignment.
+       * ld-mn10300/i127740.d: New file: Expected disassembly.
+       * ld-mn10300/i135409-3.s: New test: Check symbols inside a relaxed region.
+       * ld-mn10300/i135409-3.d: New file: Expected disassembly.
+       * ld-mn10300/mn10300.exp: Run new tests.
+
 2007-11-08  Nathan Sidwell  <nathan@codesourcery.com>
 
        * ld-vxworks/tls-2.d: New.
diff --git a/ld/testsuite/ld-mn10300/i127740.d b/ld/testsuite/ld-mn10300/i127740.d
new file mode 100644 (file)
index 0000000..456a75b
--- /dev/null
@@ -0,0 +1,17 @@
+
+tmpdir/i127740.x:     file format elf32-.*
+
+Disassembly of section .text:
+
+0+0100 <_main>:
+ 100:  2d 00 03[       ]+mov   768,d1
+ 103:  cb[     ]+nop   
+ 104:  cb[     ]+nop   
+ 105:  cb[     ]+nop   
+       ...
+
+0+0200 <_dummy>:
+ 200:  00[     ]+clr   d0
+ 201:  02 00 00[       ]+movbu d0,\(0 <_main-0x100>\)
+ 204:  df 00 00[       ]+ret   \[\],0
+       ...
diff --git a/ld/testsuite/ld-mn10300/i127740.s b/ld/testsuite/ld-mn10300/i127740.s
new file mode 100644 (file)
index 0000000..358266b
--- /dev/null
@@ -0,0 +1,12 @@
+      .section .text
+       .global _main
+       .global _dummy
+_main:
+       mov     _g_label,d1     # instruction is changed by relaxations
+
+       .balign 0x100
+_dummy:
+       .long     _dummy
+       ret [],0
+       .size   _main, .-_main
+       .comm   _g_label,4,4
diff --git a/ld/testsuite/ld-mn10300/i135409-3.d b/ld/testsuite/ld-mn10300/i135409-3.d
new file mode 100644 (file)
index 0000000..1ea91ba
--- /dev/null
@@ -0,0 +1,16 @@
+
+tmpdir/i135409-3.x:     file format elf32-.*
+
+Disassembly of section .text:
+
+0+0 <_func>:
+   0:  25 1f 00[       ]+mov   31,a1
+   3:  cb[     ]+nop   
+
+0+04 <A>:
+   4:  25 1f 00[       ]+mov   31,a1
+   7:  cb[     ]+nop   
+
+0+08 <BOTTOM>:
+   8:  e1[     ]+add   d0,d1
+#pass
diff --git a/ld/testsuite/ld-mn10300/i135409-3.s b/ld/testsuite/ld-mn10300/i135409-3.s
new file mode 100644 (file)
index 0000000..e83ad96
--- /dev/null
@@ -0,0 +1,16 @@
+      .text
+      .global _start
+_start:
+      .type   _func, @function
+_func:
+      mov     L001,A1
+      nop
+A:
+      mov     L001,A1
+BOTTOM:
+      .balign 0x8
+      add     D0,D1
+      .size   _func, .-func
+
+      .data
+L001:
index 18bbad3d8ffe832c9048e03fa1c26bb09013b5ce..232a5fb013cdbdc6f272e98639e8b386eff4ce8d 100644 (file)
@@ -47,6 +47,14 @@ set mn10300_tests {
        { {objdump -D i112045-3.d} }
        "i112045-3.x"
     }
+    {
+       "relaxation and alignment directives"
+       "-relax -Ttext 100"
+       ""
+       { "i127740.s" }
+       { {objdump -d i127740.d} }
+       "i127740.x"
+    }
     {
        "adjustment of symbols due to relaxation"
        "-Tdata 1f -Ttext 0 -relax"
@@ -63,6 +71,14 @@ set mn10300_tests {
        { {readelf --syms i135409-2.d} }
        "i135409-2.x"
     }
+    {
+       "adjustment of symbols due to relaxation (with a symbol in the deleted region)"
+       "-Tdata 1f -Ttext 0 -relax"
+       ""
+       { "i135409-3.s" }
+       { {objdump -d i135409-3.d} }
+       "i135409-3.x"
+    }
 }
 
 run_ld_link_tests $mn10300_tests