aboutsummaryrefslogtreecommitdiff
path: root/gas/write.c
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@cygnus>1993-10-25 17:49:24 +0000
committerKen Raeburn <raeburn@cygnus>1993-10-25 17:49:24 +0000
commit84fa9814e99dda28d53c558e0d86b84289bd9ace (patch)
treebe5bcf06116e25876dcbda14483a460c0f255dbb /gas/write.c
parent9b6a882eebcbcdfe862673f84aff7f4e2bdc2ce0 (diff)
downloadgdb-84fa9814e99dda28d53c558e0d86b84289bd9ace.zip
gdb-84fa9814e99dda28d53c558e0d86b84289bd9ace.tar.gz
gdb-84fa9814e99dda28d53c558e0d86b84289bd9ace.tar.bz2
* write.c (write_relocs): For relocs that are pc_relative and
pcrel_offset and not partial_inplace, adjust reloc->addend to compensate for a bfd_perform_relocation bug.
Diffstat (limited to 'gas/write.c')
-rw-r--r--gas/write.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/gas/write.c b/gas/write.c
index 2b8aec9..30ab746 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -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 */