diff --git a/binutils-2.28-gold.patch b/binutils-2.28-gold.patch new file mode 100644 index 0000000..210895b --- /dev/null +++ b/binutils-2.28-gold.patch @@ -0,0 +1,1706 @@ +diff -rup ../binutils-2.27/gold/aarch64.cc gold/aarch64.cc +--- ../binutils-2.27/gold/aarch64.cc 2016-09-26 11:22:18.728811436 +0100 ++++ gold/aarch64.cc 2016-11-03 15:05:31.000000000 +0000 +@@ -6026,6 +6026,23 @@ Target_aarch64::Scan:: + } + break; + ++ case elfcpp::R_AARCH64_MOVW_UABS_G0: // 263 ++ case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: // 264 ++ case elfcpp::R_AARCH64_MOVW_UABS_G1: // 265 ++ case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: // 266 ++ case elfcpp::R_AARCH64_MOVW_UABS_G2: // 267 ++ case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: // 268 ++ case elfcpp::R_AARCH64_MOVW_UABS_G3: // 269 ++ case elfcpp::R_AARCH64_MOVW_SABS_G0: // 270 ++ case elfcpp::R_AARCH64_MOVW_SABS_G1: // 271 ++ case elfcpp::R_AARCH64_MOVW_SABS_G2: // 272 ++ if (parameters->options().output_is_position_independent()) ++ { ++ gold_error(_("%s: unsupported reloc %u in pos independent link."), ++ object->name().c_str(), r_type); ++ } ++ break; ++ + case elfcpp::R_AARCH64_LD_PREL_LO19: // 273 + case elfcpp::R_AARCH64_ADR_PREL_LO21: // 274 + case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: // 275 +@@ -6311,6 +6328,23 @@ Target_aarch64::Scan:: + } + break; + ++ case elfcpp::R_AARCH64_MOVW_UABS_G0: // 263 ++ case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: // 264 ++ case elfcpp::R_AARCH64_MOVW_UABS_G1: // 265 ++ case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: // 266 ++ case elfcpp::R_AARCH64_MOVW_UABS_G2: // 267 ++ case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: // 268 ++ case elfcpp::R_AARCH64_MOVW_UABS_G3: // 269 ++ case elfcpp::R_AARCH64_MOVW_SABS_G0: // 270 ++ case elfcpp::R_AARCH64_MOVW_SABS_G1: // 271 ++ case elfcpp::R_AARCH64_MOVW_SABS_G2: // 272 ++ if (parameters->options().output_is_position_independent()) ++ { ++ gold_error(_("%s: unsupported reloc %u in pos independent link."), ++ object->name().c_str(), r_type); ++ } ++ break; ++ + case elfcpp::R_AARCH64_LD_PREL_LO19: // 273 + case elfcpp::R_AARCH64_ADR_PREL_LO21: // 274 + case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: // 275 +@@ -6993,6 +7027,23 @@ Target_aarch64::Reloca + view, object, psymval, addend, address, reloc_property); + break; + ++ case elfcpp::R_AARCH64_MOVW_UABS_G0: ++ case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: ++ case elfcpp::R_AARCH64_MOVW_UABS_G1: ++ case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: ++ case elfcpp::R_AARCH64_MOVW_UABS_G2: ++ case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: ++ case elfcpp::R_AARCH64_MOVW_UABS_G3: ++ reloc_status = Reloc::template rela_general<32>( ++ view, object, psymval, addend, reloc_property); ++ break; ++ case elfcpp::R_AARCH64_MOVW_SABS_G0: ++ case elfcpp::R_AARCH64_MOVW_SABS_G1: ++ case elfcpp::R_AARCH64_MOVW_SABS_G2: ++ reloc_status = Reloc::movnz(view, psymval->value(object, addend), ++ reloc_property); ++ break; ++ + case elfcpp::R_AARCH64_LD_PREL_LO19: + reloc_status = Reloc::template pcrela_general<32>( + view, object, psymval, addend, address, reloc_property); +@@ -8075,7 +8126,7 @@ Target_aarch64::is_err + typename elfcpp::Swap<32,big_endian>::Valtype insn2) + { + uint32_t rt; +- uint32_t rt2; ++ uint32_t rt2 = 0; + uint32_t rn; + uint32_t rm; + uint32_t ra; +diff -rup ../binutils-2.27/gold/aarch64-reloc.def gold/aarch64-reloc.def +--- ../binutils-2.27/gold/aarch64-reloc.def 2016-08-03 08:36:53.000000000 +0100 ++++ gold/aarch64-reloc.def 2016-11-03 14:38:22.000000000 +0000 +@@ -43,6 +43,20 @@ ARD(PREL32 , STATI + ARD(PREL16 , STATIC , DATA , Y, -1, 15,16 , 0,0 , Symbol::RELATIVE_REF , DATA ) + // Above is from Table 4-6, Data relocations, 257-262. + ++ARD(MOVW_UABS_G0 , STATIC , AARCH64 , Y, 0, 0,16 , 0,15 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_UABS_G0_NC , STATIC , AARCH64 , Y, 0, 0,0 , 0,15 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_UABS_G1 , STATIC , AARCH64 , Y, 0, 0,32 , 16,31 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_UABS_G1_NC , STATIC , AARCH64 , Y, 0, 0,0 , 16,31 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_UABS_G2 , STATIC , AARCH64 , Y, 0, 0,48 , 32,47 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_UABS_G2_NC , STATIC , AARCH64 , Y, 0, 0,0 , 32,47 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_UABS_G3 , STATIC , AARCH64 , Y, 0, 0,0 , 48,63 , Symbol::ABSOLUTE_REF , MOVW ) ++// Above is from Table 4-7, Group relocations to create a 16-, 32-, 48-, or 64-bit unsigned data value or address inline. ++ ++ARD(MOVW_SABS_G0 , STATIC , AARCH64 , Y, 0, 16,16 , 0,15 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_SABS_G1 , STATIC , AARCH64 , Y, 0, 32,32 , 16,31 , Symbol::ABSOLUTE_REF , MOVW ) ++ARD(MOVW_SABS_G2 , STATIC , AARCH64 , Y, 0, 48,48 , 32,47 , Symbol::ABSOLUTE_REF , MOVW ) ++// Above is from Table 4-8, Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline. ++ + ARD(LD_PREL_LO19 , STATIC , AARCH64 , Y, -1, 20,20 , 2,20 , Symbol::RELATIVE_REF , LDST ) + ARD(ADR_PREL_LO21 , STATIC , AARCH64 , Y, -1, 20,20 , 0,20 , Symbol::RELATIVE_REF , ADR ) + ARD(ADR_PREL_PG_HI21 , STATIC , AARCH64 , Y, -1, 32,32 , 12,32 , Symbol::RELATIVE_REF , ADRP ) +diff -rup ../binutils-2.27/gold/aarch64-reloc-property.cc gold/aarch64-reloc-property.cc +--- ../binutils-2.27/gold/aarch64-reloc-property.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/aarch64-reloc-property.cc 2016-11-03 15:05:32.000000000 +0000 +@@ -59,17 +59,51 @@ template<> + bool + rvalue_checkup<0, 0>(int64_t) { return true; } + ++namespace ++{ ++ + template +-uint64_t +-rvalue_bit_select(uint64_t x) ++class Rvalue_bit_select_impl + { +- if (U == 63) return x >> L; +- return (x & (((uint64_t)1 << (U+1)) - 1)) >> L; +-} ++public: ++ static uint64_t ++ calc(uint64_t x) ++ { ++ return (x & ((1ULL << (U+1)) - 1)) >> L; ++ } ++}; ++ ++template ++class Rvalue_bit_select_impl ++{ ++public: ++ static uint64_t ++ calc(uint64_t x) ++ { ++ return x >> L; ++ } ++}; + ++// By our convention, L=U=0 means that the whole value should be retrieved. + template<> ++class Rvalue_bit_select_impl<0, 0> ++{ ++public: ++ static uint64_t ++ calc(uint64_t x) ++ { ++ return x; ++ } ++}; ++ ++} // End anonymous namespace. ++ ++template + uint64_t +-rvalue_bit_select<0, 0>(uint64_t x) { return x; } ++rvalue_bit_select(uint64_t x) ++{ ++ return Rvalue_bit_select_impl::calc(x); ++} + + AArch64_reloc_property::AArch64_reloc_property( + unsigned int code, +diff -rup ../binutils-2.27/gold/arm.cc gold/arm.cc +--- ../binutils-2.27/gold/arm.cc 2016-09-26 11:22:18.629810833 +0100 ++++ gold/arm.cc 2016-11-03 15:05:33.000000000 +0000 +@@ -2128,8 +2128,36 @@ class Target_arm : public Sized_target<3 + stub_tables_(), stub_factory_(Stub_factory::get_instance()), + should_force_pic_veneer_(false), + arm_input_section_map_(), attributes_section_data_(NULL), +- fix_cortex_a8_(false), cortex_a8_relocs_info_() +- { } ++ fix_cortex_a8_(false), cortex_a8_relocs_info_(), ++ target1_reloc_(elfcpp::R_ARM_ABS32), ++ // This can be any reloc type but usually is R_ARM_GOT_PREL. ++ target2_reloc_(elfcpp::R_ARM_GOT_PREL) ++ { ++ if (parameters->options().user_set_target1_rel()) ++ { ++ // FIXME: This is not strictly compatible with ld, which allows both ++ // --target1-abs and --target-rel to be given. ++ if (parameters->options().user_set_target1_abs()) ++ gold_error(_("Cannot use both --target1-abs and --target1-rel.")); ++ else ++ this->target1_reloc_ = elfcpp::R_ARM_REL32; ++ } ++ // We don't need to handle --target1-abs because target1_reloc_ is set ++ // to elfcpp::R_ARM_ABS32 in the member initializer list. ++ ++ if (parameters->options().user_set_target2()) ++ { ++ const char* target2 = parameters->options().target2(); ++ if (strcmp(target2, "rel") == 0) ++ this->target2_reloc_ = elfcpp::R_ARM_REL32; ++ else if (strcmp(target2, "abs") == 0) ++ this->target2_reloc_ = elfcpp::R_ARM_ABS32; ++ else if (strcmp(target2, "got-rel") == 0) ++ this->target2_reloc_ = elfcpp::R_ARM_GOT_PREL; ++ else ++ gold_unreachable(); ++ } ++ } + + // Whether we force PCI branch veneers. + bool +@@ -2391,8 +2419,8 @@ class Target_arm : public Sized_target<3 + rel_irelative_section(Layout*); + + // Map platform-specific reloc types +- static unsigned int +- get_real_reloc_type(unsigned int r_type); ++ unsigned int ++ get_real_reloc_type(unsigned int r_type) const; + + // + // Methods to support stub-generations. +@@ -3002,6 +3030,11 @@ class Target_arm : public Sized_target<3 + bool fix_cortex_a8_; + // Map addresses to relocs for Cortex-A8 erratum. + Cortex_a8_relocs_info cortex_a8_relocs_info_; ++ // What R_ARM_TARGET1 maps to. It can be R_ARM_REL32 or R_ARM_ABS32. ++ unsigned int target1_reloc_; ++ // What R_ARM_TARGET2 maps to. It should be one of R_ARM_REL32, R_ARM_ABS32 ++ // and R_ARM_GOT_PREL. ++ unsigned int target2_reloc_; + }; + + template +@@ -6639,6 +6672,80 @@ Arm_relobj::do_relocate_sect + section_address, + section_size); + } ++ // BE8 swapping ++ if (parameters->options().be8()) ++ { ++ section_size_type span_start, span_end; ++ elfcpp::Shdr<32, big_endian> ++ shdr(pshdrs + i * elfcpp::Elf_sizes<32>::shdr_size); ++ Mapping_symbol_position section_start(i, 0); ++ typename Mapping_symbols_info::const_iterator p = ++ this->mapping_symbols_info_.lower_bound(section_start); ++ unsigned char* view = (*pviews)[i].view; ++ Arm_address view_address = (*pviews)[i].address; ++ section_size_type view_size = (*pviews)[i].view_size; ++ while (p != this->mapping_symbols_info_.end() ++ && p->first.first == i) ++ { ++ typename Mapping_symbols_info::const_iterator next = ++ this->mapping_symbols_info_.upper_bound(p->first); ++ ++ // Only swap arm or thumb code. ++ if ((p->second == 'a') || (p->second == 't')) ++ { ++ Output_section* os = this->output_section(i); ++ gold_assert(os != NULL); ++ Arm_address section_address = ++ this->simple_input_section_output_address(i, os); ++ span_start = convert_to_section_size_type(p->first.second); ++ if (next != this->mapping_symbols_info_.end() ++ && next->first.first == i) ++ span_end = ++ convert_to_section_size_type(next->first.second); ++ else ++ span_end = ++ convert_to_section_size_type(shdr.get_sh_size()); ++ unsigned char* section_view = ++ view + (section_address - view_address); ++ uint64_t section_size = this->section_size(i); ++ ++ gold_assert(section_address >= view_address ++ && ((section_address + section_size) ++ <= (view_address + view_size))); ++ ++ // Set Output view for swapping ++ unsigned char *oview = section_view + span_start; ++ unsigned int index = 0; ++ if (p->second == 'a') ++ { ++ while (index + 3 < (span_end - span_start)) ++ { ++ typedef typename elfcpp::Swap<32, big_endian> ++ ::Valtype Valtype; ++ Valtype* wv = ++ reinterpret_cast(oview+index); ++ uint32_t val = elfcpp::Swap<32, false>::readval(wv); ++ elfcpp::Swap<32, true>::writeval(wv, val); ++ index += 4; ++ } ++ } ++ else if (p->second == 't') ++ { ++ while (index + 1 < (span_end - span_start)) ++ { ++ typedef typename elfcpp::Swap<16, big_endian> ++ ::Valtype Valtype; ++ Valtype* wv = ++ reinterpret_cast(oview+index); ++ uint16_t val = elfcpp::Swap<16, false>::readval(wv); ++ elfcpp::Swap<16, true>::writeval(wv, val); ++ index += 2; ++ } ++ } ++ } ++ p = next; ++ } ++ } + } + } + +@@ -7785,7 +7892,18 @@ Output_data_plt_arm_standard + const size_t num_first_plt_words = (sizeof(first_plt_entry) + / sizeof(first_plt_entry[0])); + for (size_t i = 0; i < num_first_plt_words - 1; i++) +- elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]); ++ { ++ if (parameters->options().be8()) ++ { ++ elfcpp::Swap<32, false>::writeval(pov + i * 4, ++ first_plt_entry[i]); ++ } ++ else ++ { ++ elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, ++ first_plt_entry[i]); ++ } ++ } + // Last word in first PLT entry is &GOT[0] - . + elfcpp::Swap<32, big_endian>::writeval(pov + 16, + got_address - (plt_address + 16)); +@@ -7846,11 +7964,21 @@ Output_data_plt_arm_short::d + gold_error(_("PLT offset too large, try linking with --long-plt")); + + uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff); +- elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); + uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff); +- elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); + uint32_t plt_insn2 = plt_entry[2] | (offset & 0xfff); +- elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); ++ ++ if (parameters->options().be8()) ++ { ++ elfcpp::Swap<32, false>::writeval(pov, plt_insn0); ++ elfcpp::Swap<32, false>::writeval(pov + 4, plt_insn1); ++ elfcpp::Swap<32, false>::writeval(pov + 8, plt_insn2); ++ } ++ else ++ { ++ elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); ++ elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); ++ elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); ++ } + } + + // This class generates long (16-byte) entries, for arbitrary displacements. +@@ -7906,13 +8034,24 @@ Output_data_plt_arm_long::do + - (plt_address + plt_offset + 8)); + + uint32_t plt_insn0 = plt_entry[0] | (offset >> 28); +- elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); + uint32_t plt_insn1 = plt_entry[1] | ((offset >> 20) & 0xff); +- elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); + uint32_t plt_insn2 = plt_entry[2] | ((offset >> 12) & 0xff); +- elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); + uint32_t plt_insn3 = plt_entry[3] | (offset & 0xfff); +- elfcpp::Swap<32, big_endian>::writeval(pov + 12, plt_insn3); ++ ++ if (parameters->options().be8()) ++ { ++ elfcpp::Swap<32, false>::writeval(pov, plt_insn0); ++ elfcpp::Swap<32, false>::writeval(pov + 4, plt_insn1); ++ elfcpp::Swap<32, false>::writeval(pov + 8, plt_insn2); ++ elfcpp::Swap<32, false>::writeval(pov + 12, plt_insn3); ++ } ++ else ++ { ++ elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); ++ elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); ++ elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); ++ elfcpp::Swap<32, big_endian>::writeval(pov + 12, plt_insn3); ++ } + } + + // Write out the PLT. This uses the hand-coded instructions above, +@@ -8414,7 +8553,7 @@ Target_arm::Scan::local(Symb + if (is_discarded) + return; + +- r_type = get_real_reloc_type(r_type); ++ r_type = target->get_real_reloc_type(r_type); + + // A local STT_GNU_IFUNC symbol may require a PLT entry. + bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC; +@@ -8820,7 +8959,7 @@ Target_arm::Scan::global(Sym + && this->reloc_needs_plt_for_ifunc(object, r_type)) + target->make_plt_entry(symtab, layout, gsym); + +- r_type = get_real_reloc_type(r_type); ++ r_type = target->get_real_reloc_type(r_type); + switch (r_type) + { + case elfcpp::R_ARM_NONE: +@@ -9446,7 +9585,7 @@ Target_arm::Relocate::reloca + + const elfcpp::Rel<32, big_endian> rel(preloc); + unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info()); +- r_type = get_real_reloc_type(r_type); ++ r_type = target->get_real_reloc_type(r_type); + const Arm_reloc_property* reloc_property = + arm_reloc_property_table->get_implemented_static_reloc_property(r_type); + if (reloc_property == NULL) +@@ -10156,7 +10295,9 @@ Target_arm::Classify_reloc:: + unsigned int r_type, + Relobj* object) + { +- r_type = get_real_reloc_type(r_type); ++ Target_arm* arm_target = ++ Target_arm::default_target(); ++ r_type = arm_target->get_real_reloc_type(r_type); + const Arm_reloc_property* arp = + arm_reloc_property_table->get_implemented_static_reloc_property(r_type); + if (arp != NULL) +@@ -10580,17 +10721,15 @@ Target_arm::do_dynsym_value( + // + template + unsigned int +-Target_arm::get_real_reloc_type(unsigned int r_type) ++Target_arm::get_real_reloc_type(unsigned int r_type) const + { + switch (r_type) + { + case elfcpp::R_ARM_TARGET1: +- // This is either R_ARM_ABS32 or R_ARM_REL32; +- return elfcpp::R_ARM_ABS32; ++ return this->target1_reloc_; + + case elfcpp::R_ARM_TARGET2: +- // This can be any reloc type but usually is R_ARM_GOT_PREL +- return elfcpp::R_ARM_GOT_PREL; ++ return this->target2_reloc_; + + default: + return r_type; +@@ -10683,7 +10822,14 @@ Target_arm::do_adjust_elf_he + e_ident[elfcpp::EI_OSABI] = 0; + e_ident[elfcpp::EI_ABIVERSION] = 0; + +- // FIXME: Do EF_ARM_BE8 adjustment. ++ // Do EF_ARM_BE8 adjustment. ++ if (parameters->options().be8() && !big_endian) ++ gold_error("BE8 images only valid in big-endian mode."); ++ if (parameters->options().be8()) ++ { ++ flags |= elfcpp::EF_ARM_BE8; ++ this->set_processor_specific_flags(flags); ++ } + + // If we're working in EABI_VER5, set the hard/soft float ABI flags + // as appropriate. +diff -rup ../binutils-2.27/gold/configure gold/configure +--- ../binutils-2.27/gold/configure 2016-09-26 11:22:19.027813254 +0100 ++++ gold/configure 2016-11-03 14:38:22.000000000 +0000 +@@ -609,6 +609,7 @@ GOLD_LDFLAGS + WARN_CXXFLAGS + WARN_WRITE_STRINGS + NO_WERROR ++WARN_CFLAGS_FOR_BUILD + WARN_CFLAGS + IFUNC_STATIC_FALSE + IFUNC_STATIC_TRUE +@@ -6723,8 +6724,12 @@ fi + # Set the 'development' global. + . $srcdir/../bfd/development.sh + ++# Set acp_cpp_for_build variable ++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD" ++ + # Default set of GCC warnings to enable. + GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes" ++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes" + + # Add -Wshadow if the compiler is a sufficiently recent version of GCC. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +@@ -6769,6 +6774,36 @@ fi + rm -f conftest* + + ++# Verify CC_FOR_BUILD to be compatible with waring flags ++ ++# Add -Wshadow if the compiler is a sufficiently recent version of GCC. ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__GNUC__ ++_ACEOF ++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 | ++ $EGREP "^[0-3]$" >/dev/null 2>&1; then : ++ ++else ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow" ++fi ++rm -f conftest* ++ ++ ++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC. ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__GNUC__ ++_ACEOF ++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 | ++ $EGREP "^[0-4]$" >/dev/null 2>&1; then : ++ ++else ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144" ++fi ++rm -f conftest* ++ ++ + # Check whether --enable-werror was given. + if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; case "${enableval}" in +@@ -6784,6 +6819,7 @@ case "${host}" in + *-*-mingw32*) + if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then + GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format" ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format" + fi + ;; + *) ;; +@@ -6797,25 +6833,32 @@ fi + NO_WERROR= + if test "${ERROR_ON_WARNING}" = yes ; then + GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror" ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror" + NO_WERROR="-Wno-error" + fi + + if test "${GCC}" = yes ; then + WARN_CFLAGS="${GCC_WARN_CFLAGS}" ++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}" + fi + + # Check whether --enable-build-warnings was given. + if test "${enable_build_warnings+set}" = set; then : + enableval=$enable_build_warnings; case "${enableval}" in +- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";; ++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}" ++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";; + no) if test "${GCC}" = yes ; then + WARN_CFLAGS="-w" ++ WARN_CFLAGS_FOR_BUILD="-w" + fi;; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` +- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";; ++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}" ++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` +- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";; +- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;; ++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}" ++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";; ++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"` ++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;; + esac + fi + +diff -rup ../binutils-2.27/gold/debug.h gold/debug.h +--- ../binutils-2.27/gold/debug.h 2016-08-03 08:36:53.000000000 +0100 ++++ gold/debug.h 2016-11-03 15:05:05.000000000 +0000 +@@ -39,10 +39,11 @@ const int DEBUG_FILES = 0x4; + const int DEBUG_RELAXATION = 0x8; + const int DEBUG_INCREMENTAL = 0x10; + const int DEBUG_LOCATION = 0x20; ++const int DEBUG_TARGET = 0x40; + + const int DEBUG_ALL = (DEBUG_TASK | DEBUG_SCRIPT | DEBUG_FILES + | DEBUG_RELAXATION | DEBUG_INCREMENTAL +- | DEBUG_LOCATION); ++ | DEBUG_LOCATION | DEBUG_TARGET); + + // Convert a debug string to the appropriate enum. + inline int +@@ -57,6 +58,7 @@ debug_string_to_enum(const char* arg) + { "relaxation", DEBUG_RELAXATION }, + { "incremental", DEBUG_INCREMENTAL }, + { "location", DEBUG_LOCATION }, ++ { "target", DEBUG_TARGET }, + { "all", DEBUG_ALL } + }; + +@@ -70,11 +72,11 @@ debug_string_to_enum(const char* arg) + // Print a debug message if TYPE is enabled. This is a macro so that + // we only evaluate the arguments if necessary. + +-#define gold_debug(TYPE, FORMAT, ...) \ ++#define gold_debug(TYPE, ...) \ + do \ + { \ + if (is_debugging_enabled(TYPE)) \ +- parameters->errors()->debug(FORMAT, __VA_ARGS__); \ ++ parameters->errors()->debug(__VA_ARGS__); \ + } \ + while (0) + +diff -rup ../binutils-2.27/gold/i386.cc gold/i386.cc +--- ../binutils-2.27/gold/i386.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/i386.cc 2016-11-03 15:05:40.000000000 +0000 +@@ -2794,8 +2794,11 @@ Target_i386::Relocate::relocate(const Re + && r_type != elfcpp::R_386_PC32) + || gsym == NULL + || strcmp(gsym->name(), "___tls_get_addr") != 0) +- gold_error_at_location(relinfo, relnum, rel.get_r_offset(), +- _("missing expected TLS relocation")); ++ { ++ gold_error_at_location(relinfo, relnum, rel.get_r_offset(), ++ _("missing expected TLS relocation")); ++ this->skip_call_tls_get_addr_ = false; ++ } + else + { + this->skip_call_tls_get_addr_ = false; +diff -rup ../binutils-2.27/gold/icf.cc gold/icf.cc +--- ../binutils-2.27/gold/icf.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/icf.cc 2016-11-03 15:05:40.000000000 +0000 +@@ -590,6 +590,7 @@ match_sections(unsigned int iteration_nu + std::vector* num_tracked_relocs, + std::vector* kept_section_id, + const std::vector& id_section, ++ const std::vector& section_addraligns, + std::vector* is_secn_or_group_unique, + std::vector* section_contents) + { +@@ -630,13 +631,7 @@ match_sections(unsigned int iteration_nu + { + if ((*kept_section_id)[i] != i) + { +- // This section is already folded into something. See +- // if it should point to a different kept section. +- unsigned int kept_section = (*kept_section_id)[i]; +- if (kept_section != (*kept_section_id)[kept_section]) +- { +- (*kept_section_id)[i] = (*kept_section_id)[kept_section]; +- } ++ // This section is already folded into something. + continue; + } + this_secn_contents = get_section_contents(false, secn, i, NULL, +@@ -671,7 +666,25 @@ match_sections(unsigned int iteration_nu + this_secn_contents.c_str(), + this_secn_contents.length()) != 0) + continue; +- (*kept_section_id)[i] = kept_section; ++ ++ // Check section alignment here. ++ // The section with the larger alignment requirement ++ // should be kept. We assume alignment can only be ++ // zero or postive integral powers of two. ++ uint64_t align_i = section_addraligns[i]; ++ uint64_t align_kept = section_addraligns[kept_section]; ++ if (align_i <= align_kept) ++ { ++ (*kept_section_id)[i] = kept_section; ++ } ++ else ++ { ++ (*kept_section_id)[kept_section] = i; ++ it->second = i; ++ full_section_contents[kept_section].swap( ++ full_section_contents[i]); ++ } ++ + converged = false; + break; + } +@@ -688,6 +701,26 @@ match_sections(unsigned int iteration_nu + (*is_secn_or_group_unique)[i] = true; + } + ++ // If a section was folded into another section that was later folded ++ // again then the former has to be updated. ++ for (unsigned int i = 0; i < id_section.size(); i++) ++ { ++ // Find the end of the folding chain ++ unsigned int kept = i; ++ while ((*kept_section_id)[kept] != kept) ++ { ++ kept = (*kept_section_id)[kept]; ++ } ++ // Update every element of the chain ++ unsigned int current = i; ++ while ((*kept_section_id)[current] != kept) ++ { ++ unsigned int next = (*kept_section_id)[current]; ++ (*kept_section_id)[current] = kept; ++ current = next; ++ } ++ } ++ + return converged; + } + +@@ -719,6 +752,7 @@ Icf::find_identical_sections(const Input + { + unsigned int section_num = 0; + std::vector num_tracked_relocs; ++ std::vector section_addraligns; + std::vector is_secn_or_group_unique; + std::vector section_contents; + const Target& target = parameters->target(); +@@ -759,6 +793,7 @@ Icf::find_identical_sections(const Input + this->section_id_[Section_id(*p, i)] = section_num; + this->kept_section_id_.push_back(section_num); + num_tracked_relocs.push_back(0); ++ section_addraligns.push_back((*p)->section_addralign(i)); + is_secn_or_group_unique.push_back(false); + section_contents.push_back(""); + section_num++; +@@ -779,8 +814,8 @@ Icf::find_identical_sections(const Input + num_iterations++; + converged = match_sections(num_iterations, symtab, + &num_tracked_relocs, &this->kept_section_id_, +- this->id_section_, &is_secn_or_group_unique, +- §ion_contents); ++ this->id_section_, section_addraligns, ++ &is_secn_or_group_unique, §ion_contents); + } + + if (parameters->options().print_icf_sections()) +diff -rup ../binutils-2.27/gold/layout.cc gold/layout.cc +--- ../binutils-2.27/gold/layout.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/layout.cc 2016-11-03 15:05:42.000000000 +0000 +@@ -2135,7 +2135,7 @@ void + Layout::create_notes() + { + this->create_gold_note(); +- this->create_executable_stack_info(); ++ this->create_stack_segment(); + this->create_build_id(); + } + +@@ -2785,7 +2785,7 @@ Layout::finalize(const Input_objects* in + if (load_seg != NULL) + ehdr_start->set_output_segment(load_seg, Symbol::SEGMENT_START); + else +- ehdr_start->set_undefined(); ++ ehdr_start->set_undefined(); + } + + // Set the file offsets of all the non-data sections we've seen so +@@ -2985,25 +2985,29 @@ Layout::create_gold_note() + // executable. Otherwise, if at least one input file a + // .note.GNU-stack section, and some input file has no .note.GNU-stack + // section, we use the target default for whether the stack should be +-// executable. Otherwise, we don't generate a stack note. When +-// generating a object file, we create a .note.GNU-stack section with +-// the appropriate marking. When generating an executable or shared +-// library, we create a PT_GNU_STACK segment. ++// executable. If -z stack-size was used to set a p_memsz value for ++// PT_GNU_STACK, we generate the segment regardless. Otherwise, we ++// don't generate a stack note. When generating a object file, we ++// create a .note.GNU-stack section with the appropriate marking. ++// When generating an executable or shared library, we create a ++// PT_GNU_STACK segment. + + void +-Layout::create_executable_stack_info() ++Layout::create_stack_segment() + { + bool is_stack_executable; + if (parameters->options().is_execstack_set()) + { + is_stack_executable = parameters->options().is_stack_executable(); + if (!is_stack_executable +- && this->input_requires_executable_stack_ +- && parameters->options().warn_execstack()) ++ && this->input_requires_executable_stack_ ++ && parameters->options().warn_execstack()) + gold_warning(_("one or more inputs require executable stack, " +- "but -z noexecstack was given")); ++ "but -z noexecstack was given")); + } +- else if (!this->input_with_gnu_stack_note_) ++ else if (!this->input_with_gnu_stack_note_ ++ && (!parameters->options().user_set_stack_size() ++ || parameters->options().relocatable())) + return; + else + { +@@ -3032,7 +3036,12 @@ Layout::create_executable_stack_info() + int flags = elfcpp::PF_R | elfcpp::PF_W; + if (is_stack_executable) + flags |= elfcpp::PF_X; +- this->make_output_segment(elfcpp::PT_GNU_STACK, flags); ++ Output_segment* seg = ++ this->make_output_segment(elfcpp::PT_GNU_STACK, flags); ++ seg->set_size(parameters->options().stack_size()); ++ // BFD lets targets override this default alignment, but the only ++ // targets that do so are ones that Gold does not support so far. ++ seg->set_minimum_p_align(16); + } + } + +@@ -3718,7 +3727,9 @@ Layout::set_segment_offsets(const Target + p != this->segment_list_.end(); + ++p) + { +- if ((*p)->type() != elfcpp::PT_LOAD) ++ // PT_GNU_STACK was set up correctly when it was created. ++ if ((*p)->type() != elfcpp::PT_LOAD ++ && (*p)->type() != elfcpp::PT_GNU_STACK) + (*p)->set_offset((*p)->type() == elfcpp::PT_GNU_RELRO + ? increase_relro + : 0); +diff -rup ../binutils-2.27/gold/layout.h gold/layout.h +--- ../binutils-2.27/gold/layout.h 2016-08-03 08:36:53.000000000 +0100 ++++ gold/layout.h 2016-11-03 15:05:12.000000000 +0000 +@@ -1037,9 +1037,9 @@ class Layout + void + create_gold_note(); + +- // Record whether the stack must be executable. ++ // Record whether the stack must be executable, and a user-supplied size. + void +- create_executable_stack_info(); ++ create_stack_segment(); + + // Create a build ID note if needed. + void +diff -rup ../binutils-2.27/gold/Makefile.in gold/Makefile.in +--- ../binutils-2.27/gold/Makefile.in 2016-08-03 08:36:53.000000000 +0100 ++++ gold/Makefile.in 2016-11-03 14:38:22.000000000 +0000 +@@ -87,8 +87,8 @@ subdir = . + DIST_COMMON = NEWS README ChangeLog $(srcdir)/Makefile.in \ + $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(srcdir)/config.in \ +- $(srcdir)/../mkinstalldirs $(top_srcdir)/po/Make-in \ +- ftruncate.c pread.c mremap.c ffsll.c yyscript.h yyscript.c \ ++ $(srcdir)/../mkinstalldirs $(top_srcdir)/po/Make-in ffsll.c \ ++ mremap.c ftruncate.c pread.c yyscript.h yyscript.c \ + $(srcdir)/../depcomp $(srcdir)/../ylwrap + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ +@@ -409,6 +409,7 @@ TARGETOBJS = @TARGETOBJS@ + USE_NLS = @USE_NLS@ + VERSION = @VERSION@ + WARN_CFLAGS = @WARN_CFLAGS@ ++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@ + WARN_CXXFLAGS = @WARN_CXXFLAGS@ + WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@ + XGETTEXT = @XGETTEXT@ +diff -rup ../binutils-2.27/gold/options.h gold/options.h +--- ../binutils-2.27/gold/options.h 2016-08-03 08:36:53.000000000 +0100 ++++ gold/options.h 2016-11-03 15:05:13.000000000 +0000 +@@ -647,7 +647,7 @@ class General_options + DEFINE_bool(apply_dynamic_relocs, options::TWO_DASHES, '\0', true, + N_("Apply link-time values for dynamic relocations (default)"), + N_("(aarch64 only) Do not apply link-time values " +- "for dynamic relocations")); ++ "for dynamic relocations")); + + DEFINE_bool(as_needed, options::TWO_DASHES, '\0', false, + N_("Only set DT_NEEDED for shared libraries if used"), +@@ -674,6 +674,9 @@ class General_options + DEFINE_bool_alias(dn, Bdynamic, options::ONE_DASH, '\0', + N_("alias for -Bstatic"), NULL, true); + ++ DEFINE_bool(be8,options::TWO_DASHES, '\0', false, ++ N_("Output BE8 format image"), NULL); ++ + DEFINE_bool(Bgroup, options::ONE_DASH, '\0', false, + N_("Use group name lookup rules for shared library"), NULL); + +@@ -1152,6 +1155,17 @@ class General_options + DEFINE_string(sysroot, options::TWO_DASHES, '\0', "", + N_("Set target system root directory"), N_("DIR")); + ++ DEFINE_bool(target1_rel, options::TWO_DASHES, '\0', false, ++ N_("(ARM only) Force R_ARM_TARGET1 type to R_ARM_REL32"), ++ NULL); ++ DEFINE_bool(target1_abs, options::TWO_DASHES, '\0', false, ++ N_("(ARM only) Force R_ARM_TARGET1 type to R_ARM_ABS32"), ++ NULL); ++ DEFINE_enum(target2, options::TWO_DASHES, '\0', NULL, ++ N_("(ARM only) Set R_ARM_TARGET2 relocation type"), ++ N_("[rel, abs, got-rel"), ++ {"rel", "abs", "got-rel"}); ++ + DEFINE_bool(trace, options::TWO_DASHES, 't', false, + N_("Print the name of each input file"), NULL); + +@@ -1293,7 +1307,7 @@ class General_options + N_("Mark output as requiring executable stack"), NULL); + DEFINE_bool(global, options::DASH_Z, '\0', false, + N_("Make symbols in DSO available for subsequently loaded " +- "objects"), NULL); ++ "objects"), NULL); + DEFINE_bool(initfirst, options::DASH_Z, '\0', false, + N_("Mark DSO to be initialized first at runtime"), + NULL); +@@ -1339,6 +1353,8 @@ class General_options + DEFINE_bool(relro, options::DASH_Z, '\0', DEFAULT_LD_Z_RELRO, + N_("Where possible mark variables read-only after relocation"), + N_("Don't mark variables read-only after relocation")); ++ DEFINE_uint64(stack_size, options::DASH_Z, '\0', 0, ++ N_("Set PT_GNU_STACK segment p_memsz to SIZE"), N_("SIZE")); + DEFINE_bool(text, options::DASH_Z, '\0', false, + N_("Do not permit relocations in read-only segments"), + N_("Permit relocations in read-only segments (default)")); +diff -rup ../binutils-2.27/gold/output.cc gold/output.cc +--- ../binutils-2.27/gold/output.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/output.cc 2016-11-03 15:05:44.000000000 +0000 +@@ -4398,7 +4398,7 @@ Output_segment::set_section_addresses(co + this->offset_ = orig_off; + + off_t off = 0; +- uint64_t ret; ++ uint64_t ret = 0; + for (int i = 0; i < static_cast(ORDER_MAX); ++i) + { + if (i == static_cast(ORDER_RELRO_LAST)) +diff -rup ../binutils-2.27/gold/output.h gold/output.h +--- ../binutils-2.27/gold/output.h 2016-08-03 08:36:53.000000000 +0100 ++++ gold/output.h 2016-11-03 15:05:14.000000000 +0000 +@@ -2499,7 +2499,7 @@ class Output_data_got : public Output_da + // entry. + bool + add_local(Relobj* object, unsigned int sym_index, unsigned int got_type, +- uint64_t addend); ++ uint64_t addend); + + // Like add_local, but use the PLT offset of the local symbol if it + // has one. +@@ -2643,7 +2643,7 @@ class Output_data_got : public Output_da + + // Create a local symbol entry plus addend. + Got_entry(Relobj* object, unsigned int local_sym_index, +- bool use_plt_or_tls_offset, uint64_t addend) ++ bool use_plt_or_tls_offset, uint64_t addend) + : local_sym_index_(local_sym_index), + use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(addend) + { +@@ -4796,6 +4796,13 @@ class Output_segment + this->min_p_align_ = align; + } + ++ // Set the memory size of this segment. ++ void ++ set_size(uint64_t size) ++ { ++ this->memsz_ = size; ++ } ++ + // Set the offset of this segment based on the section. This should + // only be called for a non-PT_LOAD segment. + void +diff -rup ../binutils-2.27/gold/powerpc.cc gold/powerpc.cc +--- ../binutils-2.27/gold/powerpc.cc 2016-09-26 11:22:18.717811369 +0100 ++++ gold/powerpc.cc 2016-11-03 15:05:45.000000000 +0000 +@@ -2439,9 +2439,8 @@ class Stub_control + // the stubbed branches. + Stub_control(int32_t size, bool no_size_errors) + : state_(NO_GROUP), stub_group_size_(abs(size)), +- stub14_group_size_(abs(size) >> 10), + stubs_always_before_branch_(size < 0), +- suppress_size_errors_(no_size_errors), ++ suppress_size_errors_(no_size_errors), group_size_(0), + group_end_addr_(0), owner_(NULL), output_section_(NULL) + { + } +@@ -2479,24 +2478,28 @@ class Stub_control + + State state_; + uint32_t stub_group_size_; +- uint32_t stub14_group_size_; + bool stubs_always_before_branch_; + bool suppress_size_errors_; ++ // Current max size of group. Starts at stub_group_size_ but is ++ // reduced to stub_group_size_/1024 on seeing a section with ++ // external conditional branches. ++ uint32_t group_size_; + uint64_t group_end_addr_; ++ // owner_ and output_section_ specify the section to which stubs are ++ // attached. The stubs are placed at the end of this section. + const Output_section::Input_section* owner_; + Output_section* output_section_; + }; + + // Return true iff input section can be handled by current stub +-// group. ++// group. Sections are presented to this function in reverse order, ++// so the first section is the tail of the group. + + bool + Stub_control::can_add_to_stub_group(Output_section* o, + const Output_section::Input_section* i, + bool has14) + { +- uint32_t group_size +- = has14 ? this->stub14_group_size_ : this->stub_group_size_; + bool whole_sec = o->order() == ORDER_INIT || o->order() == ORDER_FINI; + uint64_t this_size; + uint64_t start_addr = o->address(); +@@ -2510,46 +2513,90 @@ Stub_control::can_add_to_stub_group(Outp + start_addr += i->relobj()->output_section_offset(i->shndx()); + this_size = i->data_size(); + } +- uint64_t end_addr = start_addr + this_size; +- bool toobig = this_size > group_size; + +- if (toobig && !this->suppress_size_errors_) ++ uint32_t group_size = this->stub_group_size_; ++ if (has14) ++ this->group_size_ = group_size = group_size >> 10; ++ ++ if (this_size > group_size && !this->suppress_size_errors_) + gold_warning(_("%s:%s exceeds group size"), + i->relobj()->name().c_str(), + i->relobj()->section_name(i->shndx()).c_str()); + +- if (this->state_ != HAS_STUB_SECTION +- && (!whole_sec || this->output_section_ != o) +- && (this->state_ == NO_GROUP +- || this->group_end_addr_ - end_addr < group_size)) +- { +- this->owner_ = i; +- this->output_section_ = o; +- } +- +- if (this->state_ == NO_GROUP) +- { +- this->state_ = FINDING_STUB_SECTION; +- this->group_end_addr_ = end_addr; +- } +- else if (this->group_end_addr_ - start_addr < group_size) +- ; +- // Adding this section would make the group larger than GROUP_SIZE. +- else if (this->state_ == FINDING_STUB_SECTION +- && !this->stubs_always_before_branch_ +- && !toobig) +- { +- // But wait, there's more! Input sections up to GROUP_SIZE +- // bytes before the stub table can be handled by it too. +- this->state_ = HAS_STUB_SECTION; +- this->group_end_addr_ = end_addr; ++ gold_debug(DEBUG_TARGET, "maybe add%s %s:%s size=%#llx total=%#llx", ++ has14 ? " 14bit" : "", ++ i->relobj()->name().c_str(), ++ i->relobj()->section_name(i->shndx()).c_str(), ++ (long long) this_size, ++ (long long) this->group_end_addr_ - start_addr); ++ ++ uint64_t end_addr = start_addr + this_size; ++ if (this->state_ == HAS_STUB_SECTION) ++ { ++ // Can we add this section, which is before the stubs, to the ++ // group? ++ if (this->group_end_addr_ - start_addr <= this->group_size_) ++ return true; + } + else + { +- this->state_ = NO_GROUP; +- return false; ++ // Stubs are added at the end of "owner_". ++ // The current section can always be the stub owner, except when ++ // whole_sec is true and the current section isn't the last of ++ // the pasted sections. (This restriction for the whole_sec ++ // case is just to simplify the corner case mentioned in ++ // group_sections.) ++ // Note that "owner_" itself is not necessarily part of the ++ // group of sections served by these stubs! ++ if (!whole_sec || this->output_section_ != o) ++ { ++ this->owner_ = i; ++ this->output_section_ = o; ++ } ++ ++ if (this->state_ == FINDING_STUB_SECTION) ++ { ++ if (this->group_end_addr_ - start_addr <= this->group_size_) ++ return true; ++ // The group after the stubs has reached maximum size. ++ // Now see about adding sections before the stubs to the ++ // group. If the current section has a 14-bit branch and ++ // the group after the stubs exceeds group_size_ (because ++ // they didn't have 14-bit branches), don't add sections ++ // before the stubs: The size of stubs for such a large ++ // group may exceed the reach of a 14-bit branch. ++ if (!this->stubs_always_before_branch_ ++ && this_size <= this->group_size_ ++ && this->group_end_addr_ - end_addr <= this->group_size_) ++ { ++ gold_debug(DEBUG_TARGET, "adding before stubs"); ++ this->state_ = HAS_STUB_SECTION; ++ this->group_end_addr_ = end_addr; ++ return true; ++ } ++ } ++ else if (this->state_ == NO_GROUP) ++ { ++ // Only here on very first use of Stub_control ++ this->state_ = FINDING_STUB_SECTION; ++ this->group_size_ = group_size; ++ this->group_end_addr_ = end_addr; ++ return true; ++ } ++ else ++ gold_unreachable(); + } +- return true; ++ ++ gold_debug(DEBUG_TARGET, "nope, didn't fit\n"); ++ ++ // The section fails to fit in the current group. Set up a few ++ // things for the next group. owner_ and output_section_ will be ++ // set later after we've retrieved those values for the current ++ // group. ++ this->state_ = FINDING_STUB_SECTION; ++ this->group_size_ = group_size; ++ this->group_end_addr_ = end_addr; ++ return false; + } + + // Look over all the input sections, deciding where to place stubs. +@@ -2887,7 +2934,7 @@ Target_powerpc::do_rel + } + this->stub_tables_.clear(); + this->stub_group_size_ = this->stub_group_size_ / 4 * 3; +- gold_info(_("%s: stub group size is too large; retrying with %d"), ++ gold_info(_("%s: stub group size is too large; retrying with %#x"), + program_name, this->stub_group_size_); + this->group_sections(layout, task, true); + } +@@ -2982,7 +3029,13 @@ Target_powerpc::do_rel + Stub_table* stub_table + = static_cast*>( + i->relaxed_input_section()); +- off += stub_table->set_address_and_size(os, off); ++ Address stub_table_size = stub_table->set_address_and_size(os, off); ++ off += stub_table_size; ++ // After a few iterations, set current stub table size ++ // as min size threshold, so later stub tables can only ++ // grow in size. ++ if (pass >= 4) ++ stub_table->set_min_size_threshold(stub_table_size); + } + else + off += i->data_size(); +@@ -3634,8 +3687,8 @@ class Stub_table : public Output_relaxed + targ_(targ), plt_call_stubs_(), long_branch_stubs_(), + orig_data_size_(owner->current_data_size()), + plt_size_(0), last_plt_size_(0), +- branch_size_(0), last_branch_size_(0), eh_frame_added_(false), +- need_save_res_(false) ++ branch_size_(0), last_branch_size_(0), min_size_threshold_(0), ++ eh_frame_added_(false), need_save_res_(false) + { + this->set_output_section(output_section); + +@@ -3726,6 +3779,11 @@ class Stub_table : public Output_relaxed + off = align_address(off, this->stub_align()); + // Include original section size and alignment padding in size + my_size += off - start_off; ++ // Ensure new size is always larger than min size ++ // threshold. Alignment requirement is included in "my_size", so ++ // increase "my_size" does not invalidate alignment. ++ if (my_size < this->min_size_threshold_) ++ my_size = this->min_size_threshold_; + this->reset_address_and_file_offset(); + this->set_current_data_size(my_size); + this->set_address_and_file_offset(os->address() + start_off, +@@ -3751,6 +3809,9 @@ class Stub_table : public Output_relaxed + plt_size() const + { return this->plt_size_; } + ++ void set_min_size_threshold(Address min_size) ++ { this->min_size_threshold_ = min_size; } ++ + bool + size_update() + { +@@ -4015,6 +4076,13 @@ class Stub_table : public Output_relaxed + section_size_type orig_data_size_; + // size of stubs + section_size_type plt_size_, last_plt_size_, branch_size_, last_branch_size_; ++ // Some rare cases cause (PR/20529) fluctuation in stub table ++ // size, which leads to an endless relax loop. This is to be fixed ++ // by, after the first few iterations, allowing only increase of ++ // stub table size. This variable sets the minimal possible size of ++ // a stub table, it is zero for the first few iterations, then ++ // increases monotonically. ++ Address min_size_threshold_; + // Whether .eh_frame info has been created for this stub section. + bool eh_frame_added_; + // Set if this stub group needs a copy of out-of-line register +@@ -6024,7 +6092,7 @@ Target_powerpc::Scan:: + ppc_object->set_opd_discard(reloc.get_r_offset()); + break; + } +- // Fall thru ++ // Fall through. + case elfcpp::R_PPC64_UADDR64: + case elfcpp::R_POWERPC_ADDR32: + case elfcpp::R_POWERPC_UADDR32: +@@ -6131,7 +6199,7 @@ Target_powerpc::Scan:: + || gsym->is_preemptible()))) + target->make_plt_entry(symtab, layout, gsym); + } +- // Fall thru ++ // Fall through. + + case elfcpp::R_PPC64_REL64: + case elfcpp::R_POWERPC_REL32: +@@ -7521,6 +7589,7 @@ Target_powerpc::Reloca + if (size != 64) + // R_PPC_TLSGD, R_PPC_TLSLD, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HI + break; ++ // Fall through. + case elfcpp::R_POWERPC_TPREL16: + case elfcpp::R_POWERPC_TPREL16_LO: + case elfcpp::R_POWERPC_TPREL16_HI: +@@ -7544,6 +7613,7 @@ Target_powerpc::Reloca + // R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16, R_PPC_EMB_NADDR16_LO + // R_PPC_EMB_NADDR16_HI, R_PPC_EMB_NADDR16_HA, R_PPC_EMB_SDAI16 + break; ++ // Fall through. + case elfcpp::R_POWERPC_DTPREL16: + case elfcpp::R_POWERPC_DTPREL16_LO: + case elfcpp::R_POWERPC_DTPREL16_HI: +@@ -7572,6 +7642,7 @@ Target_powerpc::Reloca + case elfcpp::R_POWERPC_ADDR14_BRTAKEN: + case elfcpp::R_POWERPC_REL14_BRTAKEN: + branch_bit = 1 << 21; ++ // Fall through. + case elfcpp::R_POWERPC_ADDR14_BRNTAKEN: + case elfcpp::R_POWERPC_REL14_BRNTAKEN: + { +@@ -7936,6 +8007,7 @@ Target_powerpc::Reloca + maybe_dq_reloc = true; + break; + } ++ // Fall through. + case elfcpp::R_POWERPC_ADDR16: + case elfcpp::R_POWERPC_REL16: + case elfcpp::R_PPC64_TOC16: +@@ -7970,6 +8042,7 @@ Target_powerpc::Reloca + if (size == 32) + // R_PPC_EMB_MRKREF, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HA + goto unsupp; ++ // Fall through. + case elfcpp::R_POWERPC_ADDR16_HI: + case elfcpp::R_POWERPC_REL16_HI: + case elfcpp::R_PPC64_TOC16_HI: +@@ -7990,6 +8063,7 @@ Target_powerpc::Reloca + if (size == 32) + // R_PPC_EMB_RELSEC16, R_PPC_EMB_RELST_HI, R_PPC_EMB_BIT_FLD + goto unsupp; ++ // Fall through. + case elfcpp::R_POWERPC_ADDR16_HA: + case elfcpp::R_POWERPC_REL16_HA: + case elfcpp::R_PPC64_TOC16_HA: +@@ -8012,6 +8086,7 @@ Target_powerpc::Reloca + if (size == 32) + // R_PPC_EMB_NADDR16_LO + goto unsupp; ++ // Fall through. + case elfcpp::R_PPC64_ADDR16_HIGHER: + case elfcpp::R_PPC64_TPREL16_HIGHER: + Reloc::addr16_hi2(view, value); +@@ -8021,6 +8096,7 @@ Target_powerpc::Reloca + if (size == 32) + // R_PPC_EMB_NADDR16_HI + goto unsupp; ++ // Fall through. + case elfcpp::R_PPC64_ADDR16_HIGHERA: + case elfcpp::R_PPC64_TPREL16_HIGHERA: + Reloc::addr16_ha2(view, value); +@@ -8030,6 +8106,7 @@ Target_powerpc::Reloca + if (size == 32) + // R_PPC_EMB_NADDR16_HA + goto unsupp; ++ // Fall through. + case elfcpp::R_PPC64_ADDR16_HIGHEST: + case elfcpp::R_PPC64_TPREL16_HIGHEST: + Reloc::addr16_hi3(view, value); +@@ -8039,6 +8116,7 @@ Target_powerpc::Reloca + if (size == 32) + // R_PPC_EMB_SDAI16 + goto unsupp; ++ // Fall through. + case elfcpp::R_PPC64_ADDR16_HIGHESTA: + case elfcpp::R_PPC64_TPREL16_HIGHESTA: + Reloc::addr16_ha3(view, value); +@@ -8049,11 +8127,13 @@ Target_powerpc::Reloca + if (size == 32) + // R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16 + goto unsupp; ++ // Fall through. + case elfcpp::R_PPC64_TPREL16_DS: + case elfcpp::R_PPC64_TPREL16_LO_DS: + if (size == 32) + // R_PPC_TLSGD, R_PPC_TLSLD + break; ++ // Fall through. + case elfcpp::R_PPC64_ADDR16_DS: + case elfcpp::R_PPC64_ADDR16_LO_DS: + case elfcpp::R_PPC64_TOC16_DS: +diff -rup ../binutils-2.27/gold/resolve.cc gold/resolve.cc +--- ../binutils-2.27/gold/resolve.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/resolve.cc 2016-11-03 15:05:47.000000000 +0000 +@@ -193,6 +193,7 @@ symbol_to_bits(elfcpp::STB binding, bool + // table. + gold_error(_("invalid STB_LOCAL symbol in external symbols")); + bits = global_flag; ++ break; + + default: + // Any target which wants to handle STB_LOOS, etc., needs to +diff -rup ../binutils-2.27/gold/script.cc gold/script.cc +--- ../binutils-2.27/gold/script.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/script.cc 2016-11-03 15:05:47.000000000 +0000 +@@ -1755,6 +1755,7 @@ script_keyword_parsecodes[] = + { "FLOAT", FLOAT }, + { "FORCE_COMMON_ALLOCATION", FORCE_COMMON_ALLOCATION }, + { "GROUP", GROUP }, ++ { "HIDDEN", HIDDEN }, + { "HLL", HLL }, + { "INCLUDE", INCLUDE }, + { "INFO", INFO }, +diff -rup ../binutils-2.27/gold/script-sections.cc gold/script-sections.cc +--- ../binutils-2.27/gold/script-sections.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/script-sections.cc 2016-11-03 15:05:48.000000000 +0000 +@@ -1503,7 +1503,7 @@ class Input_section_info + private: + // Input section, can be a relaxed section. + Output_section::Input_section input_section_; +- // Name of the section. ++ // Name of the section. + std::string section_name_; + // Section size. + uint64_t size_; +@@ -1545,7 +1545,7 @@ Input_section_sorter::get_init_priority( + // GCC uses the following section names for the init_priority + // attribute with numerical values 101 and 65535 inclusive. A + // lower value means a higher priority. +- // ++ // + // 1: .init_array.NNNN/.fini_array.NNNN: Where NNNN is the + // decimal numerical value of the init_priority attribute. + // The order of execution in .init_array is forward and +@@ -1666,7 +1666,7 @@ Output_section_element_input::set_sectio + while (p != input_sections->end()) + { + Relobj* relobj = p->relobj(); +- unsigned int shndx = p->shndx(); ++ unsigned int shndx = p->shndx(); + Input_section_info isi(*p); + + // Calling section_name and section_addralign is not very +@@ -1758,7 +1758,7 @@ Output_section_element_input::set_sectio + + uint64_t this_subalign = sis.addralign(); + if (!sis.is_input_section()) +- sis.output_section_data()->finalize_data_size(); ++ sis.output_section_data()->finalize_data_size(); + uint64_t data_size = sis.data_size(); + if (this_subalign < subalign) + { +@@ -2029,7 +2029,7 @@ class Output_section_definition : public + void + set_section_vma(Expression* address) + { this->address_ = address; } +- ++ + void + set_section_lma(Expression* address) + { this->load_address_ = address; } +@@ -2037,7 +2037,7 @@ class Output_section_definition : public + const std::string& + get_section_name() const + { return this->name_; } +- ++ + private: + static const char* + script_section_type_name(Script_section_type); +@@ -2402,9 +2402,9 @@ Output_section_definition::set_section_a + uint64_t old_load_address = *load_address; + + // If input section sorting is requested via --section-ordering-file or +- // linker plugins, then do it here. This is important because we want ++ // linker plugins, then do it here. This is important because we want + // any sorting specified in the linker scripts, which will be done after +- // this, to take precedence. The final order of input sections is then ++ // this, to take precedence. The final order of input sections is then + // guaranteed to be according to the linker script specification. + if (this->output_section_ != NULL + && this->output_section_->input_section_order_specified()) +@@ -2495,7 +2495,7 @@ Output_section_definition::set_section_a + // The LMA address was explicitly set to the given region. + laddr = lma_region->get_current_address()->eval(symtab, layout, + false); +- else ++ else + { + // We are not going to use the discovered lma_region, so + // make sure that we do not update it in the code below. +@@ -2987,9 +2987,9 @@ Orphan_output_section::set_section_addre + address = align_address(address, this->os_->addralign()); + + // If input section sorting is requested via --section-ordering-file or +- // linker plugins, then do it here. This is important because we want ++ // linker plugins, then do it here. This is important because we want + // any sorting specified in the linker scripts, which will be done after +- // this, to take precedence. The final order of input sections is then ++ // this, to take precedence. The final order of input sections is then + // guaranteed to be according to the linker script specification. + if (this->os_ != NULL + && this->os_->input_section_order_specified()) +@@ -3023,7 +3023,7 @@ Orphan_output_section::set_section_addre + { + uint64_t addralign = p->addralign(); + if (!p->is_input_section()) +- p->output_section_data()->finalize_data_size(); ++ p->output_section_data()->finalize_data_size(); + uint64_t size = p->data_size(); + address = align_address(address, addralign); + this->os_->add_script_input_section(*p); +@@ -3605,7 +3605,7 @@ Output_segment* + Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout) + { + gold_assert(this->saw_sections_clause_); +- ++ + // Implement ONLY_IF_RO/ONLY_IF_RW constraints. These are a pain + // for our representation. + for (Sections_elements::iterator p = this->sections_elements_->begin(); +@@ -3674,7 +3674,7 @@ Script_sections::set_section_addresses(S + Output_section* os = (*p)->get_output_section(); + + // Handle -Ttext, -Tdata and -Tbss options. We do this by looking for +- // the special sections by names and doing dot assignments. ++ // the special sections by names and doing dot assignments. + if (use_tsection_options + && os != NULL + && (os->flags() & elfcpp::SHF_ALLOC) != 0) +@@ -3703,7 +3703,7 @@ Script_sections::set_section_addresses(S + + (*p)->set_section_addresses(symtab, layout, &dot_value, &dot_alignment, + &load_address); +- } ++ } + + if (this->phdrs_elements_ != NULL) + { +@@ -3890,7 +3890,7 @@ Script_sections::create_segments(Layout* + layout->get_allocated_sections(§ions); + + // Sort the sections by address. +- std::stable_sort(sections.begin(), sections.end(), ++ std::stable_sort(sections.begin(), sections.end(), + Sort_output_sections(this->sections_elements_)); + + this->create_note_and_tls_segments(layout, §ions); +@@ -4217,7 +4217,7 @@ Script_sections::attach_sections_using_p + // Output sections in the script which do not list segments are + // attached to the same set of segments as the immediately preceding + // output section. +- ++ + String_list* phdr_names = NULL; + bool load_segments_only = false; + for (Sections_elements::const_iterator p = this->sections_elements_->begin(); +@@ -4262,7 +4262,7 @@ Script_sections::attach_sections_using_p + // filtering. + if (old_phdr_names != phdr_names) + load_segments_only = false; +- ++ + // If this is an orphan section--one that was not explicitly + // mentioned in the linker script--then it should not inherit + // any segment type other than PT_LOAD. Otherwise, e.g., the +@@ -4459,6 +4459,7 @@ Script_sections::release_segments() + ++p) + (*p)->release_segment(); + } ++ this->segments_created_ = false; + } + + // Print the SECTIONS clause to F for debugging. +diff -rup ../binutils-2.27/gold/sparc.cc gold/sparc.cc +--- ../binutils-2.27/gold/sparc.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/sparc.cc 2016-11-03 15:05:48.000000000 +0000 +@@ -2150,6 +2150,7 @@ Target_sparc::Scan::ch + case elfcpp::R_SPARC_RELATIVE: + case elfcpp::R_SPARC_IRELATIVE: + case elfcpp::R_SPARC_COPY: ++ case elfcpp::R_SPARC_32: + case elfcpp::R_SPARC_64: + case elfcpp::R_SPARC_GLOB_DAT: + case elfcpp::R_SPARC_JMP_SLOT: +@@ -2304,7 +2305,7 @@ Target_sparc::Scan::lo + reloc.get_r_addend(), is_ifunc); + break; + } +- /* Fall through. */ ++ // Fall through. + + case elfcpp::R_SPARC_HIX22: + case elfcpp::R_SPARC_LOX10: +@@ -2814,6 +2815,7 @@ Target_sparc::Scan::gl + // and code transform the GOT load into an addition. + break; + } ++ // Fall through. + case elfcpp::R_SPARC_GOT10: + case elfcpp::R_SPARC_GOT13: + case elfcpp::R_SPARC_GOT22: +@@ -3353,6 +3355,7 @@ Target_sparc::Relocate + gdop_valid = true; + break; + } ++ // Fall through. + case elfcpp::R_SPARC_GOT10: + case elfcpp::R_SPARC_GOT13: + case elfcpp::R_SPARC_GOT22: +@@ -3468,6 +3471,13 @@ Target_sparc::Relocate + Reloc::lo10(view, object, psymval, addend); + break; + ++ case elfcpp::R_SPARC_GOTDATA_OP_LOX10: ++ if (gdop_valid) ++ { ++ Reloc::gdop_lox10(view, got_offset); ++ break; ++ } ++ // Fall through. + case elfcpp::R_SPARC_GOT10: + Reloc::lo10(view, got_offset, addend); + break; +@@ -3486,13 +3496,6 @@ Target_sparc::Relocate + } + break; + +- case elfcpp::R_SPARC_GOTDATA_OP_LOX10: +- if (gdop_valid) +- { +- Reloc::gdop_lox10(view, got_offset); +- break; +- } +- /* Fall through. */ + case elfcpp::R_SPARC_GOT13: + Reloc::rela32_13(view, got_offset, addend); + break; +@@ -3503,7 +3506,7 @@ Target_sparc::Relocate + Reloc::gdop_hix22(view, got_offset); + break; + } +- /* Fall through. */ ++ // Fall through. + case elfcpp::R_SPARC_GOT22: + Reloc::hi22(view, got_offset, addend); + break; +diff -rup ../binutils-2.27/gold/symtab.cc gold/symtab.cc +--- ../binutils-2.27/gold/symtab.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/symtab.cc 2016-11-03 15:05:49.000000000 +0000 +@@ -882,6 +882,7 @@ Symbol_table::define_default_version(Siz + ; + else if (pdef->second->is_from_dynobj() + && sym->is_from_dynobj() ++ && pdef->second->is_defined() + && pdef->second->object() != sym->object()) + ; + else +@@ -1325,6 +1326,9 @@ Symbol_table::add_from_relobj( + res = this->add_from_object(relobj, name, name_key, ver, ver_key, + is_default_version, *psym, st_shndx, + is_ordinary, orig_st_shndx); ++ ++ if (res == NULL) ++ continue; + + if (is_forced_local) + this->force_local(res); +@@ -1406,6 +1410,9 @@ Symbol_table::add_from_pluginobj( + is_default_version, *sym, st_shndx, + is_ordinary, st_shndx); + ++ if (res == NULL) ++ return NULL; ++ + if (is_forced_local) + this->force_local(res); + +@@ -1602,6 +1609,9 @@ Symbol_table::add_from_dynobj( + } + } + ++ if (res == NULL) ++ continue; ++ + // Note that it is possible that RES was overridden by an + // earlier object, in which case it can't be aliased here. + if (st_shndx != elfcpp::SHN_UNDEF +@@ -1640,7 +1650,6 @@ Symbol_table::add_from_incrobj( + + Stringpool::Key ver_key = 0; + bool is_default_version = false; +- bool is_forced_local = false; + + Stringpool::Key name_key; + name = this->namepool_.add(name, true, &name_key); +@@ -1650,9 +1659,6 @@ Symbol_table::add_from_incrobj( + is_default_version, *sym, st_shndx, + is_ordinary, st_shndx); + +- if (is_forced_local) +- this->force_local(res); +- + return res; + } + +diff -rup ../binutils-2.27/gold/tilegx.cc gold/tilegx.cc +--- ../binutils-2.27/gold/tilegx.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/tilegx.cc 2016-11-03 15:05:50.000000000 +0000 +@@ -4428,6 +4428,7 @@ Target_tilegx::Relocat + psymval = &symval; + always_apply_relocation = true; + addend = 0; ++ // Fall through. + + // when under PIC mode, these relocations are deferred to rtld + case elfcpp::R_TILEGX_IMM16_X0_HW0: +@@ -4618,6 +4619,7 @@ Target_tilegx::Relocat + got_type = GOT_TYPE_TLS_OFFSET; + have_got_offset = true; + } ++ // Fall through. + do_update_value: + if (have_got_offset) { + if (gsym != NULL) { +@@ -4647,10 +4649,8 @@ Target_tilegx::Relocat + } // else if (opt_t == tls::TLSOPT_TO_LE) + // both GD/IE are turned into LE, which + // is absolute relocation. +- // +- // | go through +- // | +- // V ++ // Fall through. ++ + // LE + // + // tp +diff -rup ../binutils-2.27/gold/x86_64.cc gold/x86_64.cc +--- ../binutils-2.27/gold/x86_64.cc 2016-08-03 08:36:53.000000000 +0100 ++++ gold/x86_64.cc 2016-11-03 15:05:52.000000000 +0000 +@@ -2361,7 +2361,7 @@ Target_x86_64::Scan::check_non_pic + && !gsym->is_undefined() + && !gsym->is_preemptible())) + return; +- /* Fall through. */ ++ // Fall through. + case elfcpp::R_X86_64_32: + // R_X86_64_32 is OK for x32. + if (size == 32 && r_type == elfcpp::R_X86_64_32) +@@ -3505,6 +3505,7 @@ Target_x86_64::Relocate::relocate( + if (this->skip_call_tls_get_addr_) + { + if ((r_type != elfcpp::R_X86_64_PLT32 ++ && r_type != elfcpp::R_X86_64_GOTPCREL + && r_type != elfcpp::R_X86_64_GOTPCRELX + && r_type != elfcpp::R_X86_64_PLT32_BND + && r_type != elfcpp::R_X86_64_PC32_BND +@@ -3514,6 +3515,7 @@ Target_x86_64::Relocate::relocate( + { + gold_error_at_location(relinfo, relnum, rela.get_r_offset(), + _("missing expected TLS relocation")); ++ this->skip_call_tls_get_addr_ = false; + } + else + { +diff -rup ../binutils-2.27/gold/yyscript.y gold/yyscript.y +--- ../binutils-2.27/gold/yyscript.y 2016-08-03 08:36:53.000000000 +0100 ++++ gold/yyscript.y 2016-11-03 15:05:59.000000000 +0000 +@@ -137,6 +137,7 @@ + %token FORCE_COMMON_ALLOCATION + %token GLOBAL /* global */ + %token GROUP ++%token HIDDEN + %token HLL + %token INCLUDE + %token INHIBIT_COMMON_ALLOCATION +@@ -864,6 +865,8 @@ assignment: + Expression_ptr e = script_exp_binary_bitwise_or(s, $3); + script_set_symbol(closure, $1.value, $1.length, e, 0, 0); + } ++ | HIDDEN '(' string '=' parse_exp ')' ++ { script_set_symbol(closure, $3.value, $3.length, $5, 0, 1); } + | PROVIDE '(' string '=' parse_exp ')' + { script_set_symbol(closure, $3.value, $3.length, $5, 1, 0); } + | PROVIDE_HIDDEN '(' string '=' parse_exp ')' diff --git a/binutils.spec b/binutils.spec index acd9502..4b06f24 100644 --- a/binutils.spec +++ b/binutils.spec @@ -43,7 +43,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.27 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -84,6 +84,8 @@ Patch16: binutils-2.27-monotonic-section-offsets.patch Patch17: binutils-2.27-arm-aarch64-default-relro.patch # Skip PR14918 linker test for ARM native targets. Patch18: binutils-2.27-skip-rp14918-test-for-arm.patch +# Fix GOLD for ARM/AARCh64. +Patch19: binutils-2.28-gold.patch Provides: bundled(libiberty) @@ -227,6 +229,7 @@ using libelf instead of BFD. %patch16 -p1 %patch17 -p1 %patch18 -p1 +%patch19 -p0 # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -592,6 +595,10 @@ exit 0 %endif # %{isnative} %changelog +* Fri Oct 04 2016 Nick Clifton 2.27-10 +- Fix GOLD for ARM and AARCH64 + (#1386126) + * Mon Sep 26 2016 Mark Pryor 2.27-9 - Fix invocation of /sbin/ldconfig when reinstalling binutils in order to prevent warnings from rpm.