[OE-core] [PATCH] binutils-2.22: Disable recent gold backports from 2.22 branch

Saul Wold sgw at linux.intel.com
Thu Sep 27 16:27:47 UTC 2012


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 <raj.khem at gmail.com>
> ---
>   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 <ian at airs.com>
> -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  <ccoutant at google.com>
> -
> -	* 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  <ccoutant at google.com>
> -
> -	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  <ccoutant at google.com>
> -
> -	* 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  <ccoutant at google.com>
> -
> -	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  <tmsriram at google.com>
> -
> -	* 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  <iant at google.com>
> -
> -	PR gold/13163
> -	* script-sections.cc
> -	(Output_section_element_dot_assignment::needs_output_section): New
> -	function.
> -
> -	2011-10-19  Ian Lance Taylor  <iant at google.com>
> -
> -	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  <ccoutant at google.com>
> -
> -	* 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  <ccoutant at google.com>
> -
> -	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  <ccoutant at google.com>
> -
> -	* readsyms.cc (Read_symbols::run): Don't queue an unblocker
> -	task for members of lib groups.
> -
> -	2011-10-17  Cary Coutant  <ccoutant at google.com>
> -
> -	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  <ccoutant at google.com>
> -
> -	* output.cc (Output_file::open_base_file): Handle case where
> -	::read returns less than requested size.
> -
> -	2011-10-10  Cary Coutant  <ccoutant at google.com>
> -
> -	* 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  <ccoutant at google.com>
> -
> -	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  <dnovillo at google.com>
> -
> -	* options.cc (parse_uint): Fix dereference of RETVAL.
> -
> -	2011-09-29  Cary Coutant  <ccoutant at google.com>
> -
> -	* 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  <ccoutant at google.com>
> -
> -	* 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  <simonb at google.com>
> -
> -	* 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 <iant at google.com>.
> -
> - // This file is part of gold.
> -@@ -491,8 +491,10 @@ Sized_dwarf_line_info<size, big_endian>::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<off_t>(lsm.address),
> -+		      this->current_header_index_,
> -+		      static_cast<unsigned int>(lsm.file_num),
> -+		      true, lsm.line_num };
> - 	      std::vector<Offset_to_lineno_entry>&
> - 		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 <iant at google.com>.
> -
> - // 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<unsigned long long>(size)
> -+		  <= static_cast<unsigned long long>(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<unsigned long long>(size)
> --          > static_cast<unsigned long long>(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<long long>(size),
> --		   static_cast<long long>(start));
> -+  gold_assert(start <= this->size_
> -+	      && (static_cast<unsigned long long>(size)
> -+		  <= static_cast<unsigned long long>(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<unsigned long long>(size)
> -+          > static_cast<unsigned long long>(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<long long>(size),
> -+		   static_cast<long long>(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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::do_initialize_xindex()
> - template<int size, bool big_endian>
> - void
> - Sized_relobj_incr<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::do_initialize_xindex()
> - template<int size, bool big_endian>
> - void
> - Sized_incr_dynobj<size, big_endian>::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<size, big_endian>
> -   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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::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<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value(
> -   Sized_relobj_file<size, big_endian>* 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<size>* 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<long long>(s.st_size - bytes_to_read),
> -+			static_cast<long long>(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<elfcpp::SHT_REL, dynamic, size, big_endian>
> -   Output_reloc(Sized_relobj<size, big_endian>* 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<size, big_endian>* 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<elfcpp::SHT_REL, dynamic, size, big_endian>
> -   // 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<elfcpp::SHT_REL, dynamic, size, big_endian>
> -   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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> - 	       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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> - 	       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<elfcpp::SHT_REL, dynamic, size, big_endian>
> - 	    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<elfcpp::SHT_REL, dynamic, size, big_endian>
> - 	    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<elfcpp::SHT_REL, dynamic, size, big_endian>
> - 	             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<elfcpp::SHT_REL, dynamic, size, big_endian>
> - 	             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<elfcpp::SHT_REL, dynamic, size, big_endian>
> - 			      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<elfcpp::SHT_REL, dynamic, size, big_endian>
> - 			      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<elfcpp::SHT_REL, dynamic, size, big_endian>
> -                     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<elfcpp::SHT_REL, dynamic, size, big_endian>
> -                     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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> - 	    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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> - 	    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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> -   void
> -   add_local_relative(Sized_relobj<size, big_endian>* 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<size, big_endian>* 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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> - 			      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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> - 			      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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> -                     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<elfcpp::SHT_RELA, dynamic, size, big_endian>
> - 		    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<size, big_endian>::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<int size, bool big_endian>
> - void
> --Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_table*,
> --                                                   size_t*, size_t*) const
> -+Sized_pluginobj<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size>* 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<size>* 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<off_t>(sym.get_st_value()) };
> -       Symbol_location toloc = { to->object(), to->shndx(&to_is_ordinary),
> --				to->value() };
> -+				static_cast<off_t>(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<true>(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,
> --						  &section, NULL);
> -+						  &section, NULL, false);
> -   Sized_symbol<size>* ssym = symtab->get_sized_symbol<size>(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<size, big_endian>::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<size, big_endian>::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<Relobj*>(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<Relobj*>(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<Relobj*>(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 at 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<size>::Elf_Addr sym_value = sym->value();
> -       typename elfcpp::Elf_types<size>::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
> -
>




More information about the Openembedded-core mailing list