summaryrefslogtreecommitdiff
path: root/gas/config/tc-m68k.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-10-13 08:55:30 +0000
committerNick Clifton <nickc@redhat.com>2009-10-13 08:55:30 +0000
commit0d7a283bfacee53bbd5535e0f597dc57240c1194 (patch)
tree01e18c769a06d1723aeb1933382643c6b53cb54d /gas/config/tc-m68k.c
parent98b8c69d2032ba9ef31bb48cc052451bfcc3f3e2 (diff)
downloadbinutils-redhat-0d7a283bfacee53bbd5535e0f597dc57240c1194.tar.gz
gas:
2009-10-07 Vincent Riviere <vincent.riviere@freesbee.fr> PR gas/3041 * config/tc-m68k.c (tc_gen_reloc): Fix addend for relocations located in data section an referencing a weak symbol. gas/testsuite: 2009-10-07 Vincent Riviere <vincent.riviere@freesbee.fr> PR gas/3041 * gas/m68k/all.exp: Added "p3041data". * gas/m68k/p3041.d, gas/m68k/p3041.s: Added tests of weak references from text section to all possible sections. * gas/m68k/p3041data.d, gas/m68k/p3041data.s: New test. Check weak references from data section.
Diffstat (limited to 'gas/config/tc-m68k.c')
-rw-r--r--gas/config/tc-m68k.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c
index 7bb6828260..9616ba560c 100644
--- a/gas/config/tc-m68k.c
+++ b/gas/config/tc-m68k.c
@@ -1326,10 +1326,29 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
&& fixp->fx_addsy
&& S_IS_WEAK (fixp->fx_addsy)
&& ! bfd_is_und_section (S_GET_SEGMENT (fixp->fx_addsy)))
- /* PR gas/3041 Adjust addend in order to force bfd_install_relocation()
- to put the symbol offset into frags referencing a weak symbol. */
- reloc->addend = fixp->fx_addnumber
- - (S_GET_VALUE (fixp->fx_addsy) * 2);
+ {
+ /* PR gas/3041 References to weak symbols must be treated as extern
+ in order to be overridable by the linker, even if they are defined
+ in the same object file. So the original addend must be written
+ "as is" into the output section without further processing.
+ The addend value must be hacked here in order to force
+ bfd_install_relocation() to write the original value into the
+ output section.
+ 1) MD_APPLY_SYM_VALUE() is set to 1 for m68k/a.out, so the symbol
+ value has already been added to the addend in fixup_segment(). We
+ have to remove it.
+ 2) bfd_install_relocation() will incorrectly treat this symbol as
+ resolved, so it will write the symbol value plus its addend and
+ section VMA. As a workaround we can tweak the addend value here in
+ order to get the original value in the section after the call to
+ bfd_install_relocation(). */
+ reloc->addend = fixp->fx_addnumber
+ /* Fix because of MD_APPLY_SYM_VALUE() */
+ - S_GET_VALUE (fixp->fx_addsy)
+ /* Fix for bfd_install_relocation() */
+ - (S_GET_VALUE (fixp->fx_addsy)
+ + S_GET_SEGMENT (fixp->fx_addsy)->vma);
+ }
else
reloc->addend = 0;
#else