* write.c (write_relocs): For relocs that are pc_relative and
authorKen Raeburn <raeburn@cygnus>
Mon, 25 Oct 1993 17:49:24 +0000 (17:49 +0000)
committerKen Raeburn <raeburn@cygnus>
Mon, 25 Oct 1993 17:49:24 +0000 (17:49 +0000)
pcrel_offset and not partial_inplace, adjust reloc->addend to
compensate for a bfd_perform_relocation bug.

gas/write.c

index 2b8aec97c871de5b41c93b138c01347f06c0af23..30ab74611fe563aec28958af73eb901271ff2171 100644 (file)
@@ -124,6 +124,8 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
   fixP->fx_callj = 0;
 #endif
 
+  as_where (&fixP->fx_file, &fixP->fx_line);
+
   /* Usually, we want relocs sorted numerically, but while
      comparing to older versions of gas that have relocs
      reverse sorted, it is convenient to have this compile
@@ -634,6 +636,13 @@ write_relocs (abfd, sec, xxx)
       /* Pass bogus address so that when bfd_perform_relocation adds
         `address' back in, it'll come up with `data', which is where
         we want it to operate.  */
+      if (reloc->howto->partial_inplace == false
+         && reloc->howto->pcrel_offset == true
+         && reloc->howto->pc_relative == true)
+       {
+         /* bfd_perform_relocation screws this up */
+         reloc->addend += reloc->address;
+       }
       s = bfd_perform_relocation (stdoutput, reloc, data - reloc->address,
                                  sec, stdoutput);
       switch (s)
@@ -1986,8 +1995,8 @@ fixup_segment (fixP, this_segment_type)
                    seg_reloc_count++;
                    add_number += S_GET_VALUE (add_symbolP);
                  }
-             }                 /* if not in local seg */
-         }                     /* if there was a + symbol */
+             }
+         }
 
        if (pcrel)
          {
@@ -2018,9 +2027,10 @@ fixup_segment (fixP, this_segment_type)
                if (add_number > 1000)
                  sprint_value (buf2, add_number);
                else
-                 sprintf (buf2, "%d", (long) add_number);
-               as_bad ("Value of %s too large for field of %d bytes at %s",
-                       buf2, size, buf);
+                 sprintf (buf2, "%ld", (long) add_number);
+               as_bad_where (fixP->fx_file, fixP->fx_line,
+                             "Value of %s too large for field of %d bytes at %s",
+                             buf2, size, buf);
              }                 /* generic error checking */
 #ifdef WARN_SIGNED_OVERFLOW_WORD
            /* Warn if a .word value is too large when treated as a signed
@@ -2029,9 +2039,10 @@ fixup_segment (fixP, this_segment_type)
            if (!flagseen['J']
                && size == 2
                && add_number > 0x7fff)
-             as_bad ("Signed .word overflow; switch may be too large; %ld at 0x%lx",
-                     (long) add_number,
-                     (unsigned long) (fragP->fr_address + where));
+             as_bad_where (fixP->fx_file, fixP->fx_line,
+                           "Signed .word overflow; switch may be too large; %ld at 0x%lx",
+                           (long) add_number,
+                           (unsigned long) (fragP->fr_address + where));
 #endif
          }                     /* not a bit fix */