]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Copy from mainline to binutils 2.22 branch:
authorIan Lance Taylor <ian@airs.com>
Mon, 19 Dec 2011 21:14:40 +0000 (21:14 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 19 Dec 2011 21:14:40 +0000 (21:14 +0000)
2011-12-17  Cary Coutant  <ccoutant@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@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@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@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@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@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@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@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@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@google.com>

* readsyms.cc (Read_symbols::run): Don't queue an unblocker
task for members of lib groups.

2011-10-17  Cary Coutant  <ccoutant@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@google.com>

* output.cc (Output_file::open_base_file): Handle case where
::read returns less than requested size.

2011-10-10  Cary Coutant  <ccoutant@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@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@google.com>

* options.cc (parse_uint): Fix dereference of RETVAL.

2011-09-29  Cary Coutant  <ccoutant@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@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@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.

31 files changed:
gold/ChangeLog
gold/Makefile.am
gold/Makefile.in
gold/configure
gold/configure.ac
gold/dwarf_reader.cc
gold/expression.cc
gold/fileread.cc
gold/gold.cc
gold/i386.cc
gold/incremental.cc
gold/incremental.h
gold/layout.cc
gold/options.cc
gold/options.h
gold/output.cc
gold/output.h
gold/plugin.cc
gold/powerpc.cc
gold/readsyms.cc
gold/resolve.cc
gold/script-sections.cc
gold/script.cc
gold/script.h
gold/sparc.cc
gold/symtab.cc
gold/symtab.h
gold/testsuite/Makefile.in
gold/testsuite/plugin_test_2.sh
gold/testsuite/script_test_2.t
gold/x86_64.cc

index 7f9160699093163e3101ee440e15090916daa7b9..25ebc87645e74773adcac4015b0edeb5b471e828 100644 (file)
@@ -1,3 +1,166 @@
+2011-12-19  Ian Lance Taylor  <iant@google.com>
+
+       Copy from mainline to binutils 2.22 branch:
+
+       2011-12-17  Cary Coutant  <ccoutant@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@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@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@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@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@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@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@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@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@google.com>
+
+       * readsyms.cc (Read_symbols::run): Don't queue an unblocker
+       task for members of lib groups.
+
+       2011-10-17  Cary Coutant  <ccoutant@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@google.com>
+
+       * output.cc (Output_file::open_base_file): Handle case where
+       ::read returns less than requested size.
+
+       2011-10-10  Cary Coutant  <ccoutant@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@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@google.com>
+
+       * options.cc (parse_uint): Fix dereference of RETVAL.
+
+       2011-09-29  Cary Coutant  <ccoutant@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@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@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.
+
 2011-11-11  Doug Kwan  <dougkwan@google.com>
 
        * arm.cc (Target_arm::do_make_elf_object): Allow executable also
index df5e66c6b545ee7484e41b5770eaade17a944d62..c1c3588ef08f0478f381b6c2aedca28e83463d00 100644 (file)
@@ -151,12 +151,14 @@ libgold_a_LIBADD = $(LIBOBJS)
 
 sources_var = main.cc
 deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
-ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL) \
+ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(GOLD_LDADD) $(LIBINTL) \
         $(THREADSLIB) $(LIBDL)
+ldflags_var = $(GOLD_LDFLAGS)
 
 ld_new_SOURCES = $(sources_var)
 ld_new_DEPENDENCIES = $(deps_var)
 ld_new_LDADD = $(ldadd_var)
+ld_new_LDFLAGS = $(ldflags_var)
 
 EXTRA_ld_new_SOURCES = $(TARGETSOURCES)
 
index 1c33fe6a33420f6f76343a3bb738160564ea34d5..ff6d7c281cefa773d2190d0db83c10376d5b9ddf 100644 (file)
@@ -101,7 +101,9 @@ am_ld_new_OBJECTS = $(am__objects_4)
 ld_new_OBJECTS = $(am_ld_new_OBJECTS)
 am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libgold.a $(LIBIBERTY) \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-       $(am__DEPENDENCIES_1)
+       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+ld_new_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(ld_new_LDFLAGS) \
+       $(LDFLAGS) -o $@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_OBJECTS = $(am__objects_4)
 ld1_OBJECTS = $(am_ld1_OBJECTS)
 ld1_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(ld1_LDFLAGS) \
@@ -251,6 +253,8 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 GENCAT = @GENCAT@
 GMSGFMT = @GMSGFMT@
+GOLD_LDADD = @GOLD_LDADD@
+GOLD_LDFLAGS = @GOLD_LDFLAGS@
 GREP = @GREP@
 INCINTL = @INCINTL@
 INSTALL = @INSTALL@
@@ -488,12 +492,14 @@ libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES) $(DEFFILES)
 libgold_a_LIBADD = $(LIBOBJS)
 sources_var = main.cc
 deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
-ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL) \
+ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(GOLD_LDADD) $(LIBINTL) \
         $(THREADSLIB) $(LIBDL)
 
+ldflags_var = $(GOLD_LDFLAGS)
 ld_new_SOURCES = $(sources_var)
 ld_new_DEPENDENCIES = $(deps_var)
 ld_new_LDADD = $(ldadd_var)
+ld_new_LDFLAGS = $(ldflags_var)
 EXTRA_ld_new_SOURCES = $(TARGETSOURCES)
 incremental_dump_SOURCES = incremental-dump.cc
 incremental_dump_DEPENDENCIES = $(TARGETOBJS) libgold.a $(LIBIBERTY) \
@@ -601,7 +607,7 @@ incremental-dump$(EXEEXT): $(incremental_dump_OBJECTS) $(incremental_dump_DEPEND
        $(CXXLINK) $(incremental_dump_OBJECTS) $(incremental_dump_LDADD) $(LIBS)
 ld-new$(EXEEXT): $(ld_new_OBJECTS) $(ld_new_DEPENDENCIES) 
        @rm -f ld-new$(EXEEXT)
-       $(CXXLINK) $(ld_new_OBJECTS) $(ld_new_LDADD) $(LIBS)
+       $(ld_new_LINK) $(ld_new_OBJECTS) $(ld_new_LDADD) $(LIBS)
 ld1$(EXEEXT): $(ld1_OBJECTS) $(ld1_DEPENDENCIES) 
        @rm -f ld1$(EXEEXT)
        $(ld1_LINK) $(ld1_OBJECTS) $(ld1_LDADD) $(LIBS)
index e0a91f89ddc968442d85faa0884785c72ef18c47..708f540a23e53ded7980c85f0f2430a48de82676 100755 (executable)
@@ -599,6 +599,8 @@ HAVE_ZLIB_FALSE
 HAVE_ZLIB_TRUE
 LIBOBJS
 LFS_CFLAGS
+GOLD_LDADD
+GOLD_LDFLAGS
 WARN_CXXFLAGS
 NO_WERROR
 WARN_CFLAGS
@@ -777,6 +779,8 @@ enable_dependency_tracking
 enable_nls
 enable_werror
 enable_build_warnings
+with_gold_ldflags
+with_gold_ldadd
 enable_maintainer_mode
 '
       ac_precious_vars='build_alias
@@ -1431,6 +1435,8 @@ Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-sysroot=DIR    search for usr/lib et al within DIR
+  --with-gold-ldflags=FLAGS  additional link flags for gold
+  --with-gold-ldadd=LIBS     additional libraries for gold
 
 Some influential environment variables:
   CC          C compiler command
@@ -6619,6 +6625,34 @@ fi
 WARN_CXXFLAGS=`echo ${WARN_CFLAGS} | sed -e 's/-Wstrict-prototypes//' -e 's/-Wmissing-prototypes//' -e 's/-Wshadow//'`
 
 
+
+# Check whether --with-gold-ldflags was given.
+if test "${with_gold_ldflags+set}" = set; then :
+  withval=$with_gold_ldflags; if test "$withval" = "no" -o "$withval" = "yes"; then
+   GOLD_LDFLAGS=
+ else
+   GOLD_LDFLAGS=$withval
+ fi
+else
+  GOLD_LDFLAGS=
+fi
+
+
+
+
+# Check whether --with-gold-ldadd was given.
+if test "${with_gold_ldadd+set}" = set; then :
+  withval=$with_gold_ldadd; if test "$withval" = "no" -o "$withval" = "yes"; then
+   GOLD_LDADD=
+ else
+   GOLD_LDADD=$withval
+ fi
+else
+  GOLD_LDADD=
+fi
+
+
+
 LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
 
 
index 685e85bbbb0dde760086a47b4da5a03c9f83ad49..905dbaf1c706361406b927409697346ebaa138d3 100644 (file)
@@ -409,6 +409,26 @@ AM_BINUTILS_WARNINGS
 WARN_CXXFLAGS=`echo ${WARN_CFLAGS} | sed -e 's/-Wstrict-prototypes//' -e 's/-Wmissing-prototypes//' -e 's/-Wshadow//'`
 AC_SUBST(WARN_CXXFLAGS)
 
+AC_ARG_WITH(gold-ldflags,
+[  --with-gold-ldflags=FLAGS  additional link flags for gold],
+[if test "$withval" = "no" -o "$withval" = "yes"; then
+   GOLD_LDFLAGS=
+ else
+   GOLD_LDFLAGS=$withval
+ fi],
+[GOLD_LDFLAGS=])
+AC_SUBST(GOLD_LDFLAGS)
+
+AC_ARG_WITH(gold-ldadd,
+[  --with-gold-ldadd=LIBS     additional libraries for gold],
+[if test "$withval" = "no" -o "$withval" = "yes"; then
+   GOLD_LDADD=
+ else
+   GOLD_LDADD=$withval
+ fi],
+[GOLD_LDADD=])
+AC_SUBST(GOLD_LDADD)
+
 dnl Force support for large files by default.  This may need to be
 dnl host dependent.  If build == host, we can check getconf LFS_CFLAGS.
 LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
index 3dc33e4e106362ce9e47640c74e376f033bbe036..2b47a28b1762f0d7de0504474ea08b2821d32707 100644 (file)
@@ -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@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
index e527b5e382cd53be2eda1bd16f330a0ffbfed5a2..e31c151c0d00f31fe86fd6ede452be0e3da38727 100644 (file)
@@ -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@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
index 80ddfbc09f0caf14b69d889eb7195cfed575af93..c5dc320c34e8efb8952bfc05f3be021509a46197 100644 (file)
@@ -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;
index 12f25b7c41a8363e4c2c7bb6e23b142d79e9e679..693ff79b28bea1d4b0e3910bc0ccd7d3abd5540c 100644 (file)
@@ -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
index 445bc68a940127bb70fc1dc9084f6d73cca9bc75..efb6248de1befd3219c1be54811efb260ed7893f 100644 (file)
@@ -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,
index b422827e5a7392bc8108086155a56dcd8835d016..75e44c5707f996cd44719459165fd6bfe5a4c3e3 100644 (file)
@@ -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.
index e6732df5ac9bad7c97c76fa72c28379a2ba2cfe0..56fc52b7533fd20dabf85dd4bfa20e521267f68a 100644 (file)
@@ -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.
index 1c32bcfd06eed6597ae502072a01eb32a0429fca..9d8a43abd1ce35ec2923e0084760dac7f6d36b7b 100644 (file)
@@ -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;
 }
 
index be3264554a416c6eb7b448208b569a0afd4663cd..dcf6ba71ace25c080fa3d479cd09bbf94f1be921 100644 (file)
@@ -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.
 }
 
index 768df9c6eb11116559c877812f71c7e752aa780b..8876a1eedd66bd887c1e919100178350ee970231 100644 (file)
@@ -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.
index 29d8e3d5815d1fed811ff563f3ebeb90c55d919c..a7e1e9adc2d390224f71e3c08378a59a540a7bba 100644 (file)
@@ -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;
index 1bec2c003956f44a30697ca8dec6ab4933405310..e2d35e2bd166a75808c509a3d5f37cccaa9bd76b 100644 (file)
@@ -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.
index 3ccd8d08075d446a05c3cd46f860887411e8b2b1..b4e68f83b02d5b9a7eebec0ec60aeb49d762b197 100644 (file)
@@ -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.
index 45783c3933f81589c1041b384c6da87151e1a187..62a17ca7ac63467beee1e2c3f0d074d0622e4971 100644 (file)
@@ -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
index 1e50942a281c7cba7cdbcbb20c9d0b38c2c4237d..997472284ae5c2730ea73d1dfb0a20707be08bf3 100644 (file)
@@ -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_));
 }
index 03288eccf19ff20bc7aa1388cf533b796484819c..780038aee5ed383912072bf9cdc1b241223013da 100644 (file)
@@ -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);
     }
index 1fad88dd81d8b4193deeec2b3a72aaac19b6e8c8..f90c0b3752d69054f5bd63163570fc10c55d8b50 100644 (file)
@@ -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());
index 7df0c9e9dcc297b41fbcb84c002536b5ee57e2cd..b471cf9583152084b58692254be45fe76d142a7c 100644 (file)
@@ -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);
 }
index 73079a49ac3b82a20911c00cdb540016590e941c..f41f438373948a3494ff5e3dbaae87e8d35026ac 100644 (file)
@@ -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
index 5f67a4e61146cfe841b3e1300eccca2f5f405a21..12e1dee1d64014b1a85d5f3b90f669bf74c0f5b1 100644 (file)
@@ -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
index ff1b5caa36f036c7123afd5c5f8afde7d57d7309..f0ba1d560fb5563d5bfa4d80f358c90ab7307959 100644 (file)
@@ -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@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:
index b9b9e00811e4c32380fa530da51f9e4b20190b25..427f72f5ebfd412a7c518abcb2c9d99a7a5bdc9e 100644 (file)
@@ -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.
index 67149fbb9e7ca21c8b6862cbb4310cc62ec6028d..785dcdd2f2acd1d8f1fa9206c1dfd25fb8ce23cd 100644 (file)
@@ -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@
index a47d22aaa65cb1ca662f3f632d2c4cf5d1ce06ff..293b1f00603cd90fb984cb618e763b3adcdd9345 100755 (executable)
@@ -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"
index 73d39df530ba75c7766d5d4b82a6c72ff924154b..6a0188f8bc4133c7d6b1fefd9b5500d4023ca4bd 100644 (file)
@@ -49,7 +49,7 @@ SECTIONS
     /* This should match the remaining sections.  */
     *(.gold_test)
 
-    . = . + 4;
+    . = 60;
     start_data = .;
     BYTE(1)
     SHORT(2)
index e6b00210762f3effb40adda27e070c9326daa448..e7c981ba6711cfbc2a1ad5190647c36a510f95c5 100644 (file)
@@ -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,