diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 50 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 2 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 12 | ||||
-rw-r--r-- | bfd/elf32-microblaze.c | 4 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 201 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 42 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 3 | ||||
-rw-r--r-- | bfd/version.h | 2 |
8 files changed, 197 insertions, 119 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 035353b..b161a20 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,53 @@ +2017-03-09 Alan Modra <amodra@gmail.com> + + Apply from master + 2016-09-26 Alan Modra <amodra@gmail.com> + * elf-bfd.h (_bfd_elf_ppc_merge_fp_attributes): Declare. + * elf32-ppc.c (_bfd_elf_ppc_merge_fp_attributes): New function. + (ppc_elf_merge_obj_attributes): Use it. Don't copy first file + attributes, merge them. Don't warn about undefined tag bits, + or copy unknown values to output. + * elf64-ppc.c (ppc64_elf_merge_private_bfd_data): Call + _bfd_elf_ppc_merge_fp_attributes. + +2017-02-22 Alan Modra <amodra@gmail.com> + + * elf64-ppc.c (ppc64_elf_finish_dynamic_sections): Don't segfault + on .got or .plt output section being discarded by script. + * elf32-ppc.c (ppc_elf_finish_dynamic_sections): Likewise. Move + vxworks splt temp. + +2017-02-21 Alan Modra <amodra@gmail.com> + + Apply from master + 2016-12-06 Alan Modra <amodra@gmail.com> + * elf64-ppc.c (ok_lo_toc_insn): Add r_type param. Recognize + lq,lfq,lxv,lxsd,lxssp,lfdp,stq,stfq,stxv,stxsd,stxssp,stfdp. + Don't match lmd and stmd. + +2017-02-15 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/21168 + * elf32-i386.c (elf_i386_relocate_section): Allow + "lea foo@GOT, %reg" in PIC. + +2016-12-23 Maciej W. Rozycki <macro@imgtec.com> + + * bfd/elfxx-mips.c (_bfd_mips_post_process_headers): Revert + 2016-02-23 change and remove EI_ABIVERSION 5 support. + +2016-11-30 Alan Modra <amodra@gmail.com> + + PR ld/20886 + * elf64-ppc.c (ppc64_elf_size_stubs): Make rawsize max size seen + on any pass past STUB_SHRINK_ITER. + +2016-10-31 Alan Modra <amodra@gmail.com> + + PR 20748 + * elf32-microblaze.c (microblaze_elf_finish_dynamic_sections): Revert + 2016-05-13 change. + 2016-10-10 Christophe Lyon <christophe.lyon@linaro.org> Backport from mainline 2016-09-28 Christophe Lyon <christophe.lyon@linaro.org> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 163ef35..9b87037 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2376,6 +2376,8 @@ extern unsigned int _bfd_elf_ppc_at_tprel_transform (unsigned int, unsigned int); /* PowerPC elf_object_p tweak. */ extern bfd_boolean _bfd_elf_ppc_set_arch (bfd *); +/* PowerPC .gnu.attributes handling common to both 32-bit and 64-bit. */ +extern void _bfd_elf_ppc_merge_fp_attributes (bfd *, bfd *); /* Exported interface for writing elf corefile notes. */ extern char *elfcore_write_note diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 4179572..d549ffe 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -3993,7 +3993,9 @@ elf_i386_relocate_section (bfd *output_bfd, - gotplt->output_section->vma - gotplt->output_offset); - if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5) + if (rel->r_offset > 1 + && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5 + && *(contents + rel->r_offset - 2) != 0x8d) { if (bfd_link_pic (info)) goto disallow_got32; @@ -4263,13 +4265,15 @@ r_386_got32: relocation = (htab->elf.sgot->output_section->vma + htab->elf.sgot->output_offset + off); - if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5) + if (rel->r_offset > 1 + && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5 + && *(contents + rel->r_offset - 2) != 0x8d) { if (bfd_link_pic (info)) { /* For PIC, disallow R_386_GOT32 without a base - register since we don't know what the GOT base - is. */ + register, except for "lea foo@GOT, %reg", since + we don't know what the GOT base is. */ const char *name; disallow_got32: diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c index 5496d16..d964e17 100644 --- a/bfd/elf32-microblaze.c +++ b/bfd/elf32-microblaze.c @@ -3400,13 +3400,13 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd, { asection *s; - s = bfd_get_linker_section (dynobj, name); + s = bfd_get_section_by_name (output_bfd, name); if (s == NULL) dyn.d_un.d_val = 0; else { if (! size) - dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; + dyn.d_un.d_ptr = s->vma; else dyn.d_un.d_val = s->size; } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index e42ef1c..d42e2cd 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -4647,68 +4647,87 @@ ppc_elf_check_relocs (bfd *abfd, return TRUE; } - -/* Merge object attributes from IBFD into OBFD. Raise an error if - there are conflicting attributes. */ -static bfd_boolean -ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) +/* Warn for conflicting Tag_GNU_Power_ABI_FP attributes between IBFD + and OBFD, and merge non-conflicting ones. */ +void +_bfd_elf_ppc_merge_fp_attributes (bfd *ibfd, bfd *obfd) { obj_attribute *in_attr, *in_attrs; obj_attribute *out_attr, *out_attrs; - if (!elf_known_obj_attributes_proc (obfd)[0].i) - { - /* This is the first object. Copy the attributes. */ - _bfd_elf_copy_obj_attributes (ibfd, obfd); - - /* Use the Tag_null value to indicate the attributes have been - initialized. */ - elf_known_obj_attributes_proc (obfd)[0].i = 1; - - return TRUE; - } - in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU]; out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU]; - /* Check for conflicting Tag_GNU_Power_ABI_FP attributes and merge - non-conflicting ones. */ in_attr = &in_attrs[Tag_GNU_Power_ABI_FP]; out_attr = &out_attrs[Tag_GNU_Power_ABI_FP]; + if (in_attr->i != out_attr->i) { - out_attr->type = 1; - if (out_attr->i == 0) - out_attr->i = in_attr->i; - else if (in_attr->i == 0) + int in_fp = in_attr->i & 3; + int out_fp = out_attr->i & 3; + + if (in_fp == 0) ; - else if (out_attr->i == 1 && in_attr->i == 2) + else if (out_fp == 0) + { + out_attr->type = 1; + out_attr->i ^= in_fp; + } + else if (out_fp != 2 && in_fp == 2) _bfd_error_handler (_("Warning: %B uses hard float, %B uses soft float"), obfd, ibfd); - else if (out_attr->i == 1 && in_attr->i == 3) + else if (out_fp == 2 && in_fp != 2) _bfd_error_handler - (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"), - obfd, ibfd); - else if (out_attr->i == 3 && in_attr->i == 1) + (_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd); + else if (out_fp == 1 && in_fp == 3) _bfd_error_handler - (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"), - ibfd, obfd); - else if (out_attr->i == 3 && in_attr->i == 2) + (_("Warning: %B uses double-precision hard float, " + "%B uses single-precision hard float"), obfd, ibfd); + else if (out_fp == 3 && in_fp == 1) _bfd_error_handler - (_("Warning: %B uses soft float, %B uses single-precision hard float"), - ibfd, obfd); - else if (out_attr->i == 2 && (in_attr->i == 1 || in_attr->i == 3)) + (_("Warning: %B uses double-precision hard float, " + "%B uses single-precision hard float"), ibfd, obfd); + + in_fp = in_attr->i & 0xc; + out_fp = out_attr->i & 0xc; + if (in_fp == 0) + ; + else if (out_fp == 0) + { + out_attr->type = 1; + out_attr->i ^= in_fp; + } + else if (out_fp != 2 * 4 && in_fp == 2 * 4) _bfd_error_handler - (_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd); - else if (in_attr->i > 3) + (_("Warning: %B uses 64-bit long double, " + "%B uses 128-bit long double"), ibfd, obfd); + else if (in_fp != 2 * 4 && out_fp == 2 * 4) _bfd_error_handler - (_("Warning: %B uses unknown floating point ABI %d"), ibfd, - in_attr->i); - else + (_("Warning: %B uses 64-bit long double, " + "%B uses 128-bit long double"), obfd, ibfd); + else if (out_fp == 1 * 4 && in_fp == 3 * 4) _bfd_error_handler - (_("Warning: %B uses unknown floating point ABI %d"), obfd, - out_attr->i); + (_("Warning: %B uses IBM long double, " + "%B uses IEEE long double"), ibfd, obfd); + else if (out_fp == 3 * 4 && in_fp == 1 * 4) + _bfd_error_handler + (_("Warning: %B uses IBM long double, " + "%B uses IEEE long double"), obfd, ibfd); } +} + +/* Merge object attributes from IBFD into OBFD. Warn if + there are conflicting attributes. */ +static bfd_boolean +ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) +{ + obj_attribute *in_attr, *in_attrs; + obj_attribute *out_attr, *out_attrs; + + _bfd_elf_ppc_merge_fp_attributes (ibfd, obfd); + + in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU]; + out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU]; /* Check for conflicting Tag_GNU_Power_ABI_Vector attributes and merge non-conflicting ones. */ @@ -4716,48 +4735,36 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) out_attr = &out_attrs[Tag_GNU_Power_ABI_Vector]; if (in_attr->i != out_attr->i) { - const char *in_abi = NULL, *out_abi = NULL; - - switch (in_attr->i) - { - case 1: in_abi = "generic"; break; - case 2: in_abi = "AltiVec"; break; - case 3: in_abi = "SPE"; break; - } + int in_vec = in_attr->i & 3; + int out_vec = out_attr->i & 3; - switch (out_attr->i) + if (in_vec == 0) + ; + else if (out_vec == 0) { - case 1: out_abi = "generic"; break; - case 2: out_abi = "AltiVec"; break; - case 3: out_abi = "SPE"; break; + out_attr->type = 1; + out_attr->i = in_vec; } - - out_attr->type = 1; - if (out_attr->i == 0) - out_attr->i = in_attr->i; - else if (in_attr->i == 0) - ; /* For now, allow generic to transition to AltiVec or SPE without a warning. If GCC marked files with their stack alignment and used don't-care markings for files which are not affected by the vector ABI, we could warn about this case too. */ - else if (out_attr->i == 1) - out_attr->i = in_attr->i; - else if (in_attr->i == 1) + else if (in_vec == 1) ; - else if (in_abi == NULL) - _bfd_error_handler - (_("Warning: %B uses unknown vector ABI %d"), ibfd, - in_attr->i); - else if (out_abi == NULL) + else if (out_vec == 1) + { + out_attr->type = 1; + out_attr->i = in_vec; + } + else if (out_vec < in_vec) _bfd_error_handler - (_("Warning: %B uses unknown vector ABI %d"), obfd, - in_attr->i); - else + (_("Warning: %B uses AltiVec vector ABI, %B uses SPE vector ABI"), + obfd, ibfd); + else if (out_vec > in_vec) _bfd_error_handler - (_("Warning: %B uses vector ABI \"%s\", %B uses \"%s\""), - ibfd, obfd, in_abi, out_abi); + (_("Warning: %B uses AltiVec vector ABI, %B uses SPE vector ABI"), + ibfd, obfd); } /* Check for conflicting Tag_GNU_Power_ABI_Struct_Return attributes @@ -4766,25 +4773,24 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) out_attr = &out_attrs[Tag_GNU_Power_ABI_Struct_Return]; if (in_attr->i != out_attr->i) { - out_attr->type = 1; - if (out_attr->i == 0) - out_attr->i = in_attr->i; - else if (in_attr->i == 0) + int in_struct = in_attr->i & 3; + int out_struct = out_attr->i & 3; + + if (in_struct == 0 || in_struct == 3) ; - else if (out_attr->i == 1 && in_attr->i == 2) - _bfd_error_handler - (_("Warning: %B uses r3/r4 for small structure returns, %B uses memory"), obfd, ibfd); - else if (out_attr->i == 2 && in_attr->i == 1) - _bfd_error_handler - (_("Warning: %B uses r3/r4 for small structure returns, %B uses memory"), ibfd, obfd); - else if (in_attr->i > 2) - _bfd_error_handler - (_("Warning: %B uses unknown small structure return convention %d"), ibfd, - in_attr->i); - else - _bfd_error_handler - (_("Warning: %B uses unknown small structure return convention %d"), obfd, - out_attr->i); + else if (out_struct == 0) + { + out_attr->type = 1; + out_attr->i = in_struct; + } + else if (out_struct < in_struct) + _bfd_error_handler + (_("Warning: %B uses r3/r4 for small structure returns, " + "%B uses memory"), obfd, ibfd); + else if (out_struct > in_struct) + _bfd_error_handler + (_("Warning: %B uses r3/r4 for small structure returns, " + "%B uses memory"), ibfd, obfd); } /* Merge Tag_compatibility attributes and any common GNU ones. */ @@ -10303,11 +10309,6 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, htab = ppc_elf_hash_table (info); dynobj = elf_hash_table (info)->dynobj; sdyn = bfd_get_linker_section (dynobj, ".dynamic"); - if (htab->is_vxworks) - splt = bfd_get_linker_section (dynobj, ".plt"); - else - splt = NULL; - got = 0; if (htab->elf.hgot != NULL) got = SYM_VAL (htab->elf.hgot); @@ -10370,7 +10371,8 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, } } - if (htab->got != NULL) + if (htab->got != NULL + && htab->got->output_section != bfd_abs_section_ptr) { if (htab->elf.hgot->root.u.def.section == htab->got || htab->elf.hgot->root.u.def.section == htab->sgotplt) @@ -10410,7 +10412,12 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, } /* Fill in the first entry in the VxWorks procedure linkage table. */ - if (splt && splt->size > 0) + splt = NULL; + if (htab->is_vxworks) + splt = bfd_get_linker_section (dynobj, ".plt"); + if (splt != NULL + && splt->size != 0 + && splt->output_section != bfd_abs_section_ptr) { /* Use the right PLT. */ const bfd_vma *plt_entry = (bfd_link_pic (info) diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index d236732..ee3c3b2 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -5998,6 +5998,8 @@ ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) return FALSE; } + _bfd_elf_ppc_merge_fp_attributes (ibfd, obfd); + /* Merge Tag_compatibility attributes and any common GNU ones. */ _bfd_elf_merge_object_attributes (ibfd, obfd); @@ -8803,12 +8805,14 @@ adjust_toc_syms (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Return TRUE iff INSN is one we expect on a _LO variety toc/got reloc. */ +/* Return TRUE iff INSN with a relocation of R_TYPE is one we expect + on a _LO variety toc/got reloc. */ static bfd_boolean -ok_lo_toc_insn (unsigned int insn) +ok_lo_toc_insn (unsigned int insn, enum elf_ppc64_reloc_type r_type) { - return ((insn & (0x3f << 26)) == 14u << 26 /* addi */ + return ((insn & (0x3f << 26)) == 12u << 26 /* addic */ + || (insn & (0x3f << 26)) == 14u << 26 /* addi */ || (insn & (0x3f << 26)) == 32u << 26 /* lwz */ || (insn & (0x3f << 26)) == 34u << 26 /* lbz */ || (insn & (0x3f << 26)) == 36u << 26 /* stw */ @@ -8822,11 +8826,20 @@ ok_lo_toc_insn (unsigned int insn) || (insn & (0x3f << 26)) == 50u << 26 /* lfd */ || (insn & (0x3f << 26)) == 52u << 26 /* stfs */ || (insn & (0x3f << 26)) == 54u << 26 /* stfd */ - || ((insn & (0x3f << 26)) == 58u << 26 /* lwa,ld,lmd */ - && (insn & 3) != 1) - || ((insn & (0x3f << 26)) == 62u << 26 /* std, stmd */ - && ((insn & 3) == 0 || (insn & 3) == 3)) - || (insn & (0x3f << 26)) == 12u << 26 /* addic */); + || (insn & (0x3f << 26)) == 56u << 26 /* lq,lfq */ + || ((insn & (0x3f << 26)) == 57u << 26 /* lxsd,lxssp,lfdp */ + /* Exclude lfqu by testing reloc. If relocs are ever + defined for the reduced D field in psq_lu then those + will need testing too. */ + && r_type != R_PPC64_TOC16_LO && r_type != R_PPC64_GOT16_LO) + || ((insn & (0x3f << 26)) == 58u << 26 /* ld,lwa */ + && (insn & 1) == 0) + || (insn & (0x3f << 26)) == 60u << 26 /* stfq */ + || ((insn & (0x3f << 26)) == 61u << 26 /* lxv,stx{v,sd,ssp},stfdp */ + /* Exclude stfqu. psq_stu as above for psq_lu. */ + && r_type != R_PPC64_TOC16_LO && r_type != R_PPC64_GOT16_LO) + || ((insn & (0x3f << 26)) == 62u << 26 /* std,stq */ + && (insn & 1) == 0)); } /* Examine all relocs referencing .toc sections in order to remove @@ -9131,7 +9144,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) } insn = bfd_get_32 (ibfd, buf); if (insn_check == check_lo - ? !ok_lo_toc_insn (insn) + ? !ok_lo_toc_insn (insn, r_type) : ((insn & ((0x3f << 26) | 0x1f << 16)) != ((15u << 26) | (2 << 16)) /* addis rt,2,imm */)) { @@ -12540,7 +12553,10 @@ ppc64_elf_size_stubs (struct bfd_link_info *info) stub_sec = stub_sec->next) if ((stub_sec->flags & SEC_LINKER_CREATED) == 0) { - stub_sec->rawsize = stub_sec->size; + if (htab->stub_iteration <= STUB_SHRINK_ITER + || stub_sec->rawsize < stub_sec->size) + /* Past STUB_SHRINK_ITER, rawsize is the max size seen. */ + stub_sec->rawsize = stub_sec->size; stub_sec->size = 0; stub_sec->reloc_count = 0; stub_sec->flags &= ~SEC_RELOC; @@ -15518,7 +15534,8 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd, } } - if (htab->elf.sgot != NULL && htab->elf.sgot->size != 0) + if (htab->elf.sgot != NULL && htab->elf.sgot->size != 0 + && htab->elf.sgot->output_section != bfd_abs_section_ptr) { /* Fill in the first entry in the global offset table. We use it to hold the link-time TOCbase. */ @@ -15530,7 +15547,8 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd, elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 8; } - if (htab->elf.splt != NULL && htab->elf.splt->size != 0) + if (htab->elf.splt != NULL && htab->elf.splt->size != 0 + && htab->elf.splt->output_section != bfd_abs_section_ptr) { /* Set .plt entry size. */ elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index e47276b..80e171d 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -16187,9 +16187,6 @@ _bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info) if (mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64 || mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64A) i_ehdrp->e_ident[EI_ABIVERSION] = 3; - - if (elf_stack_flags (abfd) && !(elf_stack_flags (abfd) & PF_X)) - i_ehdrp->e_ident[EI_ABIVERSION] = 5; } int diff --git a/bfd/version.h b/bfd/version.h index b959b37..28e0359 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -1,4 +1,4 @@ -#define BFD_VERSION_DATE 20161019 +#define BFD_VERSION_DATE 20161229 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ |