diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2002-10-13 21:22:31 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@redhat.com> | 2002-10-13 21:22:31 +0000 |
commit | bce03d3da87e892ff24475217dd76c4d0c18f8c2 (patch) | |
tree | 9320a6b2f5c53a3f1705ccecdc58e8cbacfbd838 | |
parent | e1026ffb69bd2e0ba19c66acf7b6f81ca3b0d104 (diff) | |
download | gdb-bce03d3da87e892ff24475217dd76c4d0c18f8c2.zip gdb-bce03d3da87e892ff24475217dd76c4d0c18f8c2.tar.gz gdb-bce03d3da87e892ff24475217dd76c4d0c18f8c2.tar.bz2 |
* elfxx-mips.c (mips_elf_calculate_relocation): Take
save_addend argument. Don't apply the 32-bit mask to a
GPREL32 value if it's to be used in another relocation. Don't
use forced-check computation of local_p to decide whether to
add gp0 to GPREL16 value. Don't use only the lowest 16 bits
of the addend of a non-in-place GPREL16 relocation.
(_bfd_mips_elf_relocate_section): Pass use_saved_addend_p to
mips_elf_calculate_relocation().
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 32 |
2 files changed, 34 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ba16bd9..1c25594 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2002-10-13 Alexandre Oliva <aoliva@redhat.com> + + * elfxx-mips.c (mips_elf_calculate_relocation): Take + save_addend argument. Don't apply the 32-bit mask to a + GPREL32 value if it's to be used in another relocation. Don't + use forced-check computation of local_p to decide whether to + add gp0 to GPREL16 value. Don't use only the lowest 16 bits + of the addend of a non-in-place GPREL16 relocation. + (_bfd_mips_elf_relocate_section): Pass use_saved_addend_p to + mips_elf_calculate_relocation(). + 2002-10-12 Stephane Carrez <stcarrez@nerim.fr> * elf32-m68hc11.c (m68hc11_elf_relax_section): Don't treat relocs diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 9584bde..a179057 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -345,7 +345,7 @@ static bfd_reloc_status_type mips_elf_calculate_relocation PARAMS ((bfd *, bfd *, asection *, struct bfd_link_info *, const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *, Elf_Internal_Sym *, asection **, bfd_vma *, const char **, - boolean *)); + boolean *, boolean)); static bfd_vma mips_elf_obtain_contents PARAMS ((reloc_howto_type *, const Elf_Internal_Rela *, bfd *, bfd_byte *)); static boolean mips_elf_perform_relocation @@ -2006,7 +2006,7 @@ static bfd_reloc_status_type mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, relocation, addend, howto, local_syms, local_sections, valuep, namep, - require_jalxp) + require_jalxp, save_addend) bfd *abfd; bfd *input_bfd; asection *input_section; @@ -2019,6 +2019,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, bfd_vma *valuep; const char **namep; boolean *require_jalxp; + boolean save_addend; { /* The eventual value we will return. */ bfd_vma value; @@ -2043,7 +2044,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, struct mips_elf_link_hash_entry *h = NULL; /* True if the symbol referred to by this relocation is a local symbol. */ - boolean local_p; + boolean local_p, was_local_p; /* True if the symbol referred to by this relocation is "_gp_disp". */ boolean gp_disp_p = false; Elf_Internal_Shdr *symtab_hdr; @@ -2071,6 +2072,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; local_p = mips_elf_local_relocation_p (input_bfd, relocation, local_sections, false); + was_local_p = local_p; if (! elf_bad_symtab (input_bfd)) extsymoff = symtab_hdr->sh_info; else @@ -2458,10 +2460,19 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, order. We don't need to do anything special here; the differences are handled in mips_elf_perform_relocation. */ case R_MIPS_GPREL16: - if (local_p) - value = mips_elf_sign_extend (addend, 16) + symbol + gp0 - gp; - else - value = mips_elf_sign_extend (addend, 16) + symbol - gp; + /* Only sign-extend the addend if it was extracted from the + instruction. If the addend was separate, leave it alone, + otherwise we may lose significant bits. */ + if (howto->partial_inplace) + addend = mips_elf_sign_extend (addend, 16); + value = symbol + addend - gp; + /* If the symbol was local, any earlier relocatable links will + have adjusted its addend with the gp offset, so compensate + for that now. Don't do it for symbols forced local in this + link, though, since they won't have had the gp offset applied + to them before. */ + if (was_local_p) + value += gp0; overflowed_p = mips_elf_overflow_p (value, 16); break; @@ -2494,7 +2505,9 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, break; case R_MIPS_GPREL32: - value = (addend + symbol + gp0 - gp) & howto->dst_mask; + value = (addend + symbol + gp0 - gp); + if (!save_addend) + value &= howto->dst_mask; break; case R_MIPS_PC16: @@ -5251,7 +5264,8 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, input_section, info, rel, addend, howto, local_syms, local_sections, &value, - &name, &require_jalx)) + &name, &require_jalx, + use_saved_addend_p)) { case bfd_reloc_continue: /* There's nothing to do. */ |