From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com ([143.182.124.21]) by linuxtogo.org with esmtp (Exim 4.72) (envelope-from ) id 1THH8l-0003ve-Pf for openembedded-core@lists.openembedded.org; Thu, 27 Sep 2012 18:40:49 +0200 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga101.ch.intel.com with ESMTP; 27 Sep 2012 09:27:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.80,496,1344236400"; d="scan'208";a="149904568" Received: from unknown (HELO [10.255.13.173]) ([10.255.13.173]) by AZSMGA002.ch.intel.com with ESMTP; 27 Sep 2012 09:27:47 -0700 Message-ID: <50647E83.709@linux.intel.com> Date: Thu, 27 Sep 2012 09:27:47 -0700 From: Saul Wold User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120827 Thunderbird/15.0 MIME-Version: 1.0 To: Khem Raj References: <1348454777-20578-1-git-send-email-raj.khem@gmail.com> In-Reply-To: <1348454777-20578-1-git-send-email-raj.khem@gmail.com> Cc: openembedded-core@lists.openembedded.org Subject: Re: [PATCH] binutils-2.22: Disable recent gold backports from 2.22 branch X-BeenThere: openembedded-core@lists.openembedded.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Patches and discussions about the oe-core layer List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Sep 2012 16:40:49 -0000 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 09/23/2012 07:46 PM, Khem Raj wrote: > This patch has been causing some regressions on gold. > e.g. systemd based images segfault and uclibc based images > dont boot. There has been few other reports on the mailing > list. Considering this lets withdraw this patch. > > Signed-off-by: Khem Raj > --- > meta/recipes-devtools/binutils/binutils-2.22.inc | 3 +- > ...opy-from-mainline-to-binutils-2.22-branch.patch | 1944 -------------------- > 2 files changed, 1 insertion(+), 1946 deletions(-) > delete mode 100644 meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch > Merged into OE-Core Thanks Sau! > diff --git a/meta/recipes-devtools/binutils/binutils-2.22.inc b/meta/recipes-devtools/binutils/binutils-2.22.inc > index 42dc6b7..9697242 100644 > --- a/meta/recipes-devtools/binutils/binutils-2.22.inc > +++ b/meta/recipes-devtools/binutils/binutils-2.22.inc > @@ -1,4 +1,4 @@ > -PR = "r16" > +PR = "r17" > > LIC_FILES_CHKSUM="\ > file://src-release;endline=17;md5=4830a9ef968f3b18dd5e9f2c00db2d35\ > @@ -38,7 +38,6 @@ SRC_URI = "\ > file://0035-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \ > file://0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \ > file://0037-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \ > - file://0038-Copy-from-mainline-to-binutils-2.22-branch.patch \ > file://0039-emulparams-elf32bmip.sh-OTHER_SECTIONS-Put-.mdebug.-.patch \ > file://0052-gas.patch \ > file://0055-Remove-ABI_64_P-check-on-R_X86_64_PCXX.patch \ > diff --git a/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch b/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch > deleted file mode 100644 > index 453ef22..0000000 > --- a/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch > +++ /dev/null > @@ -1,1944 +0,0 @@ > -Upstream-Status: Backport > - > -From 624da0376264205e399bc14fe2fa7b6fa659d0ee Mon Sep 17 00:00:00 2001 > -From: Ian Lance Taylor > -Date: Mon, 19 Dec 2011 21:14:39 +0000 > -Subject: [PATCH 038/262] Copy from mainline to binutils 2.22 branch: > - > - 2011-12-17 Cary Coutant > - > - * dwarf_reader.cc (Sized_dwarf_line_info::read_lines): Add casts. > - * resolve.cc (Symbol_table::resolve): Likewise. > - * i386.cc (Target_i386::do_code_fill): Use char constants for nop > - arrays. > - * x86_64.cc (Target_x86_64::do_code_fill): Likewise. > - > - 2011-10-31 Cary Coutant > - > - PR gold/13023 > - * expression.cc (Expression::eval_with_dot): Add > - is_section_dot_assignment parameter. > - (Expression::eval_maybe_dot): Likewise. Adjust value when rhs is > - absolute and assigning to dot within a section. > - * script-sections.cc > - (Output_section_element_assignment::set_section_addresses): Pass > - dot_section to set_if_absolute. > - (Output_section_element_dot_assignment::finalize_symbols): Pass TRUE > - as is_section_dot_assignment flag to eval_with_dot. > - (Output_section_element_dot_assignment::set_section_addresses): > - Likewise. > - * script.cc (Symbol_assignment::set_if_absolute): Add dot_section > - parameter. Also set value if relative to dot_section; set the > - symbol's output_section. > - * script.h (Expression::eval_with_dot): Add is_section_dot_assignment > - parameter. Adjust all callers. > - (Expression::eval_maybe_dot): Likewise. > - (Symbol_assignment::set_if_absolute): Add dot_section parameter. > - Adjust all callers. > - * testsuite/script_test_2.t: Test assignment of an absolute value > - to dot within an output section element. > - > - 2011-10-31 Cary Coutant > - > - * options.h (class General_options): Add --[no-]gnu-unique options. > - * symtab.cc (Symbol_table::sized_write_globals): Convert > - STB_GNU_UNIQUE to STB_GLOBAL if --no-gnu-unique. > - > - 2011-10-31 Cary Coutant > - > - PR gold/13359 > - * i386.cc (Target_i386::Relocate::relocate_tls): Remove > - unnecessary assertion. > - * x86_64.cc (Target_x86_64::Relocate::relocate_tls): Likewise. > - > - 2011-10-31 Sriraman Tallam > - > - * symtab.h (Symbol_table::gc_mark_symbol_for_shlib): Rename to > - gc_mark_symbol. > - * symtab.cc (Symbol_table::gc_mark_symbol_for_shlib): Rename to > - gc_mark_symbol. > - Change to just keep the section associated with symbol. > - (Symbol_table::add_from_relobj): Mark symbols as not garbage when > - they are externally visible and --export-dynamic is turned on. > - (Symbol_table::gc_mark_dyn_syms): Call gc_mark_symbol. > - > - 2011-10-19 Ian Lance Taylor > - > - PR gold/13163 > - * script-sections.cc > - (Output_section_element_dot_assignment::needs_output_section): New > - function. > - > - 2011-10-19 Ian Lance Taylor > - > - PR gold/13204 > - * layout.cc (Layout::segment_precedes): Don't assert failure if a > - --section-start option was seen. > - * options.h (General_options::any_section_start): New function. > - > - 2011-10-18 Cary Coutant > - > - * output.cc (posix_fallocate): Return 0 on success, errno on failure. > - (Output_file::map_no_anonymous): Check for non-zero > - return code from posix_fallocate. > - > - 2011-10-17 Cary Coutant > - > - PR gold/13245 > - * plugin.cc (is_visible_from_outside): Check for symbols > - referenced from dynamic objects. > - * resolve.cc (Symbol_table::resolve): Don't count references > - from dynamic objects as references from real ELF files. > - * testsuite/plugin_test_2.sh: Adjust expected result. > - > - 2011-10-17 Cary Coutant > - > - * readsyms.cc (Read_symbols::run): Don't queue an unblocker > - task for members of lib groups. > - > - 2011-10-17 Cary Coutant > - > - PR gold/13288 > - * fileread.cc (File_read::find_view): Add assert. > - (File_read::make_view): Move bounds check (replace with assert)... > - (File_read::find_or_make_view): ... to here. > - > - 2011-10-12 Cary Coutant > - > - * output.cc (Output_file::open_base_file): Handle case where > - ::read returns less than requested size. > - > - 2011-10-10 Cary Coutant > - > - * incremental.cc (Sized_relobj_incr::Sized_relobj_incr): > - Initialize defined_count_. > - (Sized_relobj_incr::do_add_symbols): Count defined symbols. > - (Sized_relobj_incr::do_get_global_symbol_counts): Rewrite. > - (Sized_incr_dynobj::Sized_incr_dynobj): Initialize defined_count_. > - (Sized_incr_dynobj::do_add_symbols): Count defined symbols. > - (Sized_incr_dynobj::do_get_global_symbol_counts): Rewrite. > - * incremental.h (Sized_relobj_incr::defined_count_): New data > - member. > - (Sized_incr_dynobj::defined_count_): New data member. > - * plugin.cc (Sized_pluginobj::do_get_global_symbol_counts): > - Return zeroes instead of internal error. > - > - 2011-10-10 Cary Coutant > - > - PR gold/13249 > - * output.cc (Output_reloc::Output_reloc): Add use_plt_offset flag. > - (Output_reloc::symbol_value): Return PLT offset if flag is set. > - * output.h (class Output_reloc): Add use_plt_offset flag. > - (Output_reloc::type_): Adjust size of bit field. > - (Output_reloc::use_plt_offset_): New bit field. > - (class Output_data_reloc): Adjust all calls to Output_reloc_type. > - (Output_data_reloc::add_local_relative): (RELA only) Add use_plt_offset > - flag. Adjust all callers. > - * x86_64.cc (Target_x86_64::Scan::local): Check for IFUNC when > - creating RELATIVE relocations. > - > - 2011-10-03 Diego Novillo > - > - * options.cc (parse_uint): Fix dereference of RETVAL. > - > - 2011-09-29 Cary Coutant > - > - * incremental.cc (Sized_incremental_binary::do_process_got_plt): > - Check for NULL. > - * symtab.cc (Symbol_table::add_from_relobj): Ignore version > - symbols during incremental update. > - (Symbol_table::add_from_dynobj): Likewise. > - > - 2011-09-26 Cary Coutant > - > - * gold.cc (queue_initial_tasks): Move option checks ... > - * options.cc (General_options::finalize): ... to here. Disable > - some options; make others fatal. > - > - 2011-09-23 Simon Baldwin > - > - * configure.ac: Add new --with-gold-ldadd and --with-gold-ldflags > - configuration options. > - * configure: Regenerate. > - * Makefile.am: Handle GOLD_LDADD and GOLD_LDFLAGS. > - * Makefile.in: Regenerate. > - * testsuite/Makefile.in: Regenerate. > ---- > - gold/ChangeLog | 163 +++++++++++++++++++++++++++++++++++++++ > - gold/dwarf_reader.cc | 8 +- > - gold/expression.cc | 45 +++++++---- > - gold/fileread.cc | 27 ++++--- > - gold/gold.cc | 55 +++++-------- > - gold/i386.cc | 87 +++++++++++---------- > - gold/incremental.cc | 50 +++++++++--- > - gold/incremental.h | 4 + > - gold/layout.cc | 5 +- > - gold/options.cc | 33 +++++++- > - gold/options.h | 9 +++ > - gold/output.cc | 78 ++++++++++++------- > - gold/output.h | 64 +++++++++------ > - gold/plugin.cc | 18 +++-- > - gold/powerpc.cc | 4 +- > - gold/readsyms.cc | 6 +- > - gold/resolve.cc | 6 +- > - gold/script-sections.cc | 47 +++++++---- > - gold/script.cc | 17 ++-- > - gold/script.h | 24 ++++-- > - gold/sparc.cc | 4 +- > - gold/symtab.cc | 65 +++++++++------- > - gold/symtab.h | 5 +- > - gold/testsuite/Makefile.in | 2 + > - gold/testsuite/plugin_test_2.sh | 2 +- > - gold/testsuite/script_test_2.t | 2 +- > - gold/x86_64.cc | 99 ++++++++++++------------ > - 27 files changed, 636 insertions(+), 293 deletions(-) > - > -diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc > -index 3dc33e4..2b47a28 100644 > ---- a/gold/dwarf_reader.cc > -+++ b/gold/dwarf_reader.cc > -@@ -1,6 +1,6 @@ > - // dwarf_reader.cc -- parse dwarf2/3 debug information > - > --// Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc. > -+// Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. > - // Written by Ian Lance Taylor . > - > - // This file is part of gold. > -@@ -491,8 +491,10 @@ Sized_dwarf_line_info::read_lines(unsigned const char* lineptr > - && (shndx == -1U || lsm.shndx == -1U || shndx == lsm.shndx)) > - { > - Offset_to_lineno_entry entry > -- = { lsm.address, this->current_header_index_, > -- lsm.file_num, true, lsm.line_num }; > -+ = { static_cast(lsm.address), > -+ this->current_header_index_, > -+ static_cast(lsm.file_num), > -+ true, lsm.line_num }; > - std::vector& > - map(this->line_number_map_[lsm.shndx]); > - // If we see two consecutive entries with the same > -diff --git a/gold/expression.cc b/gold/expression.cc > -index e527b5e..e31c151 100644 > ---- a/gold/expression.cc > -+++ b/gold/expression.cc > -@@ -1,6 +1,6 @@ > - // expression.cc -- expressions in linker scripts for gold > - > --// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. > -+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. > - // Written by Ian Lance Taylor . > - > - // This file is part of gold. > -@@ -77,7 +77,7 @@ Expression::eval(const Symbol_table* symtab, const Layout* layout, > - bool check_assertions) > - { > - return this->eval_maybe_dot(symtab, layout, check_assertions, > -- false, 0, NULL, NULL, NULL); > -+ false, 0, NULL, NULL, NULL, false); > - } > - > - // Evaluate an expression which may refer to the dot symbol. > -@@ -87,11 +87,13 @@ Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout, > - bool check_assertions, uint64_t dot_value, > - Output_section* dot_section, > - Output_section** result_section_pointer, > -- uint64_t* result_alignment_pointer) > -+ uint64_t* result_alignment_pointer, > -+ bool is_section_dot_assignment) > - { > - return this->eval_maybe_dot(symtab, layout, check_assertions, true, > - dot_value, dot_section, result_section_pointer, > -- result_alignment_pointer); > -+ result_alignment_pointer, > -+ is_section_dot_assignment); > - } > - > - // Evaluate an expression which may or may not refer to the dot > -@@ -102,7 +104,8 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout, > - bool check_assertions, bool is_dot_available, > - uint64_t dot_value, Output_section* dot_section, > - Output_section** result_section_pointer, > -- uint64_t* result_alignment_pointer) > -+ uint64_t* result_alignment_pointer, > -+ bool is_section_dot_assignment) > - { > - Expression_eval_info eei; > - eei.symtab = symtab; > -@@ -113,14 +116,24 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout, > - eei.dot_section = dot_section; > - > - // We assume the value is absolute, and only set this to a section > -- // if we find a section relative reference. > -+ // if we find a section-relative reference. > - if (result_section_pointer != NULL) > - *result_section_pointer = NULL; > - eei.result_section_pointer = result_section_pointer; > - > - eei.result_alignment_pointer = result_alignment_pointer; > - > -- return this->value(&eei); > -+ uint64_t val = this->value(&eei); > -+ > -+ // If this is an assignment to dot within a section, and the value > -+ // is absolute, treat it as a section-relative offset. > -+ if (is_section_dot_assignment && *result_section_pointer == NULL) > -+ { > -+ gold_assert(dot_section != NULL); > -+ val += dot_section->address(); > -+ *result_section_pointer = dot_section; > -+ } > -+ return val; > - } > - > - // A number. > -@@ -257,7 +270,8 @@ class Unary_expression : public Expression > - eei->dot_value, > - eei->dot_section, > - arg_section_pointer, > -- eei->result_alignment_pointer); > -+ eei->result_alignment_pointer, > -+ false); > - } > - > - void > -@@ -336,7 +350,8 @@ class Binary_expression : public Expression > - eei->dot_value, > - eei->dot_section, > - section_pointer, > -- alignment_pointer); > -+ alignment_pointer, > -+ false); > - } > - > - uint64_t > -@@ -350,7 +365,8 @@ class Binary_expression : public Expression > - eei->dot_value, > - eei->dot_section, > - section_pointer, > -- alignment_pointer); > -+ alignment_pointer, > -+ false); > - } > - > - void > -@@ -500,7 +516,8 @@ class Trinary_expression : public Expression > - eei->dot_value, > - eei->dot_section, > - section_pointer, > -- NULL); > -+ NULL, > -+ false); > - } > - > - uint64_t > -@@ -514,7 +531,8 @@ class Trinary_expression : public Expression > - eei->dot_value, > - eei->dot_section, > - section_pointer, > -- alignment_pointer); > -+ alignment_pointer, > -+ false); > - } > - > - uint64_t > -@@ -528,7 +546,8 @@ class Trinary_expression : public Expression > - eei->dot_value, > - eei->dot_section, > - section_pointer, > -- alignment_pointer); > -+ alignment_pointer, > -+ false); > - } > - > - void > -diff --git a/gold/fileread.cc b/gold/fileread.cc > -index 80ddfbc..c5dc320 100644 > ---- a/gold/fileread.cc > -+++ b/gold/fileread.cc > -@@ -329,6 +329,10 @@ inline File_read::View* > - File_read::find_view(off_t start, section_size_type size, > - unsigned int byteshift, File_read::View** vshifted) const > - { > -+ gold_assert(start <= this->size_ > -+ && (static_cast(size) > -+ <= static_cast(this->size_ - start))); > -+ > - if (vshifted != NULL) > - *vshifted = NULL; > - > -@@ -456,16 +460,9 @@ File_read::make_view(off_t start, section_size_type size, > - unsigned int byteshift, bool cache) > - { > - gold_assert(size > 0); > -- > -- // Check that start and end of the view are within the file. > -- if (start > this->size_ > -- || (static_cast(size) > -- > static_cast(this->size_ - start))) > -- gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds " > -- "size of file; the file may be corrupt"), > -- this->filename().c_str(), > -- static_cast(size), > -- static_cast(start)); > -+ gold_assert(start <= this->size_ > -+ && (static_cast(size) > -+ <= static_cast(this->size_ - start))); > - > - off_t poff = File_read::page_offset(start); > - > -@@ -523,6 +520,16 @@ File_read::View* > - File_read::find_or_make_view(off_t offset, off_t start, > - section_size_type size, bool aligned, bool cache) > - { > -+ // Check that start and end of the view are within the file. > -+ if (start > this->size_ > -+ || (static_cast(size) > -+ > static_cast(this->size_ - start))) > -+ gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds " > -+ "size of file; the file may be corrupt"), > -+ this->filename().c_str(), > -+ static_cast(size), > -+ static_cast(start)); > -+ > - unsigned int byteshift; > - if (offset == 0) > - byteshift = 0; > -diff --git a/gold/gold.cc b/gold/gold.cc > -index 12f25b7..693ff79 100644 > ---- a/gold/gold.cc > -+++ b/gold/gold.cc > -@@ -197,46 +197,29 @@ queue_initial_tasks(const General_options& options, > - // For incremental links, the base output file. > - Incremental_binary* ibase = NULL; > - > -- if (parameters->incremental()) > -- { > -- if (options.relocatable()) > -- gold_error(_("incremental linking is incompatible with -r")); > -- if (options.emit_relocs()) > -- gold_error(_("incremental linking is incompatible with --emit-relocs")); > -- if (options.gc_sections()) > -- gold_error(_("incremental linking is incompatible with --gc-sections")); > -- if (options.icf_enabled()) > -- gold_error(_("incremental linking is incompatible with --icf")); > -- if (options.has_plugins()) > -- gold_error(_("incremental linking is incompatible with --plugin")); > -- if (strcmp(options.compress_debug_sections(), "none") != 0) > -- gold_error(_("incremental linking is incompatible with " > -- "--compress-debug-sections")); > -- > -- if (parameters->incremental_update()) > -+ if (parameters->incremental_update()) > -+ { > -+ Output_file* of = new Output_file(options.output_file_name()); > -+ if (of->open_base_file(options.incremental_base(), true)) > - { > -- Output_file* of = new Output_file(options.output_file_name()); > -- if (of->open_base_file(options.incremental_base(), true)) > -- { > -- ibase = open_incremental_binary(of); > -- if (ibase != NULL > -- && ibase->check_inputs(cmdline, layout->incremental_inputs())) > -- ibase->init_layout(layout); > -- else > -- { > -- delete ibase; > -- ibase = NULL; > -- of->close(); > -- } > -- } > -- if (ibase == NULL) > -+ ibase = open_incremental_binary(of); > -+ if (ibase != NULL > -+ && ibase->check_inputs(cmdline, layout->incremental_inputs())) > -+ ibase->init_layout(layout); > -+ else > - { > -- if (set_parameters_incremental_full()) > -- gold_info(_("linking with --incremental-full")); > -- else > -- gold_fallback(_("restart link with --incremental-full")); > -+ delete ibase; > -+ ibase = NULL; > -+ of->close(); > - } > - } > -+ if (ibase == NULL) > -+ { > -+ if (set_parameters_incremental_full()) > -+ gold_info(_("linking with --incremental-full")); > -+ else > -+ gold_fallback(_("restart link with --incremental-full")); > -+ } > - } > - > - // Read the input files. We have to add the symbols to the symbol > -diff --git a/gold/i386.cc b/gold/i386.cc > -index 445bc68..efb6248 100644 > ---- a/gold/i386.cc > -+++ b/gold/i386.cc > -@@ -2709,12 +2709,6 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, > - } > - if (optimized_type == tls::TLSOPT_TO_IE) > - { > -- if (tls_segment == NULL) > -- { > -- gold_assert(parameters->errors()->error_count() > 0 > -- || issue_undefined_symbol_error(gsym)); > -- return; > -- } > - this->tls_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type, > - got_offset, view, view_size); > - break; > -@@ -3480,42 +3474,51 @@ Target_i386::do_code_fill(section_size_type length) const > - } > - > - // Nop sequences of various lengths. > -- const char nop1[1] = { 0x90 }; // nop > -- const char nop2[2] = { 0x66, 0x90 }; // xchg %ax %ax > -- const char nop3[3] = { 0x8d, 0x76, 0x00 }; // leal 0(%esi),%esi > -- const char nop4[4] = { 0x8d, 0x74, 0x26, 0x00}; // leal 0(%esi,1),%esi > -- const char nop5[5] = { 0x90, 0x8d, 0x74, 0x26, // nop > -- 0x00 }; // leal 0(%esi,1),%esi > -- const char nop6[6] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi > -- 0x00, 0x00 }; > -- const char nop7[7] = { 0x8d, 0xb4, 0x26, 0x00, // leal 0L(%esi,1),%esi > -- 0x00, 0x00, 0x00 }; > -- const char nop8[8] = { 0x90, 0x8d, 0xb4, 0x26, // nop > -- 0x00, 0x00, 0x00, 0x00 }; // leal 0L(%esi,1),%esi > -- const char nop9[9] = { 0x89, 0xf6, 0x8d, 0xbc, // movl %esi,%esi > -- 0x27, 0x00, 0x00, 0x00, // leal 0L(%edi,1),%edi > -- 0x00 }; > -- const char nop10[10] = { 0x8d, 0x76, 0x00, 0x8d, // leal 0(%esi),%esi > -- 0xbc, 0x27, 0x00, 0x00, // leal 0L(%edi,1),%edi > -- 0x00, 0x00 }; > -- const char nop11[11] = { 0x8d, 0x74, 0x26, 0x00, // leal 0(%esi,1),%esi > -- 0x8d, 0xbc, 0x27, 0x00, // leal 0L(%edi,1),%edi > -- 0x00, 0x00, 0x00 }; > -- const char nop12[12] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi > -- 0x00, 0x00, 0x8d, 0xbf, // leal 0L(%edi),%edi > -- 0x00, 0x00, 0x00, 0x00 }; > -- const char nop13[13] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi > -- 0x00, 0x00, 0x8d, 0xbc, // leal 0L(%edi,1),%edi > -- 0x27, 0x00, 0x00, 0x00, > -- 0x00 }; > -- const char nop14[14] = { 0x8d, 0xb4, 0x26, 0x00, // leal 0L(%esi,1),%esi > -- 0x00, 0x00, 0x00, 0x8d, // leal 0L(%edi,1),%edi > -- 0xbc, 0x27, 0x00, 0x00, > -- 0x00, 0x00 }; > -- const char nop15[15] = { 0xeb, 0x0d, 0x90, 0x90, // jmp .+15 > -- 0x90, 0x90, 0x90, 0x90, // nop,nop,nop,... > -- 0x90, 0x90, 0x90, 0x90, > -- 0x90, 0x90, 0x90 }; > -+ const char nop1[1] = { '\x90' }; // nop > -+ const char nop2[2] = { '\x66', '\x90' }; // xchg %ax %ax > -+ const char nop3[3] = { '\x8d', '\x76', '\x00' }; // leal 0(%esi),%esi > -+ const char nop4[4] = { '\x8d', '\x74', '\x26', // leal 0(%esi,1),%esi > -+ '\x00'}; > -+ const char nop5[5] = { '\x90', '\x8d', '\x74', // nop > -+ '\x26', '\x00' }; // leal 0(%esi,1),%esi > -+ const char nop6[6] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi > -+ '\x00', '\x00', '\x00' }; > -+ const char nop7[7] = { '\x8d', '\xb4', '\x26', // leal 0L(%esi,1),%esi > -+ '\x00', '\x00', '\x00', > -+ '\x00' }; > -+ const char nop8[8] = { '\x90', '\x8d', '\xb4', // nop > -+ '\x26', '\x00', '\x00', // leal 0L(%esi,1),%esi > -+ '\x00', '\x00' }; > -+ const char nop9[9] = { '\x89', '\xf6', '\x8d', // movl %esi,%esi > -+ '\xbc', '\x27', '\x00', // leal 0L(%edi,1),%edi > -+ '\x00', '\x00', '\x00' }; > -+ const char nop10[10] = { '\x8d', '\x76', '\x00', // leal 0(%esi),%esi > -+ '\x8d', '\xbc', '\x27', // leal 0L(%edi,1),%edi > -+ '\x00', '\x00', '\x00', > -+ '\x00' }; > -+ const char nop11[11] = { '\x8d', '\x74', '\x26', // leal 0(%esi,1),%esi > -+ '\x00', '\x8d', '\xbc', // leal 0L(%edi,1),%edi > -+ '\x27', '\x00', '\x00', > -+ '\x00', '\x00' }; > -+ const char nop12[12] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi > -+ '\x00', '\x00', '\x00', // leal 0L(%edi),%edi > -+ '\x8d', '\xbf', '\x00', > -+ '\x00', '\x00', '\x00' }; > -+ const char nop13[13] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi > -+ '\x00', '\x00', '\x00', // leal 0L(%edi,1),%edi > -+ '\x8d', '\xbc', '\x27', > -+ '\x00', '\x00', '\x00', > -+ '\x00' }; > -+ const char nop14[14] = { '\x8d', '\xb4', '\x26', // leal 0L(%esi,1),%esi > -+ '\x00', '\x00', '\x00', // leal 0L(%edi,1),%edi > -+ '\x00', '\x8d', '\xbc', > -+ '\x27', '\x00', '\x00', > -+ '\x00', '\x00' }; > -+ const char nop15[15] = { '\xeb', '\x0d', '\x90', // jmp .+15 > -+ '\x90', '\x90', '\x90', // nop,nop,nop,... > -+ '\x90', '\x90', '\x90', > -+ '\x90', '\x90', '\x90', > -+ '\x90', '\x90', '\x90' }; > - > - const char* nops[16] = { > - NULL, > -diff --git a/gold/incremental.cc b/gold/incremental.cc > -index b422827..75e44c5 100644 > ---- a/gold/incremental.cc > -+++ b/gold/incremental.cc > -@@ -685,7 +685,7 @@ Sized_incremental_binary::do_process_got_plt( > - gold_assert(plt_desc >= first_global && plt_desc < symtab_count); > - Symbol* sym = this->global_symbol(plt_desc - first_global); > - // Add the PLT entry only if the symbol is still referenced. > -- if (sym->in_reg()) > -+ if (sym != NULL && sym->in_reg()) > - { > - gold_debug(DEBUG_INCREMENTAL, > - "PLT entry %d: %s", > -@@ -1966,8 +1966,9 @@ Sized_relobj_incr::Sized_relobj_incr( > - input_reader_(ibase->inputs_reader().input_file(input_file_index)), > - local_symbol_count_(0), output_local_dynsym_count_(0), > - local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0), > -- symbols_(), incr_reloc_offset_(-1U), incr_reloc_count_(0), > -- incr_reloc_output_index_(0), incr_relocs_(NULL), local_symbols_() > -+ symbols_(), defined_count_(0), incr_reloc_offset_(-1U), > -+ incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL), > -+ local_symbols_() > - { > - if (this->input_reader_.is_in_system_directory()) > - this->set_is_in_system_directory(); > -@@ -2120,6 +2121,9 @@ Sized_relobj_incr::do_add_symbols( > - > - Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym); > - > -+ if (shndx != elfcpp::SHN_UNDEF) > -+ ++this->defined_count_; > -+ > - // If this is a linker-defined symbol that hasn't yet been defined, > - // define it now. > - if (input_shndx == -1U && !res->is_defined()) > -@@ -2283,9 +2287,21 @@ Sized_relobj_incr::do_initialize_xindex() > - template > - void > - Sized_relobj_incr::do_get_global_symbol_counts( > -- const Symbol_table*, size_t*, size_t*) const > --{ > -- gold_unreachable(); > -+ const Symbol_table*, > -+ size_t* defined, > -+ size_t* used) const > -+{ > -+ *defined = this->defined_count_; > -+ size_t count = 0; > -+ for (typename Symbols::const_iterator p = this->symbols_.begin(); > -+ p != this->symbols_.end(); > -+ ++p) > -+ if (*p != NULL > -+ && (*p)->source() == Symbol::FROM_OBJECT > -+ && (*p)->object() == this > -+ && (*p)->is_defined()) > -+ ++count; > -+ *used = count; > - } > - > - // Read the relocs. > -@@ -2579,7 +2595,7 @@ Sized_incr_dynobj::Sized_incr_dynobj( > - : Dynobj(name, NULL), ibase_(ibase), > - input_file_index_(input_file_index), > - input_reader_(ibase->inputs_reader().input_file(input_file_index)), > -- symbols_() > -+ symbols_(), defined_count_(0) > - { > - if (this->input_reader_.is_in_system_directory()) > - this->set_is_in_system_directory(); > -@@ -2677,6 +2693,7 @@ Sized_incr_dynobj::do_add_symbols( > - // is meaningless, as long as it's not SHN_UNDEF. > - shndx = 1; > - v = gsym.get_st_value(); > -+ ++this->defined_count_; > - } > - > - osym.put_st_name(0); > -@@ -2845,9 +2862,22 @@ Sized_incr_dynobj::do_initialize_xindex() > - template > - void > - Sized_incr_dynobj::do_get_global_symbol_counts( > -- const Symbol_table*, size_t*, size_t*) const > --{ > -- gold_unreachable(); > -+ const Symbol_table*, > -+ size_t* defined, > -+ size_t* used) const > -+{ > -+ *defined = this->defined_count_; > -+ size_t count = 0; > -+ for (typename Symbols::const_iterator p = this->symbols_.begin(); > -+ p != this->symbols_.end(); > -+ ++p) > -+ if (*p != NULL > -+ && (*p)->source() == Symbol::FROM_OBJECT > -+ && (*p)->object() == this > -+ && (*p)->is_defined() > -+ && (*p)->dynsym_index() != -1U) > -+ ++count; > -+ *used = count; > - } > - > - // Allocate an incremental object of the appropriate size and endianness. > -diff --git a/gold/incremental.h b/gold/incremental.h > -index e6732df..56fc52b 100644 > ---- a/gold/incremental.h > -+++ b/gold/incremental.h > -@@ -1996,6 +1996,8 @@ class Sized_relobj_incr : public Sized_relobj > - unsigned int local_dynsym_offset_; > - // The entries in the symbol table for the external symbols. > - Symbols symbols_; > -+ // Number of symbols defined in object file itself. > -+ size_t defined_count_; > - // The offset of the first incremental relocation for this object. > - unsigned int incr_reloc_offset_; > - // The number of incremental relocations for this object. > -@@ -2127,6 +2129,8 @@ class Sized_incr_dynobj : public Dynobj > - Input_entry_reader input_reader_; > - // The entries in the symbol table for the external symbols. > - Symbols symbols_; > -+ // Number of symbols defined in object file itself. > -+ size_t defined_count_; > - }; > - > - // Allocate an incremental object of the appropriate size and endianness. > -diff --git a/gold/layout.cc b/gold/layout.cc > -index 1c32bcf..9d8a43a 100644 > ---- a/gold/layout.cc > -+++ b/gold/layout.cc > -@@ -2975,8 +2975,9 @@ Layout::segment_precedes(const Output_segment* seg1, > - > - // We shouldn't get here--we shouldn't create segments which we > - // can't distinguish. Unless of course we are using a weird linker > -- // script. > -- gold_assert(this->script_options_->saw_phdrs_clause()); > -+ // script or overlapping --section-start options. > -+ gold_assert(this->script_options_->saw_phdrs_clause() > -+ || parameters->options().any_section_start()); > - return false; > - } > - > -diff --git a/gold/options.cc b/gold/options.cc > -index be32645..dcf6ba7 100644 > ---- a/gold/options.cc > -+++ b/gold/options.cc > -@@ -198,7 +198,7 @@ parse_uint(const char* option_name, const char* arg, int* retval) > - { > - char* endptr; > - *retval = strtol(arg, &endptr, 0); > -- if (*endptr != '\0' || retval < 0) > -+ if (*endptr != '\0' || *retval < 0) > - gold_fatal(_("%s: invalid option value (expected an integer): %s"), > - option_name, arg); > - } > -@@ -1224,6 +1224,37 @@ General_options::finalize() > - gold_fatal(_("Options --incremental-changed, --incremental-unchanged, " > - "--incremental-unknown require the use of --incremental")); > - > -+ // Check for options that are not compatible with incremental linking. > -+ // Where an option can be disabled without seriously changing the semantics > -+ // of the link, we turn the option off; otherwise, we issue a fatal error. > -+ > -+ if (this->incremental_mode_ != INCREMENTAL_OFF) > -+ { > -+ if (this->relocatable()) > -+ gold_fatal(_("incremental linking is not compatible with -r")); > -+ if (this->emit_relocs()) > -+ gold_fatal(_("incremental linking is not compatible with " > -+ "--emit-relocs")); > -+ if (this->has_plugins()) > -+ gold_fatal(_("incremental linking is not compatible with --plugin")); > -+ if (this->gc_sections()) > -+ { > -+ gold_warning(_("ignoring --gc-sections for an incremental link")); > -+ this->set_gc_sections(false); > -+ } > -+ if (this->icf_enabled()) > -+ { > -+ gold_warning(_("ignoring --icf for an incremental link")); > -+ this->set_icf_status(ICF_NONE); > -+ } > -+ if (strcmp(this->compress_debug_sections(), "none") != 0) > -+ { > -+ gold_warning(_("ignoring --compress-debug-sections for an " > -+ "incremental link")); > -+ this->set_compress_debug_sections("none"); > -+ } > -+ } > -+ > - // FIXME: we can/should be doing a lot more sanity checking here. > - } > - > -diff --git a/gold/options.h b/gold/options.h > -index 768df9c..8876a1e 100644 > ---- a/gold/options.h > -+++ b/gold/options.h > -@@ -791,6 +791,10 @@ class General_options > - DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false, > - N_("Ignored"), NULL); > - > -+ DEFINE_bool(gnu_unique, options::TWO_DASHES, '\0', true, > -+ N_("Enable STB_GNU_UNIQUE symbol binding (default)"), > -+ N_("Disable STB_GNU_UNIQUE symbol binding")); > -+ > - DEFINE_string(soname, options::ONE_DASH, 'h', NULL, > - N_("Set shared library name"), N_("FILENAME")); > - > -@@ -1385,6 +1389,11 @@ class General_options > - bool > - section_start(const char* secname, uint64_t* paddr) const; > - > -+ // Return whether any --section-start option was used. > -+ bool > -+ any_section_start() const > -+ { return !this->section_starts_.empty(); } > -+ > - enum Fix_v4bx > - { > - // Leave original instruction. > -diff --git a/gold/output.cc b/gold/output.cc > -index 29d8e3d..a7e1e9a 100644 > ---- a/gold/output.cc > -+++ b/gold/output.cc > -@@ -119,7 +119,9 @@ extern "C" void *gold_mremap(void *, size_t, size_t, int); > - static int > - posix_fallocate(int o, off_t offset, off_t len) > - { > -- return ftruncate(o, offset + len); > -+ if (ftruncate(o, offset + len) < 0) > -+ return errno; > -+ return 0; > - } > - #endif // !defined(HAVE_POSIX_FALLOCATE) > - > -@@ -706,7 +708,7 @@ Output_reloc::Output_reloc( > - bool is_symbolless) > - : address_(address), local_sym_index_(GSYM_CODE), type_(type), > - is_relative_(is_relative), is_symbolless_(is_symbolless), > -- is_section_symbol_(false), shndx_(INVALID_CODE) > -+ is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE) > - { > - // this->type_ is a bitfield; make sure TYPE fits. > - gold_assert(this->type_ == type); > -@@ -727,7 +729,7 @@ Output_reloc::Output_reloc( > - bool is_symbolless) > - : address_(address), local_sym_index_(GSYM_CODE), type_(type), > - is_relative_(is_relative), is_symbolless_(is_symbolless), > -- is_section_symbol_(false), shndx_(shndx) > -+ is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx) > - { > - gold_assert(shndx != INVALID_CODE); > - // this->type_ is a bitfield; make sure TYPE fits. > -@@ -749,10 +751,12 @@ Output_reloc::Output_reloc( > - Address address, > - bool is_relative, > - bool is_symbolless, > -- bool is_section_symbol) > -+ bool is_section_symbol, > -+ bool use_plt_offset) > - : address_(address), local_sym_index_(local_sym_index), type_(type), > - is_relative_(is_relative), is_symbolless_(is_symbolless), > -- is_section_symbol_(is_section_symbol), shndx_(INVALID_CODE) > -+ is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset), > -+ shndx_(INVALID_CODE) > - { > - gold_assert(local_sym_index != GSYM_CODE > - && local_sym_index != INVALID_CODE); > -@@ -773,10 +777,12 @@ Output_reloc::Output_reloc( > - Address address, > - bool is_relative, > - bool is_symbolless, > -- bool is_section_symbol) > -+ bool is_section_symbol, > -+ bool use_plt_offset) > - : address_(address), local_sym_index_(local_sym_index), type_(type), > - is_relative_(is_relative), is_symbolless_(is_symbolless), > -- is_section_symbol_(is_section_symbol), shndx_(shndx) > -+ is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset), > -+ shndx_(shndx) > - { > - gold_assert(local_sym_index != GSYM_CODE > - && local_sym_index != INVALID_CODE); > -@@ -799,7 +805,7 @@ Output_reloc::Output_reloc( > - Address address) > - : address_(address), local_sym_index_(SECTION_CODE), type_(type), > - is_relative_(false), is_symbolless_(false), > -- is_section_symbol_(true), shndx_(INVALID_CODE) > -+ is_section_symbol_(true), use_plt_offset_(false), shndx_(INVALID_CODE) > - { > - // this->type_ is a bitfield; make sure TYPE fits. > - gold_assert(this->type_ == type); > -@@ -820,7 +826,7 @@ Output_reloc::Output_reloc( > - Address address) > - : address_(address), local_sym_index_(SECTION_CODE), type_(type), > - is_relative_(false), is_symbolless_(false), > -- is_section_symbol_(true), shndx_(shndx) > -+ is_section_symbol_(true), use_plt_offset_(false), shndx_(shndx) > - { > - gold_assert(shndx != INVALID_CODE); > - // this->type_ is a bitfield; make sure TYPE fits. > -@@ -842,7 +848,7 @@ Output_reloc::Output_reloc( > - Address address) > - : address_(address), local_sym_index_(0), type_(type), > - is_relative_(false), is_symbolless_(false), > -- is_section_symbol_(false), shndx_(INVALID_CODE) > -+ is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE) > - { > - // this->type_ is a bitfield; make sure TYPE fits. > - gold_assert(this->type_ == type); > -@@ -858,7 +864,7 @@ Output_reloc::Output_reloc( > - Address address) > - : address_(address), local_sym_index_(0), type_(type), > - is_relative_(false), is_symbolless_(false), > -- is_section_symbol_(false), shndx_(shndx) > -+ is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx) > - { > - gold_assert(shndx != INVALID_CODE); > - // this->type_ is a bitfield; make sure TYPE fits. > -@@ -877,7 +883,7 @@ Output_reloc::Output_reloc( > - Address address) > - : address_(address), local_sym_index_(TARGET_CODE), type_(type), > - is_relative_(false), is_symbolless_(false), > -- is_section_symbol_(false), shndx_(INVALID_CODE) > -+ is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE) > - { > - // this->type_ is a bitfield; make sure TYPE fits. > - gold_assert(this->type_ == type); > -@@ -894,7 +900,7 @@ Output_reloc::Output_reloc( > - Address address) > - : address_(address), local_sym_index_(TARGET_CODE), type_(type), > - is_relative_(false), is_symbolless_(false), > -- is_section_symbol_(false), shndx_(shndx) > -+ is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx) > - { > - gold_assert(shndx != INVALID_CODE); > - // this->type_ is a bitfield; make sure TYPE fits. > -@@ -1121,6 +1127,12 @@ Output_reloc::symbol_value( > - Sized_relobj_file* relobj = > - this->u1_.relobj->sized_relobj(); > - gold_assert(relobj != NULL); > -+ if (this->use_plt_offset_) > -+ { > -+ uint64_t plt_address = > -+ parameters->target().plt_address_for_local(relobj, lsi); > -+ return plt_address + relobj->local_plt_offset(lsi); > -+ } > - const Symbol_value* symval = relobj->local_symbol(lsi); > - return symval->value(relobj, addend); > - } > -@@ -4880,17 +4892,27 @@ Output_file::open_base_file(const char* base_name, bool writable) > - if (use_base_file) > - { > - this->open(s.st_size); > -- ssize_t len = ::read(o, this->base_, s.st_size); > -- if (len < 0) > -- { > -- gold_info(_("%s: read failed: %s"), base_name, strerror(errno)); > -- return false; > -- } > -- if (len < s.st_size) > -- { > -- gold_info(_("%s: file too short"), base_name); > -- return false; > -- } > -+ ssize_t bytes_to_read = s.st_size; > -+ unsigned char* p = this->base_; > -+ while (bytes_to_read > 0) > -+ { > -+ ssize_t len = ::read(o, p, bytes_to_read); > -+ if (len < 0) > -+ { > -+ gold_info(_("%s: read failed: %s"), base_name, strerror(errno)); > -+ return false; > -+ } > -+ if (len == 0) > -+ { > -+ gold_info(_("%s: file too short: read only %lld of %lld bytes"), > -+ base_name, > -+ static_cast(s.st_size - bytes_to_read), > -+ static_cast(s.st_size)); > -+ return false; > -+ } > -+ p += len; > -+ bytes_to_read -= len; > -+ } > - ::close(o); > - return true; > - } > -@@ -5052,8 +5074,12 @@ Output_file::map_no_anonymous(bool writable) > - // output file will wind up incomplete, but we will have already > - // exited. The alternative to fallocate would be to use fdatasync, > - // but that would be a more significant performance hit. > -- if (writable && ::posix_fallocate(o, 0, this->file_size_) < 0) > -- gold_fatal(_("%s: %s"), this->name_, strerror(errno)); > -+ if (writable) > -+ { > -+ int err = ::posix_fallocate(o, 0, this->file_size_); > -+ if (err != 0) > -+ gold_fatal(_("%s: %s"), this->name_, strerror(err)); > -+ } > - > - // Map the file into memory. > - int prot = PROT_READ; > -diff --git a/gold/output.h b/gold/output.h > -index 1bec2c0..e2d35e2 100644 > ---- a/gold/output.h > -+++ b/gold/output.h > -@@ -1033,12 +1033,14 @@ class Output_reloc > - Output_reloc(Sized_relobj* relobj, > - unsigned int local_sym_index, unsigned int type, > - Output_data* od, Address address, bool is_relative, > -- bool is_symbolless, bool is_section_symbol); > -+ bool is_symbolless, bool is_section_symbol, > -+ bool use_plt_offset); > - > - Output_reloc(Sized_relobj* relobj, > - unsigned int local_sym_index, unsigned int type, > - unsigned int shndx, Address address, bool is_relative, > -- bool is_symbolless, bool is_section_symbol); > -+ bool is_symbolless, bool is_section_symbol, > -+ bool use_plt_offset); > - > - // A reloc against the STT_SECTION symbol of an output section. > - > -@@ -1216,7 +1218,7 @@ class Output_reloc > - // input file. > - unsigned int local_sym_index_; > - // The reloc type--a processor specific code. > -- unsigned int type_ : 29; > -+ unsigned int type_ : 28; > - // True if the relocation is a RELATIVE relocation. > - bool is_relative_ : 1; > - // True if the relocation is one which should not use > -@@ -1224,6 +1226,10 @@ class Output_reloc > - bool is_symbolless_ : 1; > - // True if the relocation is against a section symbol. > - bool is_section_symbol_ : 1; > -+ // True if the addend should be the PLT offset. This is used only > -+ // for RELATIVE relocations to local symbols. > -+ // (Used only for RELA, but stored here for space.) > -+ bool use_plt_offset_ : 1; > - // If the reloc address is an input section in an object, the > - // section index. This is INVALID_CODE if the reloc address is > - // specified in some other way. > -@@ -1268,9 +1274,10 @@ class Output_reloc > - unsigned int local_sym_index, unsigned int type, > - Output_data* od, Address address, > - Addend addend, bool is_relative, > -- bool is_symbolless, bool is_section_symbol) > -+ bool is_symbolless, bool is_section_symbol, > -+ bool use_plt_offset) > - : rel_(relobj, local_sym_index, type, od, address, is_relative, > -- is_symbolless, is_section_symbol), > -+ is_symbolless, is_section_symbol, use_plt_offset), > - addend_(addend) > - { } > - > -@@ -1278,9 +1285,10 @@ class Output_reloc > - unsigned int local_sym_index, unsigned int type, > - unsigned int shndx, Address address, > - Addend addend, bool is_relative, > -- bool is_symbolless, bool is_section_symbol) > -+ bool is_symbolless, bool is_section_symbol, > -+ bool use_plt_offset) > - : rel_(relobj, local_sym_index, type, shndx, address, is_relative, > -- is_symbolless, is_section_symbol), > -+ is_symbolless, is_section_symbol, use_plt_offset), > - addend_(addend) > - { } > - > -@@ -1571,7 +1579,7 @@ class Output_data_reloc > - Output_data* od, Address address) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, > -- address, false, false, false)); > -+ address, false, false, false, false)); > - } > - > - void > -@@ -1580,7 +1588,7 @@ class Output_data_reloc > - Output_data* od, unsigned int shndx, Address address) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, > -- address, false, false, false)); > -+ address, false, false, false, false)); > - } > - > - // Add a RELATIVE reloc against a local symbol. > -@@ -1591,7 +1599,7 @@ class Output_data_reloc > - Output_data* od, Address address) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, > -- address, true, true, false)); > -+ address, true, true, false, false)); > - } > - > - void > -@@ -1600,7 +1608,7 @@ class Output_data_reloc > - Output_data* od, unsigned int shndx, Address address) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, > -- address, true, true, false)); > -+ address, true, true, false, false)); > - } > - > - // Add a local relocation which does not use a symbol for the relocation, > -@@ -1612,7 +1620,7 @@ class Output_data_reloc > - Output_data* od, Address address) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, > -- address, false, true, false)); > -+ address, false, true, false, false)); > - } > - > - void > -@@ -1622,7 +1630,7 @@ class Output_data_reloc > - Address address) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, > -- address, false, true, false)); > -+ address, false, true, false, false)); > - } > - > - // Add a reloc against a local section symbol. This will be > -@@ -1635,7 +1643,7 @@ class Output_data_reloc > - Output_data* od, Address address) > - { > - this->add(od, Output_reloc_type(relobj, input_shndx, type, od, > -- address, false, false, true)); > -+ address, false, false, true, false)); > - } > - > - void > -@@ -1644,7 +1652,7 @@ class Output_data_reloc > - Output_data* od, unsigned int shndx, Address address) > - { > - this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, > -- address, false, false, true)); > -+ address, false, false, true, false)); > - } > - > - // A reloc against the STT_SECTION symbol of an output section. > -@@ -1767,7 +1775,7 @@ class Output_data_reloc > - Output_data* od, Address address, Addend addend) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, > -- addend, false, false, false)); > -+ addend, false, false, false, false)); > - } > - > - void > -@@ -1777,7 +1785,8 @@ class Output_data_reloc > - Addend addend) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, > -- address, addend, false, false, false)); > -+ address, addend, false, false, false, > -+ false)); > - } > - > - // Add a RELATIVE reloc against a local symbol. > -@@ -1785,20 +1794,23 @@ class Output_data_reloc > - void > - add_local_relative(Sized_relobj* relobj, > - unsigned int local_sym_index, unsigned int type, > -- Output_data* od, Address address, Addend addend) > -+ Output_data* od, Address address, Addend addend, > -+ bool use_plt_offset) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, > -- addend, true, true, false)); > -+ addend, true, true, false, > -+ use_plt_offset)); > - } > - > - void > - add_local_relative(Sized_relobj* relobj, > - unsigned int local_sym_index, unsigned int type, > - Output_data* od, unsigned int shndx, Address address, > -- Addend addend) > -+ Addend addend, bool use_plt_offset) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, > -- address, addend, true, true, false)); > -+ address, addend, true, true, false, > -+ use_plt_offset)); > - } > - > - // Add a local relocation which does not use a symbol for the relocation, > -@@ -1810,7 +1822,7 @@ class Output_data_reloc > - Output_data* od, Address address, Addend addend) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, > -- addend, false, true, false)); > -+ addend, false, true, false, false)); > - } > - > - void > -@@ -1820,7 +1832,8 @@ class Output_data_reloc > - Address address, Addend addend) > - { > - this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, > -- address, addend, false, true, false)); > -+ address, addend, false, true, false, > -+ false)); > - } > - > - // Add a reloc against a local section symbol. This will be > -@@ -1833,7 +1846,7 @@ class Output_data_reloc > - Output_data* od, Address address, Addend addend) > - { > - this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address, > -- addend, false, false, true)); > -+ addend, false, false, true, false)); > - } > - > - void > -@@ -1843,7 +1856,8 @@ class Output_data_reloc > - Addend addend) > - { > - this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, > -- address, addend, false, false, true)); > -+ address, addend, false, false, true, > -+ false)); > - } > - > - // A reloc against the STT_SECTION symbol of an output section. > -diff --git a/gold/plugin.cc b/gold/plugin.cc > -index 3ccd8d0..b4e68f8 100644 > ---- a/gold/plugin.cc > -+++ b/gold/plugin.cc > -@@ -818,7 +818,9 @@ Pluginobj::Pluginobj(const std::string& name, Input_file* input_file, > - } > - > - // Return TRUE if a defined symbol is referenced from outside the > --// universe of claimed objects. > -+// universe of claimed objects. Only references from relocatable, > -+// non-IR (unclaimed) objects count as a reference. References from > -+// dynamic objects count only as "visible". > - > - static inline bool > - is_referenced_from_outside(Symbol* lsym) > -@@ -838,6 +840,8 @@ is_referenced_from_outside(Symbol* lsym) > - static inline bool > - is_visible_from_outside(Symbol* lsym) > - { > -+ if (lsym->in_dyn()) > -+ return true; > - if (parameters->options().export_dynamic() || parameters->options().shared()) > - return lsym->is_externally_visible(); > - return false; > -@@ -1244,14 +1248,18 @@ Sized_pluginobj::do_initialize_xindex() > - return NULL; > - } > - > --// Get symbol counts. Not used for plugin objects. > -+// Get symbol counts. Don't count plugin objects; the replacement > -+// files will provide the counts. > - > - template > - void > --Sized_pluginobj::do_get_global_symbol_counts(const Symbol_table*, > -- size_t*, size_t*) const > -+Sized_pluginobj::do_get_global_symbol_counts( > -+ const Symbol_table*, > -+ size_t* defined, > -+ size_t* used) const > - { > -- gold_unreachable(); > -+ *defined = 0; > -+ *used = 0; > - } > - > - // Get symbols. Not used for plugin objects. > -diff --git a/gold/powerpc.cc b/gold/powerpc.cc > -index 45783c3..62a17ca 100644 > ---- a/gold/powerpc.cc > -+++ b/gold/powerpc.cc > -@@ -1329,7 +1329,7 @@ Target_powerpc::Scan::local( > - rela_dyn->add_local_relative(object, r_sym, r_type, > - output_section, data_shndx, > - reloc.get_r_offset(), > -- reloc.get_r_addend()); > -+ reloc.get_r_addend(), false); > - } > - } > - break; > -@@ -1372,7 +1372,7 @@ Target_powerpc::Scan::local( > - object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off); > - rela_dyn->add_local_relative(object, r_sym, > - elfcpp::R_POWERPC_RELATIVE, > -- got, off, 0); > -+ got, off, 0, false); > - } > - } > - else > -diff --git a/gold/readsyms.cc b/gold/readsyms.cc > -index 1e50942..9974722 100644 > ---- a/gold/readsyms.cc > -+++ b/gold/readsyms.cc > -@@ -161,8 +161,10 @@ void > - Read_symbols::run(Workqueue* workqueue) > - { > - // If we didn't queue a new task, then we need to explicitly unblock > -- // the token. > -- if (!this->do_read_symbols(workqueue)) > -+ // the token. If the object is a member of a lib group, however, > -+ // the token was already added to the list of locks for the task, > -+ // and it will be unblocked automatically at the end of the task. > -+ if (!this->do_read_symbols(workqueue) && this->member_ == NULL) > - workqueue->queue_soon(new Unblock_token(this->this_blocker_, > - this->next_blocker_)); > - } > -diff --git a/gold/resolve.cc b/gold/resolve.cc > -index 03288ec..780038a 100644 > ---- a/gold/resolve.cc > -+++ b/gold/resolve.cc > -@@ -296,7 +296,7 @@ Symbol_table::resolve(Sized_symbol* to, > - > - // Record if we've seen this symbol in a real ELF object (i.e., the > - // symbol is referenced from outside the world known to the plugin). > -- if (object->pluginobj() == NULL) > -+ if (object->pluginobj() == NULL && !object->is_dynamic()) > - to->set_in_real_elf(); > - > - // If we're processing replacement files, allow new symbols to override > -@@ -336,9 +336,9 @@ Symbol_table::resolve(Sized_symbol* to, > - && to->name()[0] == '_' && to->name()[1] == 'Z') > - { > - Symbol_location fromloc > -- = { object, orig_st_shndx, sym.get_st_value() }; > -+ = { object, orig_st_shndx, static_cast(sym.get_st_value()) }; > - Symbol_location toloc = { to->object(), to->shndx(&to_is_ordinary), > -- to->value() }; > -+ static_cast(to->value()) }; > - this->candidate_odr_violations_[to->name()].insert(fromloc); > - this->candidate_odr_violations_[to->name()].insert(toloc); > - } > -diff --git a/gold/script-sections.cc b/gold/script-sections.cc > -index 1fad88d..f90c0b3 100644 > ---- a/gold/script-sections.cc > -+++ b/gold/script-sections.cc > -@@ -680,7 +680,7 @@ class Sections_element_assignment : public Sections_element > - set_section_addresses(Symbol_table* symtab, Layout* layout, > - uint64_t* dot_value, uint64_t*, uint64_t*) > - { > -- this->assignment_.set_if_absolute(symtab, layout, true, *dot_value); > -+ this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, NULL); > - } > - > - // Print for debugging. > -@@ -714,7 +714,7 @@ class Sections_element_dot_assignment : public Sections_element > - // output section definition the dot symbol is always considered > - // to be absolute. > - *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value, > -- NULL, NULL, NULL); > -+ NULL, NULL, NULL, false); > - } > - > - // Update the dot symbol while setting section addresses. > -@@ -724,7 +724,7 @@ class Sections_element_dot_assignment : public Sections_element > - uint64_t* load_address) > - { > - *dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value, > -- NULL, NULL, dot_alignment); > -+ NULL, NULL, dot_alignment, false); > - *load_address = *dot_value; > - } > - > -@@ -866,9 +866,11 @@ class Output_section_element_assignment : public Output_section_element > - void > - set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, > - uint64_t, uint64_t* dot_value, uint64_t*, > -- Output_section**, std::string*, Input_section_list*) > -+ Output_section** dot_section, std::string*, > -+ Input_section_list*) > - { > -- this->assignment_.set_if_absolute(symtab, layout, true, *dot_value); > -+ this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, > -+ *dot_section); > - } > - > - // Print for debugging. > -@@ -892,20 +894,28 @@ class Output_section_element_dot_assignment : public Output_section_element > - : val_(val) > - { } > - > -+ // An assignment to dot within an output section is enough to force > -+ // the output section to exist. > -+ bool > -+ needs_output_section() const > -+ { return true; } > -+ > - // Finalize the symbol. > - void > - finalize_symbols(Symbol_table* symtab, const Layout* layout, > - uint64_t* dot_value, Output_section** dot_section) > - { > - *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value, > -- *dot_section, dot_section, NULL); > -+ *dot_section, dot_section, NULL, > -+ true); > - } > - > - // Update the dot symbol while setting section addresses. > - void > - set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, > - uint64_t, uint64_t* dot_value, uint64_t*, > -- Output_section**, std::string*, Input_section_list*); > -+ Output_section** dot_section, std::string*, > -+ Input_section_list*); > - > - // Print for debugging. > - void > -@@ -936,7 +946,8 @@ Output_section_element_dot_assignment::set_section_addresses( > - { > - uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false, > - *dot_value, *dot_section, > -- dot_section, dot_alignment); > -+ dot_section, dot_alignment, > -+ true); > - if (next_dot < *dot_value) > - gold_error(_("dot may not move backward")); > - if (next_dot > *dot_value && output_section != NULL) > -@@ -1037,7 +1048,8 @@ Output_data_expression::do_write_to_buffer(unsigned char* buf) > - { > - uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_, > - true, this->dot_value_, > -- this->dot_section_, NULL, NULL); > -+ this->dot_section_, NULL, NULL, > -+ false); > - > - if (parameters->target().is_big_endian()) > - this->endian_write_to_buffer(val, buf); > -@@ -1187,7 +1199,7 @@ class Output_section_element_fill : public Output_section_element > - Output_section* fill_section; > - uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false, > - *dot_value, *dot_section, > -- &fill_section, NULL); > -+ &fill_section, NULL, false); > - if (fill_section != NULL) > - gold_warning(_("fill value is not absolute")); > - // FIXME: The GNU linker supports fill values of arbitrary length. > -@@ -2108,13 +2120,13 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab, > - { > - address = this->address_->eval_with_dot(symtab, layout, true, > - *dot_value, NULL, > -- NULL, NULL); > -+ NULL, NULL, false); > - } > - if (this->align_ != NULL) > - { > - uint64_t align = this->align_->eval_with_dot(symtab, layout, true, > - *dot_value, NULL, > -- NULL, NULL); > -+ NULL, NULL, false); > - address = align_address(address, align); > - } > - *dot_value = address; > -@@ -2303,7 +2315,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, > - else > - address = this->address_->eval_with_dot(symtab, layout, true, > - *dot_value, NULL, NULL, > -- dot_alignment); > -+ dot_alignment, false); > - uint64_t align; > - if (this->align_ == NULL) > - { > -@@ -2316,7 +2328,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, > - { > - Output_section* align_section; > - align = this->align_->eval_with_dot(symtab, layout, true, *dot_value, > -- NULL, &align_section, NULL); > -+ NULL, &align_section, NULL, false); > - if (align_section != NULL) > - gold_warning(_("alignment of section %s is not absolute"), > - this->name_.c_str()); > -@@ -2401,7 +2413,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, > - laddr = this->load_address_->eval_with_dot(symtab, layout, true, > - *dot_value, > - this->output_section_, > -- NULL, NULL); > -+ NULL, NULL, false); > - if (this->output_section_ != NULL) > - this->output_section_->set_load_address(laddr); > - } > -@@ -2416,7 +2428,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, > - Output_section* subalign_section; > - subalign = this->subalign_->eval_with_dot(symtab, layout, true, > - *dot_value, NULL, > -- &subalign_section, NULL); > -+ &subalign_section, NULL, > -+ false); > - if (subalign_section != NULL) > - gold_warning(_("subalign of section %s is not absolute"), > - this->name_.c_str()); > -@@ -2431,7 +2444,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, > - uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true, > - *dot_value, > - NULL, &fill_section, > -- NULL); > -+ NULL, false); > - if (fill_section != NULL) > - gold_warning(_("fill of section %s is not absolute"), > - this->name_.c_str()); > -diff --git a/gold/script.cc b/gold/script.cc > -index 7df0c9e..b471cf9 100644 > ---- a/gold/script.cc > -+++ b/gold/script.cc > -@@ -983,18 +983,20 @@ Symbol_assignment::sized_finalize(Symbol_table* symtab, const Layout* layout, > - uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true, > - is_dot_available, > - dot_value, dot_section, > -- §ion, NULL); > -+ §ion, NULL, false); > - Sized_symbol* ssym = symtab->get_sized_symbol(this->sym_); > - ssym->set_value(final_val); > - if (section != NULL) > - ssym->set_output_section(section); > - } > - > --// Set the symbol value if the expression yields an absolute value. > -+// Set the symbol value if the expression yields an absolute value or > -+// a value relative to DOT_SECTION. > - > - void > - Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, > -- bool is_dot_available, uint64_t dot_value) > -+ bool is_dot_available, uint64_t dot_value, > -+ Output_section* dot_section) > - { > - if (this->sym_ == NULL) > - return; > -@@ -1002,8 +1004,9 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, > - Output_section* val_section; > - uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false, > - is_dot_available, dot_value, > -- NULL, &val_section, NULL); > -- if (val_section != NULL) > -+ dot_section, &val_section, NULL, > -+ false); > -+ if (val_section != NULL && val_section != dot_section) > - return; > - > - if (parameters->target().get_size() == 32) > -@@ -1026,6 +1029,8 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, > - } > - else > - gold_unreachable(); > -+ if (val_section != NULL) > -+ this->sym_->set_output_section(val_section); > - } > - > - // Print for debugging. > -@@ -1215,7 +1220,7 @@ Script_options::set_section_addresses(Symbol_table* symtab, Layout* layout) > - for (Symbol_assignments::iterator p = this->symbol_assignments_.begin(); > - p != this->symbol_assignments_.end(); > - ++p) > -- (*p)->set_if_absolute(symtab, layout, false, 0); > -+ (*p)->set_if_absolute(symtab, layout, false, 0, NULL); > - > - return this->script_sections_.set_section_addresses(symtab, layout); > - } > -diff --git a/gold/script.h b/gold/script.h > -index 73079a4..f41f438 100644 > ---- a/gold/script.h > -+++ b/gold/script.h > -@@ -90,20 +90,28 @@ class Expression > - // the section address. If RESULT_ALIGNMENT is not NULL, this sets > - // *RESULT_ALIGNMENT to the alignment of the value of that alignment > - // is larger than *RESULT_ALIGNMENT; this will only be non-zero if > -- // this is an ALIGN expression. > -+ // this is an ALIGN expression. If IS_SECTION_DOT_ASSIGMENT is true, > -+ // we are evaluating an assignment to dot within an output section, > -+ // and an absolute value should be interpreted as an offset within > -+ // the section. > - uint64_t > - eval_with_dot(const Symbol_table*, const Layout*, bool check_assertions, > - uint64_t dot_value, Output_section* dot_section, > -- Output_section** result_section, uint64_t* result_alignment); > -+ Output_section** result_section, uint64_t* result_alignment, > -+ bool is_section_dot_assignment); > - > - // Return the value of an expression which may or may not be > - // permitted to refer to the dot symbol, depending on > -- // is_dot_available. > -+ // is_dot_available. If IS_SECTION_DOT_ASSIGMENT is true, > -+ // we are evaluating an assignment to dot within an output section, > -+ // and an absolute value should be interpreted as an offset within > -+ // the section. > - uint64_t > - eval_maybe_dot(const Symbol_table*, const Layout*, bool check_assertions, > - bool is_dot_available, uint64_t dot_value, > - Output_section* dot_section, > -- Output_section** result_section, uint64_t* result_alignment); > -+ Output_section** result_section, uint64_t* result_alignment, > -+ bool is_section_dot_assignment); > - > - // Print the expression to the FILE. This is for debugging. > - virtual void > -@@ -339,12 +347,12 @@ class Symbol_assignment > - finalize_with_dot(Symbol_table*, const Layout*, uint64_t dot_value, > - Output_section* dot_section); > - > -- // Set the symbol value, but only if the value is absolute. This is > -- // used while processing a SECTIONS clause. We assume that dot is > -- // an absolute value here. We do not check assertions. > -+ // Set the symbol value, but only if the value is absolute or relative to > -+ // DOT_SECTION. This is used while processing a SECTIONS clause. > -+ // We assume that dot is an absolute value here. We do not check assertions. > - void > - set_if_absolute(Symbol_table*, const Layout*, bool is_dot_available, > -- uint64_t dot_value); > -+ uint64_t dot_value, Output_section* dot_section); > - > - const std::string& > - name() const > -diff --git a/gold/sparc.cc b/gold/sparc.cc > -index 5f67a4e..12e1dee 100644 > ---- a/gold/sparc.cc > -+++ b/gold/sparc.cc > -@@ -1855,7 +1855,7 @@ Target_sparc::Scan::local( > - rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_RELATIVE, > - output_section, data_shndx, > - reloc.get_r_offset(), > -- reloc.get_r_addend()); > -+ reloc.get_r_addend(), false); > - } > - break; > - > -@@ -1946,7 +1946,7 @@ Target_sparc::Scan::local( > - object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off); > - rela_dyn->add_local_relative(object, r_sym, > - elfcpp::R_SPARC_RELATIVE, > -- got, off, 0); > -+ got, off, 0, false); > - } > - } > - else > -diff --git a/gold/symtab.cc b/gold/symtab.cc > -index ff1b5ca..f0ba1d5 100644 > ---- a/gold/symtab.cc > -+++ b/gold/symtab.cc > -@@ -602,20 +602,16 @@ Symbol_table::gc_mark_undef_symbols(Layout* layout) > - } > - > - void > --Symbol_table::gc_mark_symbol_for_shlib(Symbol* sym) > -+Symbol_table::gc_mark_symbol(Symbol* sym) > - { > -- if (!sym->is_from_dynobj() > -- && sym->is_externally_visible()) > -+ // Add the object and section to the work list. > -+ Relobj* obj = static_cast(sym->object()); > -+ bool is_ordinary; > -+ unsigned int shndx = sym->shndx(&is_ordinary); > -+ if (is_ordinary && shndx != elfcpp::SHN_UNDEF) > - { > -- //Add the object and section to the work list. > -- Relobj* obj = static_cast(sym->object()); > -- bool is_ordinary; > -- unsigned int shndx = sym->shndx(&is_ordinary); > -- if (is_ordinary && shndx != elfcpp::SHN_UNDEF) > -- { > -- gold_assert(this->gc_!= NULL); > -- this->gc_->worklist().push(Section_id(obj, shndx)); > -- } > -+ gold_assert(this->gc_!= NULL); > -+ this->gc_->worklist().push(Section_id(obj, shndx)); > - } > - } > - > -@@ -626,16 +622,7 @@ Symbol_table::gc_mark_dyn_syms(Symbol* sym) > - { > - if (sym->in_dyn() && sym->source() == Symbol::FROM_OBJECT > - && !sym->object()->is_dynamic()) > -- { > -- Relobj* obj = static_cast(sym->object()); > -- bool is_ordinary; > -- unsigned int shndx = sym->shndx(&is_ordinary); > -- if (is_ordinary && shndx != elfcpp::SHN_UNDEF) > -- { > -- gold_assert(this->gc_ != NULL); > -- this->gc_->worklist().push(Section_id(obj, shndx)); > -- } > -- } > -+ this->gc_mark_symbol(sym); > - } > - > - // Make TO a symbol which forwards to FROM. > -@@ -1143,6 +1130,14 @@ Symbol_table::add_from_relobj( > - bool is_default_version = false; > - bool is_forced_local = false; > - > -+ // FIXME: For incremental links, we don't store version information, > -+ // so we need to ignore version symbols for now. > -+ if (parameters->incremental_update() && ver != NULL) > -+ { > -+ namelen = ver - name; > -+ ver = NULL; > -+ } > -+ > - if (ver != NULL) > - { > - // The symbol name is of the form foo@VERSION or foo@@VERSION > -@@ -1243,11 +1238,16 @@ Symbol_table::add_from_relobj( > - if (is_forced_local) > - this->force_local(res); > - > -- // If building a shared library using garbage collection, do not > -- // treat externally visible symbols as garbage. > -- if (parameters->options().gc_sections() > -- && parameters->options().shared()) > -- this->gc_mark_symbol_for_shlib(res); > -+ // Do not treat this symbol as garbage if this symbol will be > -+ // exported to the dynamic symbol table. This is true when > -+ // building a shared library or using --export-dynamic and > -+ // the symbol is externally visible. > -+ if (parameters->options().gc_sections() > -+ && res->is_externally_visible() > -+ && !res->is_from_dynobj() > -+ && (parameters->options().shared() > -+ || parameters->options().export_dynamic())) > -+ this->gc_mark_symbol(res); > - > - if (is_defined_in_discarded_section) > - res->set_is_defined_in_discarded_section(); > -@@ -1346,6 +1346,11 @@ Symbol_table::add_from_dynobj( > - return; > - } > - > -+ // FIXME: For incremental links, we don't store version information, > -+ // so we need to ignore version symbols for now. > -+ if (parameters->incremental_update()) > -+ versym = NULL; > -+ > - if (versym != NULL && versym_size / 2 < count) > - { > - dynobj->error(_("too few symbol versions")); > -@@ -2809,6 +2814,12 @@ Symbol_table::sized_write_globals(const Stringpool* sympool, > - typename elfcpp::Elf_types::Elf_Addr sym_value = sym->value(); > - typename elfcpp::Elf_types::Elf_Addr dynsym_value = sym_value; > - elfcpp::STB binding = sym->binding(); > -+ > -+ // If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL. > -+ if (binding == elfcpp::STB_GNU_UNIQUE > -+ && !parameters->options().gnu_unique()) > -+ binding = elfcpp::STB_GLOBAL; > -+ > - switch (sym->source()) > - { > - case Symbol::FROM_OBJECT: > -diff --git a/gold/symtab.h b/gold/symtab.h > -index b9b9e00..427f72f 100644 > ---- a/gold/symtab.h > -+++ b/gold/symtab.h > -@@ -1308,10 +1308,9 @@ class Symbol_table > - void > - gc_mark_undef_symbols(Layout*); > - > -- // During garbage collection, this ensures externally visible symbols > -- // are not treated as garbage while building shared objects. > -+ // This tells garbage collection that this symbol is referenced. > - void > -- gc_mark_symbol_for_shlib(Symbol* sym); > -+ gc_mark_symbol(Symbol* sym); > - > - // During garbage collection, this keeps sections that correspond to > - // symbols seen in dynamic objects. > -diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in > -index 67149fb..785dcdd 100644 > ---- a/gold/testsuite/Makefile.in > -+++ b/gold/testsuite/Makefile.in > -@@ -1844,6 +1844,8 @@ EGREP = @EGREP@ > - EXEEXT = @EXEEXT@ > - GENCAT = @GENCAT@ > - GMSGFMT = @GMSGFMT@ > -+GOLD_LDADD = @GOLD_LDADD@ > -+GOLD_LDFLAGS = @GOLD_LDFLAGS@ > - GREP = @GREP@ > - INCINTL = @INCINTL@ > - INSTALL = @INSTALL@ > -diff --git a/gold/testsuite/plugin_test_2.sh b/gold/testsuite/plugin_test_2.sh > -index a47d22a..293b1f0 100755 > ---- a/gold/testsuite/plugin_test_2.sh > -+++ b/gold/testsuite/plugin_test_2.sh > -@@ -45,7 +45,7 @@ check plugin_test_2.err "two_file_test_main.o: claim file hook called" > - check plugin_test_2.err "two_file_test_1.syms: claim file hook called" > - check plugin_test_2.err "two_file_test_1b.syms: claim file hook called" > - check plugin_test_2.err "two_file_shared_2.so: claim file hook called" > --check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_REG" > -+check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_IRONLY_EXP" > - check plugin_test_2.err "two_file_test_1.syms: _Z2t2v: PREVAILING_DEF_REG" > - check plugin_test_2.err "two_file_test_1.syms: v2: RESOLVED_DYN" > - check plugin_test_2.err "two_file_test_1.syms: t17data: RESOLVED_DYN" > -diff --git a/gold/testsuite/script_test_2.t b/gold/testsuite/script_test_2.t > -index 73d39df..6a0188f 100644 > ---- a/gold/testsuite/script_test_2.t > -+++ b/gold/testsuite/script_test_2.t > -@@ -49,7 +49,7 @@ SECTIONS > - /* This should match the remaining sections. */ > - *(.gold_test) > - > -- . = . + 4; > -+ . = 60; > - start_data = .; > - BYTE(1) > - SHORT(2) > -diff --git a/gold/x86_64.cc b/gold/x86_64.cc > -index e6b0021..e7c981b 100644 > ---- a/gold/x86_64.cc > -+++ b/gold/x86_64.cc > -@@ -1549,7 +1549,7 @@ Target_x86_64::reserve_local_got_entry( > - case GOT_TYPE_STANDARD: > - if (parameters->options().output_is_position_independent()) > - rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_X86_64_RELATIVE, > -- this->got_, got_offset, 0); > -+ this->got_, got_offset, 0, false); > - break; > - case GOT_TYPE_TLS_OFFSET: > - rela_dyn->add_local(obj, r_sym, elfcpp::R_X86_64_TPOFF64, > -@@ -1953,8 +1953,8 @@ Target_x86_64::Scan::local(Symbol_table* symtab, > - const elfcpp::Sym<64, false>& lsym) > - { > - // A local STT_GNU_IFUNC symbol may require a PLT entry. > -- if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC > -- && this->reloc_needs_plt_for_ifunc(object, r_type)) > -+ bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC; > -+ if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type)) > - { > - unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info()); > - target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym); > -@@ -1982,7 +1982,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, > - elfcpp::R_X86_64_RELATIVE, > - output_section, data_shndx, > - reloc.get_r_offset(), > -- reloc.get_r_addend()); > -+ reloc.get_r_addend(), is_ifunc); > - } > - break; > - > -@@ -2058,7 +2058,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, > - // lets function pointers compare correctly with shared > - // libraries. Otherwise we would need an IRELATIVE reloc. > - bool is_new; > -- if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC) > -+ if (is_ifunc) > - is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD); > - else > - is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD); > -@@ -2076,7 +2076,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, > - object->local_got_offset(r_sym, GOT_TYPE_STANDARD); > - rela_dyn->add_local_relative(object, r_sym, > - elfcpp::R_X86_64_RELATIVE, > -- got, got_offset, 0); > -+ got, got_offset, 0, is_ifunc); > - } > - else > - { > -@@ -3181,12 +3181,6 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, > - } > - if (optimized_type == tls::TLSOPT_TO_IE) > - { > -- if (tls_segment == NULL) > -- { > -- gold_assert(parameters->errors()->error_count() > 0 > -- || issue_undefined_symbol_error(gsym)); > -- return; > -- } > - value = target->got_plt_section()->address() + got_offset; > - this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type, > - value, view, address, view_size); > -@@ -3867,42 +3861,51 @@ Target_x86_64::do_code_fill(section_size_type length) const > - } > - > - // Nop sequences of various lengths. > -- const char nop1[1] = { 0x90 }; // nop > -- const char nop2[2] = { 0x66, 0x90 }; // xchg %ax %ax > -- const char nop3[3] = { 0x0f, 0x1f, 0x00 }; // nop (%rax) > -- const char nop4[4] = { 0x0f, 0x1f, 0x40, 0x00}; // nop 0(%rax) > -- const char nop5[5] = { 0x0f, 0x1f, 0x44, 0x00, // nop 0(%rax,%rax,1) > -- 0x00 }; > -- const char nop6[6] = { 0x66, 0x0f, 0x1f, 0x44, // nopw 0(%rax,%rax,1) > -- 0x00, 0x00 }; > -- const char nop7[7] = { 0x0f, 0x1f, 0x80, 0x00, // nopl 0L(%rax) > -- 0x00, 0x00, 0x00 }; > -- const char nop8[8] = { 0x0f, 0x1f, 0x84, 0x00, // nopl 0L(%rax,%rax,1) > -- 0x00, 0x00, 0x00, 0x00 }; > -- const char nop9[9] = { 0x66, 0x0f, 0x1f, 0x84, // nopw 0L(%rax,%rax,1) > -- 0x00, 0x00, 0x00, 0x00, > -- 0x00 }; > -- const char nop10[10] = { 0x66, 0x2e, 0x0f, 0x1f, // nopw %cs:0L(%rax,%rax,1) > -- 0x84, 0x00, 0x00, 0x00, > -- 0x00, 0x00 }; > -- const char nop11[11] = { 0x66, 0x66, 0x2e, 0x0f, // data16 > -- 0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1) > -- 0x00, 0x00, 0x00 }; > -- const char nop12[12] = { 0x66, 0x66, 0x66, 0x2e, // data16; data16 > -- 0x0f, 0x1f, 0x84, 0x00, // nopw %cs:0L(%rax,%rax,1) > -- 0x00, 0x00, 0x00, 0x00 }; > -- const char nop13[13] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16 > -- 0x2e, 0x0f, 0x1f, 0x84, // nopw %cs:0L(%rax,%rax,1) > -- 0x00, 0x00, 0x00, 0x00, > -- 0x00 }; > -- const char nop14[14] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16 > -- 0x66, 0x2e, 0x0f, 0x1f, // data16 > -- 0x84, 0x00, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1) > -- 0x00, 0x00 }; > -- const char nop15[15] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16 > -- 0x66, 0x66, 0x2e, 0x0f, // data16; data16 > -- 0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1) > -- 0x00, 0x00, 0x00 }; > -+ const char nop1[1] = { '\x90' }; // nop > -+ const char nop2[2] = { '\x66', '\x90' }; // xchg %ax %ax > -+ const char nop3[3] = { '\x0f', '\x1f', '\x00' }; // nop (%rax) > -+ const char nop4[4] = { '\x0f', '\x1f', '\x40', // nop 0(%rax) > -+ '\x00'}; > -+ const char nop5[5] = { '\x0f', '\x1f', '\x44', // nop 0(%rax,%rax,1) > -+ '\x00', '\x00' }; > -+ const char nop6[6] = { '\x66', '\x0f', '\x1f', // nopw 0(%rax,%rax,1) > -+ '\x44', '\x00', '\x00' }; > -+ const char nop7[7] = { '\x0f', '\x1f', '\x80', // nopl 0L(%rax) > -+ '\x00', '\x00', '\x00', > -+ '\x00' }; > -+ const char nop8[8] = { '\x0f', '\x1f', '\x84', // nopl 0L(%rax,%rax,1) > -+ '\x00', '\x00', '\x00', > -+ '\x00', '\x00' }; > -+ const char nop9[9] = { '\x66', '\x0f', '\x1f', // nopw 0L(%rax,%rax,1) > -+ '\x84', '\x00', '\x00', > -+ '\x00', '\x00', '\x00' }; > -+ const char nop10[10] = { '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1) > -+ '\x1f', '\x84', '\x00', > -+ '\x00', '\x00', '\x00', > -+ '\x00' }; > -+ const char nop11[11] = { '\x66', '\x66', '\x2e', // data16 > -+ '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1) > -+ '\x00', '\x00', '\x00', > -+ '\x00', '\x00' }; > -+ const char nop12[12] = { '\x66', '\x66', '\x66', // data16; data16 > -+ '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1) > -+ '\x84', '\x00', '\x00', > -+ '\x00', '\x00', '\x00' }; > -+ const char nop13[13] = { '\x66', '\x66', '\x66', // data16; data16; data16 > -+ '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1) > -+ '\x1f', '\x84', '\x00', > -+ '\x00', '\x00', '\x00', > -+ '\x00' }; > -+ const char nop14[14] = { '\x66', '\x66', '\x66', // data16; data16; data16 > -+ '\x66', '\x66', '\x2e', // data16 > -+ '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1) > -+ '\x00', '\x00', '\x00', > -+ '\x00', '\x00' }; > -+ const char nop15[15] = { '\x66', '\x66', '\x66', // data16; data16; data16 > -+ '\x66', '\x66', '\x66', // data16; data16 > -+ '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1) > -+ '\x84', '\x00', '\x00', > -+ '\x00', '\x00', '\x00' }; > - > - const char* nops[16] = { > - NULL, > --- > -1.7.9.5 > - >