This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
patch committed: Move gold patches to 2.22 branch
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Wed, 02 Nov 2011 22:08:59 -0700
- Subject: patch committed: Move gold patches to 2.22 branch
This patch moves a bunch of changes from mainline gold to the 2.22
branch. Committed to 2.22 branch.
Ian
2011-11-02 Ian Lance Taylor <iant@google.com>
Copy from mainline to binutils 2.22 branch:
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.
Index: Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/Makefile.am,v
retrieving revision 1.62
diff -u -p -r1.62 Makefile.am
--- Makefile.am 27 Apr 2010 16:05:48 -0000 1.62
+++ Makefile.am 3 Nov 2011 05:04:49 -0000
@@ -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: configure.ac
===================================================================
RCS file: /cvs/src/src/gold/configure.ac,v
retrieving revision 1.66
diff -u -p -r1.66 configure.ac
--- configure.ac 14 Sep 2011 01:29:01 -0000 1.66
+++ configure.ac 3 Nov 2011 05:04:50 -0000
@@ -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: expression.cc
===================================================================
RCS file: /cvs/src/src/gold/expression.cc,v
retrieving revision 1.18
diff -u -p -r1.18 expression.cc
--- expression.cc 18 Nov 2010 23:25:08 -0000 1.18
+++ expression.cc 3 Nov 2011 05:04:50 -0000
@@ -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* sym
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_t
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_
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_
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 Expressi
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 Express
eei->dot_value,
eei->dot_section,
section_pointer,
- alignment_pointer);
+ alignment_pointer,
+ false);
}
uint64_t
@@ -350,7 +365,8 @@ class Binary_expression : public Express
eei->dot_value,
eei->dot_section,
section_pointer,
- alignment_pointer);
+ alignment_pointer,
+ false);
}
void
@@ -500,7 +516,8 @@ class Trinary_expression : public Expres
eei->dot_value,
eei->dot_section,
section_pointer,
- NULL);
+ NULL,
+ false);
}
uint64_t
@@ -514,7 +531,8 @@ class Trinary_expression : public Expres
eei->dot_value,
eei->dot_section,
section_pointer,
- alignment_pointer);
+ alignment_pointer,
+ false);
}
uint64_t
@@ -528,7 +546,8 @@ class Trinary_expression : public Expres
eei->dot_value,
eei->dot_section,
section_pointer,
- alignment_pointer);
+ alignment_pointer,
+ false);
}
void
Index: fileread.cc
===================================================================
RCS file: /cvs/src/src/gold/fileread.cc,v
retrieving revision 1.74
diff -u -p -r1.74 fileread.cc
--- fileread.cc 25 May 2011 06:15:28 -0000 1.74
+++ fileread.cc 3 Nov 2011 05:04:50 -0000
@@ -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, sectio
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: gold.cc
===================================================================
RCS file: /cvs/src/src/gold/gold.cc,v
retrieving revision 1.94
diff -u -p -r1.94 gold.cc
--- gold.cc 15 Jul 2011 21:43:08 -0000 1.94
+++ gold.cc 3 Nov 2011 05:04:51 -0000
@@ -197,46 +197,29 @@ queue_initial_tasks(const General_option
// For incremental links, the base output file.
Incremental_binary* ibase = NULL;
- if (parameters->incremental())
+ if (parameters->incremental_update())
{
- 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())
+ 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: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.141
diff -u -p -r1.141 i386.cc
--- i386.cc 15 Jul 2011 15:31:54 -0000 1.141
+++ i386.cc 3 Nov 2011 05:04:51 -0000
@@ -2709,12 +2709,6 @@ Target_i386::Relocate::relocate_tls(cons
}
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;
Index: incremental.cc
===================================================================
RCS file: /cvs/src/src/gold/incremental.cc,v
retrieving revision 1.47
diff -u -p -r1.47 incremental.cc
--- incremental.cc 19 Sep 2011 19:29:55 -0000 1.47
+++ incremental.cc 3 Nov 2011 05:04:52 -0000
@@ -685,7 +685,7 @@ Sized_incremental_binary<size, big_endia
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>::Siz
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_
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_
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>::Siz
: 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_
// 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_
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: incremental.h
===================================================================
RCS file: /cvs/src/src/gold/incremental.h,v
retrieving revision 1.28
diff -u -p -r1.28 incremental.h
--- incremental.h 19 Sep 2011 19:29:55 -0000 1.28
+++ incremental.h 3 Nov 2011 05:04:52 -0000
@@ -1996,6 +1996,8 @@ class Sized_relobj_incr : public Sized_r
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: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.220
diff -u -p -r1.220 layout.cc
--- layout.cc 18 Sep 2011 15:06:28 -0000 1.220
+++ layout.cc 3 Nov 2011 05:04:53 -0000
@@ -2975,8 +2975,9 @@ Layout::segment_precedes(const Output_se
// 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: options.cc
===================================================================
RCS file: /cvs/src/src/gold/options.cc,v
retrieving revision 1.114
diff -u -p -r1.114 options.cc
--- options.cc 11 Jul 2011 16:19:51 -0000 1.114
+++ options.cc 3 Nov 2011 05:04:53 -0000
@@ -198,7 +198,7 @@ parse_uint(const char* option_name, cons
{
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: options.h
===================================================================
RCS file: /cvs/src/src/gold/options.h,v
retrieving revision 1.169
diff -u -p -r1.169 options.h
--- options.h 15 Jul 2011 21:43:08 -0000 1.169
+++ options.h 3 Nov 2011 05:04:53 -0000
@@ -787,6 +787,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"));
@@ -1381,6 +1385,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: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.159
diff -u -p -r1.159 output.cc
--- output.cc 10 Sep 2011 05:15:43 -0000 1.159
+++ output.cc 3 Nov 2011 05:04:54 -0000
@@ -119,7 +119,9 @@ extern "C" void *gold_mremap(void *, siz
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, s
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, s
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, s
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, s
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, s
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, s
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, s
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, s
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, s
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, s
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, s
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*
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 writa
// 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: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.128
diff -u -p -r1.128 output.h
--- output.h 27 Aug 2011 01:28:18 -0000 1.128
+++ output.h 3 Nov 2011 05:04:55 -0000
@@ -1033,12 +1033,14 @@ class Output_reloc<elfcpp::SHT_REL, dyna
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, dyna
// 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, dyna
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, dyn
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, dyn
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,
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,
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,
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,
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,
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,
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,
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,
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
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
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
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
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
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
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
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: plugin.cc
===================================================================
RCS file: /cvs/src/src/gold/plugin.cc,v
retrieving revision 1.48.2.1
diff -u -p -r1.48.2.1 plugin.cc
--- plugin.cc 25 Oct 2011 02:43:14 -0000 1.48.2.1
+++ plugin.cc 3 Nov 2011 05:04:55 -0000
@@ -818,7 +818,9 @@ Pluginobj::Pluginobj(const std::string&
}
// 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_in
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: powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.39
diff -u -p -r1.39 powerpc.cc
--- powerpc.cc 28 Jun 2011 23:12:31 -0000 1.39
+++ powerpc.cc 3 Nov 2011 05:04:55 -0000
@@ -1329,7 +1329,7 @@ Target_powerpc<size, big_endian>::Scan::
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::
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: readsyms.cc
===================================================================
RCS file: /cvs/src/src/gold/readsyms.cc,v
retrieving revision 1.51
diff -u -p -r1.51 readsyms.cc
--- readsyms.cc 14 Jul 2011 00:55:18 -0000 1.51
+++ readsyms.cc 3 Nov 2011 05:04:55 -0000
@@ -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: resolve.cc
===================================================================
RCS file: /cvs/src/src/gold/resolve.cc,v
retrieving revision 1.63
diff -u -p -r1.63 resolve.cc
--- resolve.cc 8 Jul 2011 23:49:11 -0000 1.63
+++ resolve.cc 3 Nov 2011 05:04:55 -0000
@@ -296,7 +296,7 @@ Symbol_table::resolve(Sized_symbol<size>
// 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
Index: script-sections.cc
===================================================================
RCS file: /cvs/src/src/gold/script-sections.cc,v
retrieving revision 1.53
diff -u -p -r1.53 script-sections.cc
--- script-sections.cc 29 Jun 2011 00:39:54 -0000 1.53
+++ script-sections.cc 3 Nov 2011 05:04:56 -0000
@@ -680,7 +680,7 @@ class Sections_element_assignment : publ
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 :
// 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 :
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
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_assignm
: 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::s
{
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_buff
{
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 : publ
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_symb
{
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_a
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_a
{
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_a
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_a
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_a
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: script.cc
===================================================================
RCS file: /cvs/src/src/gold/script.cc,v
retrieving revision 1.84
diff -u -p -r1.84 script.cc
--- script.cc 29 Jun 2011 21:57:14 -0000 1.84
+++ script.cc 3 Nov 2011 05:04:57 -0000
@@ -983,18 +983,20 @@ Symbol_assignment::sized_finalize(Symbol
uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true,
is_dot_available,
dot_value, dot_section,
- §ion, NULL);
+ §ion, NULL, false);
Sized_symbol<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(Symbo
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(Symbo
}
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(Sy
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: script.h
===================================================================
RCS file: /cvs/src/src/gold/script.h,v
retrieving revision 1.37
diff -u -p -r1.37 script.h
--- script.h 12 Apr 2011 00:44:48 -0000 1.37
+++ script.h 3 Nov 2011 05:04:57 -0000
@@ -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: sparc.cc
===================================================================
RCS file: /cvs/src/src/gold/sparc.cc,v
retrieving revision 1.48.2.1
diff -u -p -r1.48.2.1 sparc.cc
--- sparc.cc 19 Oct 2011 00:38:54 -0000 1.48.2.1
+++ sparc.cc 3 Nov 2011 05:04:57 -0000
@@ -1855,7 +1855,7 @@ Target_sparc<size, big_endian>::Scan::lo
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::lo
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: symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.159.2.1
diff -u -p -r1.159.2.1 symtab.cc
--- symtab.cc 28 Sep 2011 00:55:46 -0000 1.159.2.1
+++ symtab.cc 3 Nov 2011 05:04:57 -0000
@@ -602,20 +602,16 @@ Symbol_table::gc_mark_undef_symbols(Layo
}
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* s
{
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
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: symtab.h
===================================================================
RCS file: /cvs/src/src/gold/symtab.h,v
retrieving revision 1.125
diff -u -p -r1.125 symtab.h
--- symtab.h 22 Jul 2011 22:38:42 -0000 1.125
+++ symtab.h 3 Nov 2011 05:04:58 -0000
@@ -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: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.139
diff -u -p -r1.139 x86_64.cc
--- x86_64.cc 15 Jul 2011 15:31:54 -0000 1.139
+++ x86_64.cc 3 Nov 2011 05:04:58 -0000
@@ -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*
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*
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*
// 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*
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(co
}
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);
Index: testsuite/plugin_test_2.sh
===================================================================
RCS file: /cvs/src/src/gold/testsuite/plugin_test_2.sh,v
retrieving revision 1.2
diff -u -p -r1.2 plugin_test_2.sh
--- testsuite/plugin_test_2.sh 15 Jan 2009 01:29:25 -0000 1.2
+++ testsuite/plugin_test_2.sh 3 Nov 2011 05:04:59 -0000
@@ -45,7 +45,7 @@ check plugin_test_2.err "two_file_test_m
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: testsuite/script_test_2.t
===================================================================
RCS file: /cvs/src/src/gold/testsuite/script_test_2.t,v
retrieving revision 1.3
diff -u -p -r1.3 script_test_2.t
--- testsuite/script_test_2.t 29 Jul 2008 22:58:03 -0000 1.3
+++ testsuite/script_test_2.t 3 Nov 2011 05:04:59 -0000
@@ -49,7 +49,7 @@ SECTIONS
/* This should match the remaining sections. */
*(.gold_test)
- . = . + 4;
+ . = 60;
start_data = .;
BYTE(1)
SHORT(2)