diff options
author | Ken Raeburn <raeburn@cygnus> | 1993-10-25 17:49:24 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1993-10-25 17:49:24 +0000 |
commit | 84fa9814e99dda28d53c558e0d86b84289bd9ace (patch) | |
tree | be5bcf06116e25876dcbda14483a460c0f255dbb | |
parent | 9b6a882eebcbcdfe862673f84aff7f4e2bdc2ce0 (diff) | |
download | gdb-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.
-rw-r--r-- | gas/write.c | 27 |
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 */ |