gas/
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 2 Dec 2010 13:25:13 +0000 (13:25 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Thu, 2 Dec 2010 13:25:13 +0000 (13:25 +0000)
* symbols.c (S_FORCE_RELOC): Return true for indirect functions
even if !strict.
* expr.c (operand): Don't convert absolute symbols to constants
if S_FORCE_RELOC is true.
(expr): Only reduce subtractions between different symbols if
S_FORCE_RELOC is false for both of them.
* write.c (fixup_segment): Don't remove symbols if S_FORCE_RELOC
is true for them, regardless of their segment.

gas/testsuite/
* gas/i386/ifunc-2.s, gas/i386/ifunc-2.l: New test.
* gas/i386/ifunc-3.s, gas/i386/ifunc-3.d: Likeise.
* gas/i386/i386.exp: Run them.

gas/ChangeLog
gas/expr.c
gas/symbols.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/ifunc-2.l [new file with mode: 0644]
gas/testsuite/gas/i386/ifunc-2.s [new file with mode: 0644]
gas/testsuite/gas/i386/ifunc-3.d [new file with mode: 0644]
gas/testsuite/gas/i386/ifunc-3.s [new file with mode: 0644]
gas/write.c

index e8e58fdac682e8b4e7b1beb72fe5548ba1257b85..b0a1966dfa2fdf395df7890241c004c72e5d3a53 100644 (file)
@@ -1,3 +1,14 @@
+2010-12-02  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * symbols.c (S_FORCE_RELOC): Return true for indirect functions
+       even if !strict.
+       * expr.c (operand): Don't convert absolute symbols to constants
+       if S_FORCE_RELOC is true.
+       (expr): Only reduce subtractions between different symbols if
+       S_FORCE_RELOC is false for both of them.
+       * write.c (fixup_segment): Don't remove symbols if S_FORCE_RELOC
+       is true for them, regardless of their segment.
+
 2010-12-01  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * symbols.h (dot_symbol): New declaration.
index 215b2bad7c43d99cf5c91caf877cadabc4f35a10..f818ad389afae5d419b1fbb9a1e5af3934629383 100644 (file)
@@ -1325,7 +1325,9 @@ operand (expressionS *expressionP, enum expr_mode mode)
          /* If we have an absolute symbol or a reg, then we know its
             value now.  */
          segment = S_GET_SEGMENT (symbolP);
-         if (mode != expr_defer && segment == absolute_section)
+         if (mode != expr_defer
+             && segment == absolute_section
+             && !S_FORCE_RELOC (symbolP, 0))
            {
              expressionP->X_op = O_constant;
              expressionP->X_add_number = S_GET_VALUE (symbolP);
@@ -1840,7 +1842,9 @@ expr (int rankarg,                /* Larger # is higher rank.  */
 #ifdef md_allow_local_subtract
               && md_allow_local_subtract (resultP, & right, rightseg)
 #endif
-              && (SEG_NORMAL (rightseg)
+              && ((SEG_NORMAL (rightseg)
+                   && !S_FORCE_RELOC (resultP->X_add_symbol, 0)
+                   && !S_FORCE_RELOC (right.X_add_symbol, 0))
                   || right.X_add_symbol == resultP->X_add_symbol)
               && frag_offset_fixed_p (symbol_get_frag (resultP->X_add_symbol),
                                       symbol_get_frag (right.X_add_symbol),
@@ -1954,7 +1958,10 @@ expr (int rankarg,               /* Larger # is higher rank.  */
          else if (op_left == O_subtract)
            {
              resultP->X_add_number -= right.X_add_number;
-             if (retval == rightseg && SEG_NORMAL (retval))
+             if (retval == rightseg
+                 && SEG_NORMAL (retval)
+                 && !S_FORCE_RELOC (resultP->X_add_symbol, 0)
+                 && !S_FORCE_RELOC (right.X_add_symbol, 0))
                {
                  retval = absolute_section;
                  rightseg = absolute_section;
index 5fae5471b144116822a078e3e016df182f7a28d4..4e4ad775b3b7bb3c8a93aeb10d524345e0a09818 100644 (file)
@@ -2065,9 +2065,9 @@ S_FORCE_RELOC (symbolS *s, int strict)
 
   return ((strict
           && ((s->bsym->flags & BSF_WEAK) != 0
-              || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0
               || (EXTERN_FORCE_RELOC
                   && (s->bsym->flags & BSF_GLOBAL) != 0)))
+         || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0
          || s->bsym->section == undefined_section
          || bfd_is_com_section (s->bsym->section));
 }
index 90b3bfce6e3566dae233e1a35a95681d1217ce57..10fbad88411a4fcc79a408756db1058414b8d54b 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-02  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * gas/i386/ifunc-2.s, gas/i386/ifunc-2.l: New test.
+       * gas/i386/ifunc-3.s, gas/i386/ifunc-3.d: Likeise.
+       * gas/i386/i386.exp: Run them.
+
 2010-11-20  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * lib/gas-defs.exp (regexp_diff): Delete.
index c295be63e562181e9142cc65643e503e78380df4..3a966d7006ee5ed1831a1587c1020d47653362bd 100644 (file)
@@ -215,6 +215,8 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
        run_list_test "inval-equ-1" "-al"
        run_list_test "inval-equ-2" "-al"
        run_dump_test "ifunc"
+       run_list_test "ifunc-2"
+       run_dump_test "ifunc-3"
        run_list_test "l1om-inval" "-march=l1om --32"
        run_dump_test "localpic"
        run_dump_test "debug1"
diff --git a/gas/testsuite/gas/i386/ifunc-2.l b/gas/testsuite/gas/i386/ifunc-2.l
new file mode 100644 (file)
index 0000000..0ed314b
--- /dev/null
@@ -0,0 +1,61 @@
+.*/ifunc-2\.s: Assembler messages:
+.*/ifunc-2\.s:4: Error: can't resolve `bar1' {\.text\.1 section} - `foo1' {\.text\.1 section}
+.*/ifunc-2\.s:5: Error: can't resolve `bar2' {\.text\.2 section} - `foo2' {\.text\.2 section}
+.*/ifunc-2\.s:6: Error: can't resolve `bar1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:7: Error: can't resolve `bar2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:8: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:9: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:10: Error: can't resolve `bar1' {\.text\.1 section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:11: Error: can't resolve `abs1' {\*ABS\* section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:12: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:19: Error: can't resolve `bar1' {\.text\.1 section} - `foo1' {\.text\.1 section}
+.*/ifunc-2\.s:20: Error: can't resolve `bar2' {\.text\.2 section} - `foo2' {\.text\.2 section}
+.*/ifunc-2\.s:21: Error: can't resolve `bar1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:22: Error: can't resolve `bar2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:23: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:24: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:25: Error: can't resolve `bar1' {\.text\.1 section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:26: Error: can't resolve `abs1' {\*ABS\* section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:27: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:34: Error: can't resolve `bar1' {\.text\.1 section} - `foo1' {\.text\.1 section}
+.*/ifunc-2\.s:35: Error: can't resolve `bar2' {\.text\.2 section} - `foo2' {\.text\.2 section}
+.*/ifunc-2\.s:36: Error: can't resolve `bar1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:37: Error: can't resolve `bar2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:38: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:39: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:40: Error: can't resolve `bar1' {\.text\.1 section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:41: Error: can't resolve `abs1' {\*ABS\* section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:42: Error: can't resolve `\.text\.1' {\.text\.1 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:44: Error: can't resolve `abs1' {\*ABS\* section} - `abs2' {\*ABS\* section}
+.*/ifunc-2\.s:45: Error: can't resolve `abs2' {\*ABS\* section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:50: Error: can't resolve `abs1' {\*ABS\* section} - `abs2' {\*ABS\* section}
+.*/ifunc-2\.s:51: Error: can't resolve `abs2' {\*ABS\* section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:56: Error: can't resolve `abs1' {\*ABS\* section} - `abs2' {\*ABS\* section}
+.*/ifunc-2\.s:57: Error: can't resolve `abs2' {\*ABS\* section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:62: Error: can't resolve `bar1' {\.text\.1 section} - `foo1' {\.text\.1 section}
+.*/ifunc-2\.s:63: Error: can't resolve `bar2' {\.text\.2 section} - `foo2' {\.text\.2 section}
+.*/ifunc-2\.s:64: Error: can't resolve `bar1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:65: Error: can't resolve `bar2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:66: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:67: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:68: Error: can't resolve `bar2' {\.text\.2 section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:69: Error: can't resolve `abs1' {\*ABS\* section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:70: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:77: Error: can't resolve `bar1' {\.text\.1 section} - `foo1' {\.text\.1 section}
+.*/ifunc-2\.s:78: Error: can't resolve `bar2' {\.text\.2 section} - `foo2' {\.text\.2 section}
+.*/ifunc-2\.s:79: Error: can't resolve `bar1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:80: Error: can't resolve `bar2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:81: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:82: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:83: Error: can't resolve `bar2' {\.text\.2 section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:84: Error: can't resolve `abs1' {\*ABS\* section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:85: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:92: Error: can't resolve `bar1' {\.text\.1 section} - `foo1' {\.text\.1 section}
+.*/ifunc-2\.s:93: Error: can't resolve `bar2' {\.text\.2 section} - `foo2' {\.text\.2 section}
+.*/ifunc-2\.s:94: Error: can't resolve `bar1' {\.text\.1 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:95: Error: can't resolve `bar2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:96: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar1' {\.text\.1 section}
+.*/ifunc-2\.s:97: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:98: Error: can't resolve `bar2' {\.text\.2 section} - `abs1' {\*ABS\* section}
+.*/ifunc-2\.s:99: Error: can't resolve `abs1' {\*ABS\* section} - `bar2' {\.text\.2 section}
+.*/ifunc-2\.s:100: Error: can't resolve `\.text\.2' {\.text\.2 section} - `bar2' {\.text\.2 section}
diff --git a/gas/testsuite/gas/i386/ifunc-2.s b/gas/testsuite/gas/i386/ifunc-2.s
new file mode 100644 (file)
index 0000000..ca536d3
--- /dev/null
@@ -0,0 +1,100 @@
+       .section .text.1,"ax",@progbits
+
+start1:
+       .long   bar1-foo1
+       .long   bar2-foo2
+       .long   bar1-bar2
+       .long   bar2-bar1
+       .long   start1-bar1
+       .long   start1-bar2
+       .long   bar1-abs1
+       .long   abs1-bar1
+       .long   .-bar1
+
+       .type   foo1,%gnu_indirect_function
+foo1:
+       ret
+       .size   foo1,.-foo1
+
+       .long   bar1-foo1
+       .long   bar2-foo2
+       .long   bar1-bar2
+       .long   bar2-bar1
+       .long   start1-bar1
+       .long   start1-bar2
+       .long   bar1-abs1
+       .long   abs1-bar1
+       .long   .-bar1
+
+       .type   bar1,%gnu_indirect_function
+bar1:
+       ret
+       .size   bar1,.-bar1
+
+       .long   bar1-foo1
+       .long   bar2-foo2
+       .long   bar1-bar2
+       .long   bar2-bar1
+       .long   start1-bar1
+       .long   start1-bar2
+       .long   bar1-abs1
+       .long   abs1-bar1
+       .long   .-bar1
+
+       .long   abs1-abs2
+       .long   abs2-abs1
+
+       .equ    abs1,0x11223300
+       .type   abs1,%gnu_indirect_function
+
+       .long   abs1-abs2
+       .long   abs2-abs1
+
+       .equ    abs2,0x11223380
+       .type   abs2,%gnu_indirect_function
+
+       .long   abs1-abs2
+       .long   abs2-abs1
+
+       .section .text.2,"ax",@progbits
+
+start2:
+       .long   bar1-foo1
+       .long   bar2-foo2
+       .long   bar1-bar2
+       .long   bar2-bar1
+       .long   start2-bar1
+       .long   start2-bar2
+       .long   bar2-abs1
+       .long   abs1-bar2
+       .long   .-bar2
+
+       .type   foo2,%gnu_indirect_function
+foo2:
+       ret
+       .size   foo2,.-foo2
+
+       .long   bar1-foo1
+       .long   bar2-foo2
+       .long   bar1-bar2
+       .long   bar2-bar1
+       .long   start2-bar1
+       .long   start2-bar2
+       .long   bar2-abs1
+       .long   abs1-bar2
+       .long   .-bar2
+
+       .type   bar2,%gnu_indirect_function
+bar2:
+       ret
+       .size   bar2,.-bar2
+
+       .long   bar1-foo1
+       .long   bar2-foo2
+       .long   bar1-bar2
+       .long   bar2-bar1
+       .long   start2-bar1
+       .long   start2-bar2
+       .long   bar2-abs1
+       .long   abs1-bar2
+       .long   .-bar2
diff --git a/gas/testsuite/gas/i386/ifunc-3.d b/gas/testsuite/gas/i386/ifunc-3.d
new file mode 100644 (file)
index 0000000..124de37
--- /dev/null
@@ -0,0 +1,57 @@
+#readelf: --relocs --syms -x .text.1 -x .text.2
+#name: i386 ifunc 3
+
+Relocation section '\.rel\.text\.1' at offset .* contains .* entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+00000000  ........ R_386_PC32        bar1\(\)     bar1
+00000004  ........ R_386_PC32        bar2\(\)     bar2
+00000008  ........ R_386_PC32        bar1\(\)     bar1
+0000000c  ........ R_386_PC32        bar2\(\)     bar2
+00000010  ........ R_386_32          bar1\(\)     bar1
+00000018  ........ R_386_PC32        bar1\(\)     bar1
+0000001c  ........ R_386_PC32        bar2\(\)     bar2
+00000020  ........ R_386_PC32        bar1\(\)     bar1
+00000024  ........ R_386_PC32        bar2\(\)     bar2
+00000028  ........ R_386_32          bar1\(\)     bar1
+0000002c  ........ R_386_PC32        abs1\(\)     abs1
+00000030  ........ R_386_PC32        abs1\(\)     abs1
+00000034  ........ R_386_32          abs1\(\)     abs1
+00000038  ........ R_386_PC32        abs1\(\)     abs1
+0000003c  ........ R_386_PC32        abs1\(\)     abs1
+00000040  ........ R_386_32          abs1\(\)     abs1
+
+Relocation section '\.rel\.text\.2' at offset .* contains .* entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+00000000  ........ R_386_PC32        bar1\(\)     bar1
+00000004  ........ R_386_PC32        bar2\(\)     bar2
+00000008  ........ R_386_PC32        bar1\(\)     bar1
+0000000c  ........ R_386_PC32        bar2\(\)     bar2
+00000010  ........ R_386_32          bar2\(\)     bar2
+00000018  ........ R_386_PC32        bar1\(\)     bar1
+0000001c  ........ R_386_PC32        bar2\(\)     bar2
+00000020  ........ R_386_PC32        bar1\(\)     bar1
+00000024  ........ R_386_PC32        bar2\(\)     bar2
+00000028  ........ R_386_32          bar2\(\)     bar2
+
+Symbol table '.symtab' contains .* entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+#...
+.*: 00000014     1 IFUNC   LOCAL  DEFAULT   .* bar1
+.*: 00000014     1 IFUNC   LOCAL  DEFAULT   .* bar2
+#...
+.*: 11223300     0 IFUNC   LOCAL  DEFAULT  ABS abs1
+#...
+
+Hex dump of section '\.text\.1':
+ NOTE: This section has relocations against it, but these have NOT been applied to this dump\.
+  0x00000000 00000000 00000000 08000000 0c000000 .*
+  0x00000010 4054ffff c38d7600 00000000 00000000 .*
+  0x00000020 20000000 24000000 4054ffff 00000000 .*
+  0x00000030 30000000 4054ffff 00000000 3c000000 .*
+  0x00000040 4054ffff                            .*
+
+Hex dump of section '\.text\.2':
+ NOTE: This section has relocations against it, but these have NOT been applied to this dump\.
+  0x00000000 00000000 00000000 08000000 0c000000 .*
+  0x00000010 4054ffff c38d7600 00000000 00000000 .*
+  0x00000020 20000000 24000000 4054ffff          .*
diff --git a/gas/testsuite/gas/i386/ifunc-3.s b/gas/testsuite/gas/i386/ifunc-3.s
new file mode 100644 (file)
index 0000000..dbcf494
--- /dev/null
@@ -0,0 +1,54 @@
+       .section .text.1,"ax",@progbits
+
+start1:
+       .long   bar1-.
+       .long   bar2-.
+       .long   bar1-start1
+       .long   bar2-start1
+       .long   bar1-base
+
+       .type   bar1,%gnu_indirect_function
+bar1:
+       ret
+       .size   bar1,.-bar1
+       .align  4
+
+       .long   bar1-.
+       .long   bar2-.
+       .long   bar1-start1
+       .long   bar2-start1
+       .long   bar1-base
+
+       .long   abs1-.
+       .long   abs1-start1
+       .long   abs1-base
+
+       .equ    abs1,0x11223300
+       .type   abs1,%gnu_indirect_function
+
+       .long   abs1-.
+       .long   abs1-start1
+       .long   abs1-base
+
+       .section .text.2,"ax",@progbits
+
+start2:
+       .long   bar1-.
+       .long   bar2-.
+       .long   bar1-start2
+       .long   bar2-start2
+       .long   bar2-base
+
+       .type   bar2,%gnu_indirect_function
+bar2:
+       ret
+       .size   bar2,.-bar2
+       .align  4
+
+       .long   bar1-.
+       .long   bar2-.
+       .long   bar1-start2
+       .long   bar2-start2
+       .long   bar2-base
+
+       .equ    base,0xabc0
index 939b80e520ba37190f11ec0ae4db0e946392df23..018800e0750ba05be3c0335086e86372fed20f52 100644 (file)
@@ -932,6 +932,8 @@ fixup_segment (fixS *fixP, segT this_segment)
          sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy);
          if (fixP->fx_addsy != NULL
              && sub_symbol_segment == add_symbol_segment
+             && !S_FORCE_RELOC (fixP->fx_addsy, 0)
+             && !S_FORCE_RELOC (fixP->fx_subsy, 0)
              && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment))
            {
              add_number += S_GET_VALUE (fixP->fx_addsy);
@@ -945,6 +947,7 @@ fixup_segment (fixS *fixP, segT this_segment)
 #endif
            }
          else if (sub_symbol_segment == absolute_section
+                  && !S_FORCE_RELOC (fixP->fx_subsy, 0)
                   && !TC_FORCE_RELOCATION_SUB_ABS (fixP, add_symbol_segment))
            {
              add_number -= S_GET_VALUE (fixP->fx_subsy);
@@ -952,6 +955,7 @@ fixup_segment (fixS *fixP, segT this_segment)
              fixP->fx_subsy = NULL;
            }
          else if (sub_symbol_segment == this_segment
+                  && !S_FORCE_RELOC (fixP->fx_subsy, 0)
                   && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP, add_symbol_segment))
            {
              add_number -= S_GET_VALUE (fixP->fx_subsy);
@@ -994,6 +998,7 @@ fixup_segment (fixS *fixP, segT this_segment)
       if (fixP->fx_addsy)
        {
          if (add_symbol_segment == this_segment
+             && !S_FORCE_RELOC (fixP->fx_addsy, 0)
              && !TC_FORCE_RELOCATION_LOCAL (fixP))
            {
              /* This fixup was made when the symbol's segment was
@@ -1007,6 +1012,7 @@ fixup_segment (fixS *fixP, segT this_segment)
              fixP->fx_pcrel = 0;
            }
          else if (add_symbol_segment == absolute_section
+                  && !S_FORCE_RELOC (fixP->fx_addsy, 0)
                   && !TC_FORCE_RELOCATION_ABS (fixP))
            {
              add_number += S_GET_VALUE (fixP->fx_addsy);