* write.c (fixup_segment): Do not assume we know the section a
authorNick Clifton <nickc@redhat.com>
Thu, 29 Apr 2010 14:44:15 +0000 (14:44 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 29 Apr 2010 14:44:15 +0000 (14:44 +0000)
        defined weak symbol is in.
        * config/tc-arm.c (relax_adr, relax_branch, md_apply_fix): Treat
        weak symbols as not known to be in the same section, even if they
        are defined.

        * gas/arm/weakdef-1.s: New.
        * gas/arm/weakdef-1.d: New.
        * gas/arm/weakdef-2.s: New.
        * gas/arm/weakdef-2.d: New.
        * gas/arm/weakdef-2.l: New.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/weakdef-1.d [new file with mode: 0644]
gas/testsuite/gas/arm/weakdef-1.s [new file with mode: 0644]
gas/testsuite/gas/arm/weakdef-2.d [new file with mode: 0644]
gas/testsuite/gas/arm/weakdef-2.l [new file with mode: 0644]
gas/testsuite/gas/arm/weakdef-2.s [new file with mode: 0644]
gas/write.c

index 961b7169470c567474369464ee44ad944e9b09d3..c2b3faab86558de9ef6e8406279ade089a7805f2 100644 (file)
@@ -1,3 +1,11 @@
+2010-04-29  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * write.c (fixup_segment): Do not assume we know the section a
+       defined weak symbol is in.
+       * config/tc-arm.c (relax_adr, relax_branch, md_apply_fix): Treat
+       weak symbols as not known to be in the same section, even if they
+       are defined.
+
 2010-04-27  Joseph Myers  <joseph@codesourcery.com>
 
        * config/tc-tic6x.h (tic6x_label_list): New.
index b7ea21b69c1d6766f6038a593f4600ccbfc640d6..a50ac1d6c6cba86ddfac36a70803c6ff30e2361b 100644 (file)
@@ -18530,7 +18530,8 @@ relax_adr (fragS *fragp, asection *sec, long stretch)
   /* Assume worst case for symbols not known to be in the same section.  */
   if (fragp->fr_symbol == NULL
       || !S_IS_DEFINED (fragp->fr_symbol)
-      || sec != S_GET_SEGMENT (fragp->fr_symbol))
+      || sec != S_GET_SEGMENT (fragp->fr_symbol)
+      || S_IS_WEAK (fragp->fr_symbol))
     return 4;
 
   val = relaxed_symbol_addr (fragp, stretch);
@@ -18573,7 +18574,8 @@ relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
 
   /* Assume worst case for symbols not known to be in the same section.  */
   if (!S_IS_DEFINED (fragp->fr_symbol)
-      || sec != S_GET_SEGMENT (fragp->fr_symbol))
+      || sec != S_GET_SEGMENT (fragp->fr_symbol)
+      || S_IS_WEAK (fragp->fr_symbol))
     return 4;
 
 #ifdef OBJ_ELF
@@ -19784,22 +19786,23 @@ md_apply_fix (fixS *  fixP,
         not have a reloc for it, so tc_gen_reloc will reject it.  */
       fixP->fx_done = 1;
 
-      if (fixP->fx_addsy
-         && ! S_IS_DEFINED (fixP->fx_addsy))
+      if (fixP->fx_addsy)
        {
-         as_bad_where (fixP->fx_file, fixP->fx_line,
-                       _("undefined symbol %s used as an immediate value"),
-                       S_GET_NAME (fixP->fx_addsy));
-         break;
-       }
+         const char *msg = 0;
 
-      if (fixP->fx_addsy
-         && S_GET_SEGMENT (fixP->fx_addsy) != seg)
-       {
-         as_bad_where (fixP->fx_file, fixP->fx_line,
-                       _("symbol %s is in a different section"),
-                       S_GET_NAME (fixP->fx_addsy));
-         break;
+         if (! S_IS_DEFINED (fixP->fx_addsy))
+           msg = _("undefined symbol %s used as an immediate value");
+         else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
+           msg = _("symbol %s is in a different section");
+         else if (S_IS_WEAK (fixP->fx_addsy))
+           msg = _("symbol %s is weak and may be overridden later");
+
+         if (msg)
+           {
+             as_bad_where (fixP->fx_file, fixP->fx_line,
+                           msg, S_GET_NAME (fixP->fx_addsy));
+             break;
+           }
        }
 
       newimm = encode_arm_immediate (value);
@@ -19825,24 +19828,25 @@ md_apply_fix (fixS *  fixP,
        unsigned int highpart = 0;
        unsigned int newinsn  = 0xe1a00000; /* nop.  */
 
-       if (fixP->fx_addsy
-           && ! S_IS_DEFINED (fixP->fx_addsy))
+       if (fixP->fx_addsy)
          {
-           as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("undefined symbol %s used as an immediate value"),
-                         S_GET_NAME (fixP->fx_addsy));
-           break;
-         }
+           const char *msg = 0;
 
-       if (fixP->fx_addsy
-           && S_GET_SEGMENT (fixP->fx_addsy) != seg)
-         {
-           as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("symbol %s is in a different section"),
-                         S_GET_NAME (fixP->fx_addsy));
-           break;
-         }
+           if (! S_IS_DEFINED (fixP->fx_addsy))
+             msg = _("undefined symbol %s used as an immediate value");
+           else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
+             msg = _("symbol %s is in a different section");
+           else if (S_IS_WEAK (fixP->fx_addsy))
+             msg = _("symbol %s is weak and may be overridden later");
 
+           if (msg)
+             {
+               as_bad_where (fixP->fx_file, fixP->fx_line,
+                             msg, S_GET_NAME (fixP->fx_addsy));
+               break;
+             }
+         }
+       
        newimm = encode_arm_immediate (value);
        temp = md_chars_to_number (buf, INSN_SIZE);
 
index f381115a4e87bbf78e743e31877856f8be5e86c7..c9eae547f77afc95a1e9b0a7811868f0dc56d70b 100644 (file)
@@ -1,3 +1,11 @@
+2010-04-29  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * gas/arm/weakdef-1.s: New.
+       * gas/arm/weakdef-1.d: New.
+       * gas/arm/weakdef-2.s: New.
+       * gas/arm/weakdef-2.d: New.
+       * gas/arm/weakdef-2.l: New.
+
 2010-04-27  Joseph Myers  <joseph@codesourcery.com>
 
        * gas/tic6x/align-1-be.d, gas/tic6x/align-1.d,
diff --git a/gas/testsuite/gas/arm/weakdef-1.d b/gas/testsuite/gas/arm/weakdef-1.d
new file mode 100644 (file)
index 0000000..8351fc2
--- /dev/null
@@ -0,0 +1,20 @@
+# name: Thumb branch to weak
+# as:
+# objdump: -dr
+# This test is only valid on ELF based ports.
+#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+
+Disassembly of section .text:
+
+0+000 <Weak>:
+   0:  e7fe            b.n     2 <Strong>
+                       0: R_ARM_THM_JUMP11     Strong
+
+0+002 <Strong>:
+   2:  f7ff bffe       b.w     0 <Random>
+                       2: R_ARM_THM_JUMP24     Random
+   6:  f7ff bffe       b.w     0 <Weak>
+                       6: R_ARM_THM_JUMP24     Weak
diff --git a/gas/testsuite/gas/arm/weakdef-1.s b/gas/testsuite/gas/arm/weakdef-1.s
new file mode 100644 (file)
index 0000000..4aa6bc4
--- /dev/null
@@ -0,0 +1,18 @@
+       .syntax unified
+       .text
+       .thumb
+
+       .globl  Weak
+       .weak   Weak
+       .thumb_func
+       .type   Weak, %function
+Weak:
+       b       Strong
+       .size   Weak, .-Weak
+       
+       .globl  Strong
+       .type   Strong, %function
+Strong:
+       b       Random
+       b       Weak
+       .size   Strong, .-Strong
diff --git a/gas/testsuite/gas/arm/weakdef-2.d b/gas/testsuite/gas/arm/weakdef-2.d
new file mode 100644 (file)
index 0000000..e0ff272
--- /dev/null
@@ -0,0 +1,5 @@
+# name: adr of weak
+# as:
+# error-output: weakdef-2.l
+# This test is only valid on ELF based ports.
+#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
diff --git a/gas/testsuite/gas/arm/weakdef-2.l b/gas/testsuite/gas/arm/weakdef-2.l
new file mode 100644 (file)
index 0000000..7aec5e1
--- /dev/null
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:9: Error: symbol Weak is weak and may be overridden later
+[^:]*:10: Error: symbol Weak is weak and may be overridden later
diff --git a/gas/testsuite/gas/arm/weakdef-2.s b/gas/testsuite/gas/arm/weakdef-2.s
new file mode 100644 (file)
index 0000000..08da196
--- /dev/null
@@ -0,0 +1,10 @@
+       .syntax unified
+       .text
+       .globl  Strong
+Strong:        
+       adrl    r0,Strong
+       adr     r0,Strong
+       .globl  Weak
+       .weak   Weak
+Weak:  adrl    r0,Weak
+       adr     r0,Weak
index a148b248d20bd31de5ea6ab0dc3fdd76dda7f446..b50b0d491e660cd45ae40b71c51a2bf86f527c7b 100644 (file)
@@ -992,7 +992,9 @@ fixup_segment (fixS *fixP, segT this_segment)
 
       if (fixP->fx_addsy)
        {
-         if (add_symbol_segment == this_segment
+         if (S_IS_WEAK (fixP->fx_addsy))
+           ; // even if it is defined, it might be overridden later
+         else if (add_symbol_segment == this_segment
              && !TC_FORCE_RELOCATION_LOCAL (fixP))
            {
              /* This fixup was made when the symbol's segment was