From a7be2893a6449e64fe6cfcdd8700b0a367a69f19 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Sun, 27 Dec 2015 12:30:26 -0800 Subject: [PATCH] Correct nios2 _gp address computation. 2015-12-27 Sandra Loosemore bfd/ * elf32-nios2.c (nios2_elf_assign_gp): Correct computation of _gp address. (nios2_elf32_relocate_section): Tidy code for R_NIOS2_GPREL error messages. --- bfd/ChangeLog | 7 +++++++ bfd/elf32-nios2.c | 31 +++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a3f3a6c08cb..0689cf0cca0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2015-12-27 Sandra Loosemore + + * elf32-nios2.c (nios2_elf_assign_gp): Correct computation of _gp + address. + (nios2_elf32_relocate_section): Tidy code for R_NIOS2_GPREL error + messages. + 2015-12-24 Thomas Preud'homme * elf32-arm.c (using_thumb_only): Check that profile is 'M' and update diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c index 1c54320e53d..babecf3bf34 100644 --- a/bfd/elf32-nios2.c +++ b/bfd/elf32-nios2.c @@ -3086,7 +3086,15 @@ lookup: case bfd_link_hash_defined: case bfd_link_hash_defweak: gp_found = TRUE; - *pgp = lh->u.def.value; + { + asection *sym_sec = lh->u.def.section; + bfd_vma sym_value = lh->u.def.value; + + if (sym_sec->output_section) + sym_value = (sym_value + sym_sec->output_offset + + sym_sec->output_section->vma); + *pgp = sym_value; + } break; case bfd_link_hash_indirect: case bfd_link_hash_warning: @@ -3719,7 +3727,6 @@ nios2_elf32_relocate_section (bfd *output_bfd, struct elf32_nios2_link_hash_entry *eh; bfd_vma relocation; bfd_vma gp; - bfd_vma reloc_address; bfd_reloc_status_type r = bfd_reloc_ok; const char *name = NULL; int r_type; @@ -3762,12 +3769,6 @@ nios2_elf32_relocate_section (bfd *output_bfd, if (bfd_link_relocatable (info)) continue; - if (sec && sec->output_section) - reloc_address = (sec->output_section->vma + sec->output_offset - + rel->r_offset); - else - reloc_address = 0; - if (howto) { switch (howto->type) @@ -3816,6 +3817,15 @@ nios2_elf32_relocate_section (bfd *output_bfd, /* Turns an absolute address into a gp-relative address. */ if (!nios2_elf_assign_gp (output_bfd, &gp, info)) { + bfd_vma reloc_address; + + if (sec && sec->output_section) + reloc_address = (sec->output_section->vma + + sec->output_offset + + rel->r_offset); + else + reloc_address = 0; + format = _("global pointer relative relocation at address " "0x%08x when _gp not defined\n"); sprintf (msgbuf, format, reloc_address); @@ -3825,7 +3835,7 @@ nios2_elf32_relocate_section (bfd *output_bfd, else { bfd_vma symbol_address = rel->r_addend + relocation; - relocation = relocation + rel->r_addend - gp; + relocation = symbol_address - gp; rel->r_addend = 0; if (((signed) relocation < -32768 || (signed) relocation > 32767) @@ -3833,6 +3843,8 @@ nios2_elf32_relocate_section (bfd *output_bfd, || h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak)) { + if (h) + name = h->root.root.string; format = _("Unable to reach %s (at 0x%08x) from the " "global pointer (at 0x%08x) because the " "offset (%d) is out of the allowed range, " @@ -3848,7 +3860,6 @@ nios2_elf32_relocate_section (bfd *output_bfd, rel->r_offset, relocation, rel->r_addend); } - break; case R_NIOS2_UJMP: r = nios2_elf32_do_ujmp_relocate (input_bfd, howto, -- 2.30.2