summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2012-09-23 19:46:17 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-09-24 12:13:48 +0100
commitd4384e126a95b1bf7bc9ef53a3c902a8057127e8 (patch)
tree3ec4b6845b932fbde0647704c7ea96ffb313059f
parent0fb184d7dfca33f09b9248ee380b5b4f24cdf79c (diff)
downloadpoky-d4384e126a95b1bf7bc9ef53a3c902a8057127e8.tar.gz
binutils-2.22: Disable recent gold backports from 2.22 branch
This patch has been causing some regressions on gold. e.g. systemd based images segfault and uclibc based images dont boot. There has been few other reports on the mailing list. Considering this lets withdraw this patch. (From OE-Core rev: ecbe671de1553956f83798e1c6fa3ec2fc6a7b4e) Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.22.inc3
-rw-r--r--meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch1944
2 files changed, 1 insertions, 1946 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.22.inc b/meta/recipes-devtools/binutils/binutils-2.22.inc
index 42dc6b78b5..9697242379 100644
--- a/meta/recipes-devtools/binutils/binutils-2.22.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.22.inc
@@ -1,4 +1,4 @@
1PR = "r16" 1PR = "r17"
2 2
3LIC_FILES_CHKSUM="\ 3LIC_FILES_CHKSUM="\
4 file://src-release;endline=17;md5=4830a9ef968f3b18dd5e9f2c00db2d35\ 4 file://src-release;endline=17;md5=4830a9ef968f3b18dd5e9f2c00db2d35\
@@ -38,7 +38,6 @@ SRC_URI = "\
38 file://0035-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \ 38 file://0035-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \
39 file://0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \ 39 file://0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \
40 file://0037-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \ 40 file://0037-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \
41 file://0038-Copy-from-mainline-to-binutils-2.22-branch.patch \
42 file://0039-emulparams-elf32bmip.sh-OTHER_SECTIONS-Put-.mdebug.-.patch \ 41 file://0039-emulparams-elf32bmip.sh-OTHER_SECTIONS-Put-.mdebug.-.patch \
43 file://0052-gas.patch \ 42 file://0052-gas.patch \
44 file://0055-Remove-ABI_64_P-check-on-R_X86_64_PCXX.patch \ 43 file://0055-Remove-ABI_64_P-check-on-R_X86_64_PCXX.patch \
diff --git a/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch b/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch
deleted file mode 100644
index 453ef2211c..0000000000
--- a/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch
+++ /dev/null
@@ -1,1944 +0,0 @@
1Upstream-Status: Backport
2
3From 624da0376264205e399bc14fe2fa7b6fa659d0ee Mon Sep 17 00:00:00 2001
4From: Ian Lance Taylor <ian@airs.com>
5Date: Mon, 19 Dec 2011 21:14:39 +0000
6Subject: [PATCH 038/262] Copy from mainline to binutils 2.22 branch:
7
8 2011-12-17 Cary Coutant <ccoutant@google.com>
9
10 * dwarf_reader.cc (Sized_dwarf_line_info::read_lines): Add casts.
11 * resolve.cc (Symbol_table::resolve): Likewise.
12 * i386.cc (Target_i386::do_code_fill): Use char constants for nop
13 arrays.
14 * x86_64.cc (Target_x86_64::do_code_fill): Likewise.
15
16 2011-10-31 Cary Coutant <ccoutant@google.com>
17
18 PR gold/13023
19 * expression.cc (Expression::eval_with_dot): Add
20 is_section_dot_assignment parameter.
21 (Expression::eval_maybe_dot): Likewise. Adjust value when rhs is
22 absolute and assigning to dot within a section.
23 * script-sections.cc
24 (Output_section_element_assignment::set_section_addresses): Pass
25 dot_section to set_if_absolute.
26 (Output_section_element_dot_assignment::finalize_symbols): Pass TRUE
27 as is_section_dot_assignment flag to eval_with_dot.
28 (Output_section_element_dot_assignment::set_section_addresses):
29 Likewise.
30 * script.cc (Symbol_assignment::set_if_absolute): Add dot_section
31 parameter. Also set value if relative to dot_section; set the
32 symbol's output_section.
33 * script.h (Expression::eval_with_dot): Add is_section_dot_assignment
34 parameter. Adjust all callers.
35 (Expression::eval_maybe_dot): Likewise.
36 (Symbol_assignment::set_if_absolute): Add dot_section parameter.
37 Adjust all callers.
38 * testsuite/script_test_2.t: Test assignment of an absolute value
39 to dot within an output section element.
40
41 2011-10-31 Cary Coutant <ccoutant@google.com>
42
43 * options.h (class General_options): Add --[no-]gnu-unique options.
44 * symtab.cc (Symbol_table::sized_write_globals): Convert
45 STB_GNU_UNIQUE to STB_GLOBAL if --no-gnu-unique.
46
47 2011-10-31 Cary Coutant <ccoutant@google.com>
48
49 PR gold/13359
50 * i386.cc (Target_i386::Relocate::relocate_tls): Remove
51 unnecessary assertion.
52 * x86_64.cc (Target_x86_64::Relocate::relocate_tls): Likewise.
53
54 2011-10-31 Sriraman Tallam <tmsriram@google.com>
55
56 * symtab.h (Symbol_table::gc_mark_symbol_for_shlib): Rename to
57 gc_mark_symbol.
58 * symtab.cc (Symbol_table::gc_mark_symbol_for_shlib): Rename to
59 gc_mark_symbol.
60 Change to just keep the section associated with symbol.
61 (Symbol_table::add_from_relobj): Mark symbols as not garbage when
62 they are externally visible and --export-dynamic is turned on.
63 (Symbol_table::gc_mark_dyn_syms): Call gc_mark_symbol.
64
65 2011-10-19 Ian Lance Taylor <iant@google.com>
66
67 PR gold/13163
68 * script-sections.cc
69 (Output_section_element_dot_assignment::needs_output_section): New
70 function.
71
72 2011-10-19 Ian Lance Taylor <iant@google.com>
73
74 PR gold/13204
75 * layout.cc (Layout::segment_precedes): Don't assert failure if a
76 --section-start option was seen.
77 * options.h (General_options::any_section_start): New function.
78
79 2011-10-18 Cary Coutant <ccoutant@google.com>
80
81 * output.cc (posix_fallocate): Return 0 on success, errno on failure.
82 (Output_file::map_no_anonymous): Check for non-zero
83 return code from posix_fallocate.
84
85 2011-10-17 Cary Coutant <ccoutant@google.com>
86
87 PR gold/13245
88 * plugin.cc (is_visible_from_outside): Check for symbols
89 referenced from dynamic objects.
90 * resolve.cc (Symbol_table::resolve): Don't count references
91 from dynamic objects as references from real ELF files.
92 * testsuite/plugin_test_2.sh: Adjust expected result.
93
94 2011-10-17 Cary Coutant <ccoutant@google.com>
95
96 * readsyms.cc (Read_symbols::run): Don't queue an unblocker
97 task for members of lib groups.
98
99 2011-10-17 Cary Coutant <ccoutant@google.com>
100
101 PR gold/13288
102 * fileread.cc (File_read::find_view): Add assert.
103 (File_read::make_view): Move bounds check (replace with assert)...
104 (File_read::find_or_make_view): ... to here.
105
106 2011-10-12 Cary Coutant <ccoutant@google.com>
107
108 * output.cc (Output_file::open_base_file): Handle case where
109 ::read returns less than requested size.
110
111 2011-10-10 Cary Coutant <ccoutant@google.com>
112
113 * incremental.cc (Sized_relobj_incr::Sized_relobj_incr):
114 Initialize defined_count_.
115 (Sized_relobj_incr::do_add_symbols): Count defined symbols.
116 (Sized_relobj_incr::do_get_global_symbol_counts): Rewrite.
117 (Sized_incr_dynobj::Sized_incr_dynobj): Initialize defined_count_.
118 (Sized_incr_dynobj::do_add_symbols): Count defined symbols.
119 (Sized_incr_dynobj::do_get_global_symbol_counts): Rewrite.
120 * incremental.h (Sized_relobj_incr::defined_count_): New data
121 member.
122 (Sized_incr_dynobj::defined_count_): New data member.
123 * plugin.cc (Sized_pluginobj::do_get_global_symbol_counts):
124 Return zeroes instead of internal error.
125
126 2011-10-10 Cary Coutant <ccoutant@google.com>
127
128 PR gold/13249
129 * output.cc (Output_reloc::Output_reloc): Add use_plt_offset flag.
130 (Output_reloc::symbol_value): Return PLT offset if flag is set.
131 * output.h (class Output_reloc): Add use_plt_offset flag.
132 (Output_reloc::type_): Adjust size of bit field.
133 (Output_reloc::use_plt_offset_): New bit field.
134 (class Output_data_reloc): Adjust all calls to Output_reloc_type.
135 (Output_data_reloc::add_local_relative): (RELA only) Add use_plt_offset
136 flag. Adjust all callers.
137 * x86_64.cc (Target_x86_64::Scan::local): Check for IFUNC when
138 creating RELATIVE relocations.
139
140 2011-10-03 Diego Novillo <dnovillo@google.com>
141
142 * options.cc (parse_uint): Fix dereference of RETVAL.
143
144 2011-09-29 Cary Coutant <ccoutant@google.com>
145
146 * incremental.cc (Sized_incremental_binary::do_process_got_plt):
147 Check for NULL.
148 * symtab.cc (Symbol_table::add_from_relobj): Ignore version
149 symbols during incremental update.
150 (Symbol_table::add_from_dynobj): Likewise.
151
152 2011-09-26 Cary Coutant <ccoutant@google.com>
153
154 * gold.cc (queue_initial_tasks): Move option checks ...
155 * options.cc (General_options::finalize): ... to here. Disable
156 some options; make others fatal.
157
158 2011-09-23 Simon Baldwin <simonb@google.com>
159
160 * configure.ac: Add new --with-gold-ldadd and --with-gold-ldflags
161 configuration options.
162 * configure: Regenerate.
163 * Makefile.am: Handle GOLD_LDADD and GOLD_LDFLAGS.
164 * Makefile.in: Regenerate.
165 * testsuite/Makefile.in: Regenerate.
166---
167 gold/ChangeLog | 163 +++++++++++++++++++++++++++++++++++++++
168 gold/dwarf_reader.cc | 8 +-
169 gold/expression.cc | 45 +++++++----
170 gold/fileread.cc | 27 ++++---
171 gold/gold.cc | 55 +++++--------
172 gold/i386.cc | 87 +++++++++++----------
173 gold/incremental.cc | 50 +++++++++---
174 gold/incremental.h | 4 +
175 gold/layout.cc | 5 +-
176 gold/options.cc | 33 +++++++-
177 gold/options.h | 9 +++
178 gold/output.cc | 78 ++++++++++++-------
179 gold/output.h | 64 +++++++++------
180 gold/plugin.cc | 18 +++--
181 gold/powerpc.cc | 4 +-
182 gold/readsyms.cc | 6 +-
183 gold/resolve.cc | 6 +-
184 gold/script-sections.cc | 47 +++++++----
185 gold/script.cc | 17 ++--
186 gold/script.h | 24 ++++--
187 gold/sparc.cc | 4 +-
188 gold/symtab.cc | 65 +++++++++-------
189 gold/symtab.h | 5 +-
190 gold/testsuite/Makefile.in | 2 +
191 gold/testsuite/plugin_test_2.sh | 2 +-
192 gold/testsuite/script_test_2.t | 2 +-
193 gold/x86_64.cc | 99 ++++++++++++------------
194 27 files changed, 636 insertions(+), 293 deletions(-)
195
196diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc
197index 3dc33e4..2b47a28 100644
198--- a/gold/dwarf_reader.cc
199+++ b/gold/dwarf_reader.cc
200@@ -1,6 +1,6 @@
201 // dwarf_reader.cc -- parse dwarf2/3 debug information
202
203-// Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
204+// Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
205 // Written by Ian Lance Taylor <iant@google.com>.
206
207 // This file is part of gold.
208@@ -491,8 +491,10 @@ Sized_dwarf_line_info<size, big_endian>::read_lines(unsigned const char* lineptr
209 && (shndx == -1U || lsm.shndx == -1U || shndx == lsm.shndx))
210 {
211 Offset_to_lineno_entry entry
212- = { lsm.address, this->current_header_index_,
213- lsm.file_num, true, lsm.line_num };
214+ = { static_cast<off_t>(lsm.address),
215+ this->current_header_index_,
216+ static_cast<unsigned int>(lsm.file_num),
217+ true, lsm.line_num };
218 std::vector<Offset_to_lineno_entry>&
219 map(this->line_number_map_[lsm.shndx]);
220 // If we see two consecutive entries with the same
221diff --git a/gold/expression.cc b/gold/expression.cc
222index e527b5e..e31c151 100644
223--- a/gold/expression.cc
224+++ b/gold/expression.cc
225@@ -1,6 +1,6 @@
226 // expression.cc -- expressions in linker scripts for gold
227
228-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
229+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
230 // Written by Ian Lance Taylor <iant@google.com>.
231
232 // This file is part of gold.
233@@ -77,7 +77,7 @@ Expression::eval(const Symbol_table* symtab, const Layout* layout,
234 bool check_assertions)
235 {
236 return this->eval_maybe_dot(symtab, layout, check_assertions,
237- false, 0, NULL, NULL, NULL);
238+ false, 0, NULL, NULL, NULL, false);
239 }
240
241 // Evaluate an expression which may refer to the dot symbol.
242@@ -87,11 +87,13 @@ Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout,
243 bool check_assertions, uint64_t dot_value,
244 Output_section* dot_section,
245 Output_section** result_section_pointer,
246- uint64_t* result_alignment_pointer)
247+ uint64_t* result_alignment_pointer,
248+ bool is_section_dot_assignment)
249 {
250 return this->eval_maybe_dot(symtab, layout, check_assertions, true,
251 dot_value, dot_section, result_section_pointer,
252- result_alignment_pointer);
253+ result_alignment_pointer,
254+ is_section_dot_assignment);
255 }
256
257 // Evaluate an expression which may or may not refer to the dot
258@@ -102,7 +104,8 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout,
259 bool check_assertions, bool is_dot_available,
260 uint64_t dot_value, Output_section* dot_section,
261 Output_section** result_section_pointer,
262- uint64_t* result_alignment_pointer)
263+ uint64_t* result_alignment_pointer,
264+ bool is_section_dot_assignment)
265 {
266 Expression_eval_info eei;
267 eei.symtab = symtab;
268@@ -113,14 +116,24 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout,
269 eei.dot_section = dot_section;
270
271 // We assume the value is absolute, and only set this to a section
272- // if we find a section relative reference.
273+ // if we find a section-relative reference.
274 if (result_section_pointer != NULL)
275 *result_section_pointer = NULL;
276 eei.result_section_pointer = result_section_pointer;
277
278 eei.result_alignment_pointer = result_alignment_pointer;
279
280- return this->value(&eei);
281+ uint64_t val = this->value(&eei);
282+
283+ // If this is an assignment to dot within a section, and the value
284+ // is absolute, treat it as a section-relative offset.
285+ if (is_section_dot_assignment && *result_section_pointer == NULL)
286+ {
287+ gold_assert(dot_section != NULL);
288+ val += dot_section->address();
289+ *result_section_pointer = dot_section;
290+ }
291+ return val;
292 }
293
294 // A number.
295@@ -257,7 +270,8 @@ class Unary_expression : public Expression
296 eei->dot_value,
297 eei->dot_section,
298 arg_section_pointer,
299- eei->result_alignment_pointer);
300+ eei->result_alignment_pointer,
301+ false);
302 }
303
304 void
305@@ -336,7 +350,8 @@ class Binary_expression : public Expression
306 eei->dot_value,
307 eei->dot_section,
308 section_pointer,
309- alignment_pointer);
310+ alignment_pointer,
311+ false);
312 }
313
314 uint64_t
315@@ -350,7 +365,8 @@ class Binary_expression : public Expression
316 eei->dot_value,
317 eei->dot_section,
318 section_pointer,
319- alignment_pointer);
320+ alignment_pointer,
321+ false);
322 }
323
324 void
325@@ -500,7 +516,8 @@ class Trinary_expression : public Expression
326 eei->dot_value,
327 eei->dot_section,
328 section_pointer,
329- NULL);
330+ NULL,
331+ false);
332 }
333
334 uint64_t
335@@ -514,7 +531,8 @@ class Trinary_expression : public Expression
336 eei->dot_value,
337 eei->dot_section,
338 section_pointer,
339- alignment_pointer);
340+ alignment_pointer,
341+ false);
342 }
343
344 uint64_t
345@@ -528,7 +546,8 @@ class Trinary_expression : public Expression
346 eei->dot_value,
347 eei->dot_section,
348 section_pointer,
349- alignment_pointer);
350+ alignment_pointer,
351+ false);
352 }
353
354 void
355diff --git a/gold/fileread.cc b/gold/fileread.cc
356index 80ddfbc..c5dc320 100644
357--- a/gold/fileread.cc
358+++ b/gold/fileread.cc
359@@ -329,6 +329,10 @@ inline File_read::View*
360 File_read::find_view(off_t start, section_size_type size,
361 unsigned int byteshift, File_read::View** vshifted) const
362 {
363+ gold_assert(start <= this->size_
364+ && (static_cast<unsigned long long>(size)
365+ <= static_cast<unsigned long long>(this->size_ - start)));
366+
367 if (vshifted != NULL)
368 *vshifted = NULL;
369
370@@ -456,16 +460,9 @@ File_read::make_view(off_t start, section_size_type size,
371 unsigned int byteshift, bool cache)
372 {
373 gold_assert(size > 0);
374-
375- // Check that start and end of the view are within the file.
376- if (start > this->size_
377- || (static_cast<unsigned long long>(size)
378- > static_cast<unsigned long long>(this->size_ - start)))
379- gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds "
380- "size of file; the file may be corrupt"),
381- this->filename().c_str(),
382- static_cast<long long>(size),
383- static_cast<long long>(start));
384+ gold_assert(start <= this->size_
385+ && (static_cast<unsigned long long>(size)
386+ <= static_cast<unsigned long long>(this->size_ - start)));
387
388 off_t poff = File_read::page_offset(start);
389
390@@ -523,6 +520,16 @@ File_read::View*
391 File_read::find_or_make_view(off_t offset, off_t start,
392 section_size_type size, bool aligned, bool cache)
393 {
394+ // Check that start and end of the view are within the file.
395+ if (start > this->size_
396+ || (static_cast<unsigned long long>(size)
397+ > static_cast<unsigned long long>(this->size_ - start)))
398+ gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds "
399+ "size of file; the file may be corrupt"),
400+ this->filename().c_str(),
401+ static_cast<long long>(size),
402+ static_cast<long long>(start));
403+
404 unsigned int byteshift;
405 if (offset == 0)
406 byteshift = 0;
407diff --git a/gold/gold.cc b/gold/gold.cc
408index 12f25b7..693ff79 100644
409--- a/gold/gold.cc
410+++ b/gold/gold.cc
411@@ -197,46 +197,29 @@ queue_initial_tasks(const General_options& options,
412 // For incremental links, the base output file.
413 Incremental_binary* ibase = NULL;
414
415- if (parameters->incremental())
416- {
417- if (options.relocatable())
418- gold_error(_("incremental linking is incompatible with -r"));
419- if (options.emit_relocs())
420- gold_error(_("incremental linking is incompatible with --emit-relocs"));
421- if (options.gc_sections())
422- gold_error(_("incremental linking is incompatible with --gc-sections"));
423- if (options.icf_enabled())
424- gold_error(_("incremental linking is incompatible with --icf"));
425- if (options.has_plugins())
426- gold_error(_("incremental linking is incompatible with --plugin"));
427- if (strcmp(options.compress_debug_sections(), "none") != 0)
428- gold_error(_("incremental linking is incompatible with "
429- "--compress-debug-sections"));
430-
431- if (parameters->incremental_update())
432+ if (parameters->incremental_update())
433+ {
434+ Output_file* of = new Output_file(options.output_file_name());
435+ if (of->open_base_file(options.incremental_base(), true))
436 {
437- Output_file* of = new Output_file(options.output_file_name());
438- if (of->open_base_file(options.incremental_base(), true))
439- {
440- ibase = open_incremental_binary(of);
441- if (ibase != NULL
442- && ibase->check_inputs(cmdline, layout->incremental_inputs()))
443- ibase->init_layout(layout);
444- else
445- {
446- delete ibase;
447- ibase = NULL;
448- of->close();
449- }
450- }
451- if (ibase == NULL)
452+ ibase = open_incremental_binary(of);
453+ if (ibase != NULL
454+ && ibase->check_inputs(cmdline, layout->incremental_inputs()))
455+ ibase->init_layout(layout);
456+ else
457 {
458- if (set_parameters_incremental_full())
459- gold_info(_("linking with --incremental-full"));
460- else
461- gold_fallback(_("restart link with --incremental-full"));
462+ delete ibase;
463+ ibase = NULL;
464+ of->close();
465 }
466 }
467+ if (ibase == NULL)
468+ {
469+ if (set_parameters_incremental_full())
470+ gold_info(_("linking with --incremental-full"));
471+ else
472+ gold_fallback(_("restart link with --incremental-full"));
473+ }
474 }
475
476 // Read the input files. We have to add the symbols to the symbol
477diff --git a/gold/i386.cc b/gold/i386.cc
478index 445bc68..efb6248 100644
479--- a/gold/i386.cc
480+++ b/gold/i386.cc
481@@ -2709,12 +2709,6 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
482 }
483 if (optimized_type == tls::TLSOPT_TO_IE)
484 {
485- if (tls_segment == NULL)
486- {
487- gold_assert(parameters->errors()->error_count() > 0
488- || issue_undefined_symbol_error(gsym));
489- return;
490- }
491 this->tls_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type,
492 got_offset, view, view_size);
493 break;
494@@ -3480,42 +3474,51 @@ Target_i386::do_code_fill(section_size_type length) const
495 }
496
497 // Nop sequences of various lengths.
498- const char nop1[1] = { 0x90 }; // nop
499- const char nop2[2] = { 0x66, 0x90 }; // xchg %ax %ax
500- const char nop3[3] = { 0x8d, 0x76, 0x00 }; // leal 0(%esi),%esi
501- const char nop4[4] = { 0x8d, 0x74, 0x26, 0x00}; // leal 0(%esi,1),%esi
502- const char nop5[5] = { 0x90, 0x8d, 0x74, 0x26, // nop
503- 0x00 }; // leal 0(%esi,1),%esi
504- const char nop6[6] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi
505- 0x00, 0x00 };
506- const char nop7[7] = { 0x8d, 0xb4, 0x26, 0x00, // leal 0L(%esi,1),%esi
507- 0x00, 0x00, 0x00 };
508- const char nop8[8] = { 0x90, 0x8d, 0xb4, 0x26, // nop
509- 0x00, 0x00, 0x00, 0x00 }; // leal 0L(%esi,1),%esi
510- const char nop9[9] = { 0x89, 0xf6, 0x8d, 0xbc, // movl %esi,%esi
511- 0x27, 0x00, 0x00, 0x00, // leal 0L(%edi,1),%edi
512- 0x00 };
513- const char nop10[10] = { 0x8d, 0x76, 0x00, 0x8d, // leal 0(%esi),%esi
514- 0xbc, 0x27, 0x00, 0x00, // leal 0L(%edi,1),%edi
515- 0x00, 0x00 };
516- const char nop11[11] = { 0x8d, 0x74, 0x26, 0x00, // leal 0(%esi,1),%esi
517- 0x8d, 0xbc, 0x27, 0x00, // leal 0L(%edi,1),%edi
518- 0x00, 0x00, 0x00 };
519- const char nop12[12] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi
520- 0x00, 0x00, 0x8d, 0xbf, // leal 0L(%edi),%edi
521- 0x00, 0x00, 0x00, 0x00 };
522- const char nop13[13] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi
523- 0x00, 0x00, 0x8d, 0xbc, // leal 0L(%edi,1),%edi
524- 0x27, 0x00, 0x00, 0x00,
525- 0x00 };
526- const char nop14[14] = { 0x8d, 0xb4, 0x26, 0x00, // leal 0L(%esi,1),%esi
527- 0x00, 0x00, 0x00, 0x8d, // leal 0L(%edi,1),%edi
528- 0xbc, 0x27, 0x00, 0x00,
529- 0x00, 0x00 };
530- const char nop15[15] = { 0xeb, 0x0d, 0x90, 0x90, // jmp .+15
531- 0x90, 0x90, 0x90, 0x90, // nop,nop,nop,...
532- 0x90, 0x90, 0x90, 0x90,
533- 0x90, 0x90, 0x90 };
534+ const char nop1[1] = { '\x90' }; // nop
535+ const char nop2[2] = { '\x66', '\x90' }; // xchg %ax %ax
536+ const char nop3[3] = { '\x8d', '\x76', '\x00' }; // leal 0(%esi),%esi
537+ const char nop4[4] = { '\x8d', '\x74', '\x26', // leal 0(%esi,1),%esi
538+ '\x00'};
539+ const char nop5[5] = { '\x90', '\x8d', '\x74', // nop
540+ '\x26', '\x00' }; // leal 0(%esi,1),%esi
541+ const char nop6[6] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi
542+ '\x00', '\x00', '\x00' };
543+ const char nop7[7] = { '\x8d', '\xb4', '\x26', // leal 0L(%esi,1),%esi
544+ '\x00', '\x00', '\x00',
545+ '\x00' };
546+ const char nop8[8] = { '\x90', '\x8d', '\xb4', // nop
547+ '\x26', '\x00', '\x00', // leal 0L(%esi,1),%esi
548+ '\x00', '\x00' };
549+ const char nop9[9] = { '\x89', '\xf6', '\x8d', // movl %esi,%esi
550+ '\xbc', '\x27', '\x00', // leal 0L(%edi,1),%edi
551+ '\x00', '\x00', '\x00' };
552+ const char nop10[10] = { '\x8d', '\x76', '\x00', // leal 0(%esi),%esi
553+ '\x8d', '\xbc', '\x27', // leal 0L(%edi,1),%edi
554+ '\x00', '\x00', '\x00',
555+ '\x00' };
556+ const char nop11[11] = { '\x8d', '\x74', '\x26', // leal 0(%esi,1),%esi
557+ '\x00', '\x8d', '\xbc', // leal 0L(%edi,1),%edi
558+ '\x27', '\x00', '\x00',
559+ '\x00', '\x00' };
560+ const char nop12[12] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi
561+ '\x00', '\x00', '\x00', // leal 0L(%edi),%edi
562+ '\x8d', '\xbf', '\x00',
563+ '\x00', '\x00', '\x00' };
564+ const char nop13[13] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi
565+ '\x00', '\x00', '\x00', // leal 0L(%edi,1),%edi
566+ '\x8d', '\xbc', '\x27',
567+ '\x00', '\x00', '\x00',
568+ '\x00' };
569+ const char nop14[14] = { '\x8d', '\xb4', '\x26', // leal 0L(%esi,1),%esi
570+ '\x00', '\x00', '\x00', // leal 0L(%edi,1),%edi
571+ '\x00', '\x8d', '\xbc',
572+ '\x27', '\x00', '\x00',
573+ '\x00', '\x00' };
574+ const char nop15[15] = { '\xeb', '\x0d', '\x90', // jmp .+15
575+ '\x90', '\x90', '\x90', // nop,nop,nop,...
576+ '\x90', '\x90', '\x90',
577+ '\x90', '\x90', '\x90',
578+ '\x90', '\x90', '\x90' };
579
580 const char* nops[16] = {
581 NULL,
582diff --git a/gold/incremental.cc b/gold/incremental.cc
583index b422827..75e44c5 100644
584--- a/gold/incremental.cc
585+++ b/gold/incremental.cc
586@@ -685,7 +685,7 @@ Sized_incremental_binary<size, big_endian>::do_process_got_plt(
587 gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
588 Symbol* sym = this->global_symbol(plt_desc - first_global);
589 // Add the PLT entry only if the symbol is still referenced.
590- if (sym->in_reg())
591+ if (sym != NULL && sym->in_reg())
592 {
593 gold_debug(DEBUG_INCREMENTAL,
594 "PLT entry %d: %s",
595@@ -1966,8 +1966,9 @@ Sized_relobj_incr<size, big_endian>::Sized_relobj_incr(
596 input_reader_(ibase->inputs_reader().input_file(input_file_index)),
597 local_symbol_count_(0), output_local_dynsym_count_(0),
598 local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0),
599- symbols_(), incr_reloc_offset_(-1U), incr_reloc_count_(0),
600- incr_reloc_output_index_(0), incr_relocs_(NULL), local_symbols_()
601+ symbols_(), defined_count_(0), incr_reloc_offset_(-1U),
602+ incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL),
603+ local_symbols_()
604 {
605 if (this->input_reader_.is_in_system_directory())
606 this->set_is_in_system_directory();
607@@ -2120,6 +2121,9 @@ Sized_relobj_incr<size, big_endian>::do_add_symbols(
608
609 Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym);
610
611+ if (shndx != elfcpp::SHN_UNDEF)
612+ ++this->defined_count_;
613+
614 // If this is a linker-defined symbol that hasn't yet been defined,
615 // define it now.
616 if (input_shndx == -1U && !res->is_defined())
617@@ -2283,9 +2287,21 @@ Sized_relobj_incr<size, big_endian>::do_initialize_xindex()
618 template<int size, bool big_endian>
619 void
620 Sized_relobj_incr<size, big_endian>::do_get_global_symbol_counts(
621- const Symbol_table*, size_t*, size_t*) const
622-{
623- gold_unreachable();
624+ const Symbol_table*,
625+ size_t* defined,
626+ size_t* used) const
627+{
628+ *defined = this->defined_count_;
629+ size_t count = 0;
630+ for (typename Symbols::const_iterator p = this->symbols_.begin();
631+ p != this->symbols_.end();
632+ ++p)
633+ if (*p != NULL
634+ && (*p)->source() == Symbol::FROM_OBJECT
635+ && (*p)->object() == this
636+ && (*p)->is_defined())
637+ ++count;
638+ *used = count;
639 }
640
641 // Read the relocs.
642@@ -2579,7 +2595,7 @@ Sized_incr_dynobj<size, big_endian>::Sized_incr_dynobj(
643 : Dynobj(name, NULL), ibase_(ibase),
644 input_file_index_(input_file_index),
645 input_reader_(ibase->inputs_reader().input_file(input_file_index)),
646- symbols_()
647+ symbols_(), defined_count_(0)
648 {
649 if (this->input_reader_.is_in_system_directory())
650 this->set_is_in_system_directory();
651@@ -2677,6 +2693,7 @@ Sized_incr_dynobj<size, big_endian>::do_add_symbols(
652 // is meaningless, as long as it's not SHN_UNDEF.
653 shndx = 1;
654 v = gsym.get_st_value();
655+ ++this->defined_count_;
656 }
657
658 osym.put_st_name(0);
659@@ -2845,9 +2862,22 @@ Sized_incr_dynobj<size, big_endian>::do_initialize_xindex()
660 template<int size, bool big_endian>
661 void
662 Sized_incr_dynobj<size, big_endian>::do_get_global_symbol_counts(
663- const Symbol_table*, size_t*, size_t*) const
664-{
665- gold_unreachable();
666+ const Symbol_table*,
667+ size_t* defined,
668+ size_t* used) const
669+{
670+ *defined = this->defined_count_;
671+ size_t count = 0;
672+ for (typename Symbols::const_iterator p = this->symbols_.begin();
673+ p != this->symbols_.end();
674+ ++p)
675+ if (*p != NULL
676+ && (*p)->source() == Symbol::FROM_OBJECT
677+ && (*p)->object() == this
678+ && (*p)->is_defined()
679+ && (*p)->dynsym_index() != -1U)
680+ ++count;
681+ *used = count;
682 }
683
684 // Allocate an incremental object of the appropriate size and endianness.
685diff --git a/gold/incremental.h b/gold/incremental.h
686index e6732df..56fc52b 100644
687--- a/gold/incremental.h
688+++ b/gold/incremental.h
689@@ -1996,6 +1996,8 @@ class Sized_relobj_incr : public Sized_relobj<size, big_endian>
690 unsigned int local_dynsym_offset_;
691 // The entries in the symbol table for the external symbols.
692 Symbols symbols_;
693+ // Number of symbols defined in object file itself.
694+ size_t defined_count_;
695 // The offset of the first incremental relocation for this object.
696 unsigned int incr_reloc_offset_;
697 // The number of incremental relocations for this object.
698@@ -2127,6 +2129,8 @@ class Sized_incr_dynobj : public Dynobj
699 Input_entry_reader input_reader_;
700 // The entries in the symbol table for the external symbols.
701 Symbols symbols_;
702+ // Number of symbols defined in object file itself.
703+ size_t defined_count_;
704 };
705
706 // Allocate an incremental object of the appropriate size and endianness.
707diff --git a/gold/layout.cc b/gold/layout.cc
708index 1c32bcf..9d8a43a 100644
709--- a/gold/layout.cc
710+++ b/gold/layout.cc
711@@ -2975,8 +2975,9 @@ Layout::segment_precedes(const Output_segment* seg1,
712
713 // We shouldn't get here--we shouldn't create segments which we
714 // can't distinguish. Unless of course we are using a weird linker
715- // script.
716- gold_assert(this->script_options_->saw_phdrs_clause());
717+ // script or overlapping --section-start options.
718+ gold_assert(this->script_options_->saw_phdrs_clause()
719+ || parameters->options().any_section_start());
720 return false;
721 }
722
723diff --git a/gold/options.cc b/gold/options.cc
724index be32645..dcf6ba7 100644
725--- a/gold/options.cc
726+++ b/gold/options.cc
727@@ -198,7 +198,7 @@ parse_uint(const char* option_name, const char* arg, int* retval)
728 {
729 char* endptr;
730 *retval = strtol(arg, &endptr, 0);
731- if (*endptr != '\0' || retval < 0)
732+ if (*endptr != '\0' || *retval < 0)
733 gold_fatal(_("%s: invalid option value (expected an integer): %s"),
734 option_name, arg);
735 }
736@@ -1224,6 +1224,37 @@ General_options::finalize()
737 gold_fatal(_("Options --incremental-changed, --incremental-unchanged, "
738 "--incremental-unknown require the use of --incremental"));
739
740+ // Check for options that are not compatible with incremental linking.
741+ // Where an option can be disabled without seriously changing the semantics
742+ // of the link, we turn the option off; otherwise, we issue a fatal error.
743+
744+ if (this->incremental_mode_ != INCREMENTAL_OFF)
745+ {
746+ if (this->relocatable())
747+ gold_fatal(_("incremental linking is not compatible with -r"));
748+ if (this->emit_relocs())
749+ gold_fatal(_("incremental linking is not compatible with "
750+ "--emit-relocs"));
751+ if (this->has_plugins())
752+ gold_fatal(_("incremental linking is not compatible with --plugin"));
753+ if (this->gc_sections())
754+ {
755+ gold_warning(_("ignoring --gc-sections for an incremental link"));
756+ this->set_gc_sections(false);
757+ }
758+ if (this->icf_enabled())
759+ {
760+ gold_warning(_("ignoring --icf for an incremental link"));
761+ this->set_icf_status(ICF_NONE);
762+ }
763+ if (strcmp(this->compress_debug_sections(), "none") != 0)
764+ {
765+ gold_warning(_("ignoring --compress-debug-sections for an "
766+ "incremental link"));
767+ this->set_compress_debug_sections("none");
768+ }
769+ }
770+
771 // FIXME: we can/should be doing a lot more sanity checking here.
772 }
773
774diff --git a/gold/options.h b/gold/options.h
775index 768df9c..8876a1e 100644
776--- a/gold/options.h
777+++ b/gold/options.h
778@@ -791,6 +791,10 @@ class General_options
779 DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
780 N_("Ignored"), NULL);
781
782+ DEFINE_bool(gnu_unique, options::TWO_DASHES, '\0', true,
783+ N_("Enable STB_GNU_UNIQUE symbol binding (default)"),
784+ N_("Disable STB_GNU_UNIQUE symbol binding"));
785+
786 DEFINE_string(soname, options::ONE_DASH, 'h', NULL,
787 N_("Set shared library name"), N_("FILENAME"));
788
789@@ -1385,6 +1389,11 @@ class General_options
790 bool
791 section_start(const char* secname, uint64_t* paddr) const;
792
793+ // Return whether any --section-start option was used.
794+ bool
795+ any_section_start() const
796+ { return !this->section_starts_.empty(); }
797+
798 enum Fix_v4bx
799 {
800 // Leave original instruction.
801diff --git a/gold/output.cc b/gold/output.cc
802index 29d8e3d..a7e1e9a 100644
803--- a/gold/output.cc
804+++ b/gold/output.cc
805@@ -119,7 +119,9 @@ extern "C" void *gold_mremap(void *, size_t, size_t, int);
806 static int
807 posix_fallocate(int o, off_t offset, off_t len)
808 {
809- return ftruncate(o, offset + len);
810+ if (ftruncate(o, offset + len) < 0)
811+ return errno;
812+ return 0;
813 }
814 #endif // !defined(HAVE_POSIX_FALLOCATE)
815
816@@ -706,7 +708,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
817 bool is_symbolless)
818 : address_(address), local_sym_index_(GSYM_CODE), type_(type),
819 is_relative_(is_relative), is_symbolless_(is_symbolless),
820- is_section_symbol_(false), shndx_(INVALID_CODE)
821+ is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
822 {
823 // this->type_ is a bitfield; make sure TYPE fits.
824 gold_assert(this->type_ == type);
825@@ -727,7 +729,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
826 bool is_symbolless)
827 : address_(address), local_sym_index_(GSYM_CODE), type_(type),
828 is_relative_(is_relative), is_symbolless_(is_symbolless),
829- is_section_symbol_(false), shndx_(shndx)
830+ is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
831 {
832 gold_assert(shndx != INVALID_CODE);
833 // this->type_ is a bitfield; make sure TYPE fits.
834@@ -749,10 +751,12 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
835 Address address,
836 bool is_relative,
837 bool is_symbolless,
838- bool is_section_symbol)
839+ bool is_section_symbol,
840+ bool use_plt_offset)
841 : address_(address), local_sym_index_(local_sym_index), type_(type),
842 is_relative_(is_relative), is_symbolless_(is_symbolless),
843- is_section_symbol_(is_section_symbol), shndx_(INVALID_CODE)
844+ is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset),
845+ shndx_(INVALID_CODE)
846 {
847 gold_assert(local_sym_index != GSYM_CODE
848 && local_sym_index != INVALID_CODE);
849@@ -773,10 +777,12 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
850 Address address,
851 bool is_relative,
852 bool is_symbolless,
853- bool is_section_symbol)
854+ bool is_section_symbol,
855+ bool use_plt_offset)
856 : address_(address), local_sym_index_(local_sym_index), type_(type),
857 is_relative_(is_relative), is_symbolless_(is_symbolless),
858- is_section_symbol_(is_section_symbol), shndx_(shndx)
859+ is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset),
860+ shndx_(shndx)
861 {
862 gold_assert(local_sym_index != GSYM_CODE
863 && local_sym_index != INVALID_CODE);
864@@ -799,7 +805,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
865 Address address)
866 : address_(address), local_sym_index_(SECTION_CODE), type_(type),
867 is_relative_(false), is_symbolless_(false),
868- is_section_symbol_(true), shndx_(INVALID_CODE)
869+ is_section_symbol_(true), use_plt_offset_(false), shndx_(INVALID_CODE)
870 {
871 // this->type_ is a bitfield; make sure TYPE fits.
872 gold_assert(this->type_ == type);
873@@ -820,7 +826,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
874 Address address)
875 : address_(address), local_sym_index_(SECTION_CODE), type_(type),
876 is_relative_(false), is_symbolless_(false),
877- is_section_symbol_(true), shndx_(shndx)
878+ is_section_symbol_(true), use_plt_offset_(false), shndx_(shndx)
879 {
880 gold_assert(shndx != INVALID_CODE);
881 // this->type_ is a bitfield; make sure TYPE fits.
882@@ -842,7 +848,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
883 Address address)
884 : address_(address), local_sym_index_(0), type_(type),
885 is_relative_(false), is_symbolless_(false),
886- is_section_symbol_(false), shndx_(INVALID_CODE)
887+ is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
888 {
889 // this->type_ is a bitfield; make sure TYPE fits.
890 gold_assert(this->type_ == type);
891@@ -858,7 +864,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
892 Address address)
893 : address_(address), local_sym_index_(0), type_(type),
894 is_relative_(false), is_symbolless_(false),
895- is_section_symbol_(false), shndx_(shndx)
896+ is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
897 {
898 gold_assert(shndx != INVALID_CODE);
899 // this->type_ is a bitfield; make sure TYPE fits.
900@@ -877,7 +883,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
901 Address address)
902 : address_(address), local_sym_index_(TARGET_CODE), type_(type),
903 is_relative_(false), is_symbolless_(false),
904- is_section_symbol_(false), shndx_(INVALID_CODE)
905+ is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
906 {
907 // this->type_ is a bitfield; make sure TYPE fits.
908 gold_assert(this->type_ == type);
909@@ -894,7 +900,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
910 Address address)
911 : address_(address), local_sym_index_(TARGET_CODE), type_(type),
912 is_relative_(false), is_symbolless_(false),
913- is_section_symbol_(false), shndx_(shndx)
914+ is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
915 {
916 gold_assert(shndx != INVALID_CODE);
917 // this->type_ is a bitfield; make sure TYPE fits.
918@@ -1121,6 +1127,12 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value(
919 Sized_relobj_file<size, big_endian>* relobj =
920 this->u1_.relobj->sized_relobj();
921 gold_assert(relobj != NULL);
922+ if (this->use_plt_offset_)
923+ {
924+ uint64_t plt_address =
925+ parameters->target().plt_address_for_local(relobj, lsi);
926+ return plt_address + relobj->local_plt_offset(lsi);
927+ }
928 const Symbol_value<size>* symval = relobj->local_symbol(lsi);
929 return symval->value(relobj, addend);
930 }
931@@ -4880,17 +4892,27 @@ Output_file::open_base_file(const char* base_name, bool writable)
932 if (use_base_file)
933 {
934 this->open(s.st_size);
935- ssize_t len = ::read(o, this->base_, s.st_size);
936- if (len < 0)
937- {
938- gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
939- return false;
940- }
941- if (len < s.st_size)
942- {
943- gold_info(_("%s: file too short"), base_name);
944- return false;
945- }
946+ ssize_t bytes_to_read = s.st_size;
947+ unsigned char* p = this->base_;
948+ while (bytes_to_read > 0)
949+ {
950+ ssize_t len = ::read(o, p, bytes_to_read);
951+ if (len < 0)
952+ {
953+ gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
954+ return false;
955+ }
956+ if (len == 0)
957+ {
958+ gold_info(_("%s: file too short: read only %lld of %lld bytes"),
959+ base_name,
960+ static_cast<long long>(s.st_size - bytes_to_read),
961+ static_cast<long long>(s.st_size));
962+ return false;
963+ }
964+ p += len;
965+ bytes_to_read -= len;
966+ }
967 ::close(o);
968 return true;
969 }
970@@ -5052,8 +5074,12 @@ Output_file::map_no_anonymous(bool writable)
971 // output file will wind up incomplete, but we will have already
972 // exited. The alternative to fallocate would be to use fdatasync,
973 // but that would be a more significant performance hit.
974- if (writable && ::posix_fallocate(o, 0, this->file_size_) < 0)
975- gold_fatal(_("%s: %s"), this->name_, strerror(errno));
976+ if (writable)
977+ {
978+ int err = ::posix_fallocate(o, 0, this->file_size_);
979+ if (err != 0)
980+ gold_fatal(_("%s: %s"), this->name_, strerror(err));
981+ }
982
983 // Map the file into memory.
984 int prot = PROT_READ;
985diff --git a/gold/output.h b/gold/output.h
986index 1bec2c0..e2d35e2 100644
987--- a/gold/output.h
988+++ b/gold/output.h
989@@ -1033,12 +1033,14 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
990 Output_reloc(Sized_relobj<size, big_endian>* relobj,
991 unsigned int local_sym_index, unsigned int type,
992 Output_data* od, Address address, bool is_relative,
993- bool is_symbolless, bool is_section_symbol);
994+ bool is_symbolless, bool is_section_symbol,
995+ bool use_plt_offset);
996
997 Output_reloc(Sized_relobj<size, big_endian>* relobj,
998 unsigned int local_sym_index, unsigned int type,
999 unsigned int shndx, Address address, bool is_relative,
1000- bool is_symbolless, bool is_section_symbol);
1001+ bool is_symbolless, bool is_section_symbol,
1002+ bool use_plt_offset);
1003
1004 // A reloc against the STT_SECTION symbol of an output section.
1005
1006@@ -1216,7 +1218,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1007 // input file.
1008 unsigned int local_sym_index_;
1009 // The reloc type--a processor specific code.
1010- unsigned int type_ : 29;
1011+ unsigned int type_ : 28;
1012 // True if the relocation is a RELATIVE relocation.
1013 bool is_relative_ : 1;
1014 // True if the relocation is one which should not use
1015@@ -1224,6 +1226,10 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1016 bool is_symbolless_ : 1;
1017 // True if the relocation is against a section symbol.
1018 bool is_section_symbol_ : 1;
1019+ // True if the addend should be the PLT offset. This is used only
1020+ // for RELATIVE relocations to local symbols.
1021+ // (Used only for RELA, but stored here for space.)
1022+ bool use_plt_offset_ : 1;
1023 // If the reloc address is an input section in an object, the
1024 // section index. This is INVALID_CODE if the reloc address is
1025 // specified in some other way.
1026@@ -1268,9 +1274,10 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1027 unsigned int local_sym_index, unsigned int type,
1028 Output_data* od, Address address,
1029 Addend addend, bool is_relative,
1030- bool is_symbolless, bool is_section_symbol)
1031+ bool is_symbolless, bool is_section_symbol,
1032+ bool use_plt_offset)
1033 : rel_(relobj, local_sym_index, type, od, address, is_relative,
1034- is_symbolless, is_section_symbol),
1035+ is_symbolless, is_section_symbol, use_plt_offset),
1036 addend_(addend)
1037 { }
1038
1039@@ -1278,9 +1285,10 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1040 unsigned int local_sym_index, unsigned int type,
1041 unsigned int shndx, Address address,
1042 Addend addend, bool is_relative,
1043- bool is_symbolless, bool is_section_symbol)
1044+ bool is_symbolless, bool is_section_symbol,
1045+ bool use_plt_offset)
1046 : rel_(relobj, local_sym_index, type, shndx, address, is_relative,
1047- is_symbolless, is_section_symbol),
1048+ is_symbolless, is_section_symbol, use_plt_offset),
1049 addend_(addend)
1050 { }
1051
1052@@ -1571,7 +1579,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1053 Output_data* od, Address address)
1054 {
1055 this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
1056- address, false, false, false));
1057+ address, false, false, false, false));
1058 }
1059
1060 void
1061@@ -1580,7 +1588,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1062 Output_data* od, unsigned int shndx, Address address)
1063 {
1064 this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
1065- address, false, false, false));
1066+ address, false, false, false, false));
1067 }
1068
1069 // Add a RELATIVE reloc against a local symbol.
1070@@ -1591,7 +1599,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1071 Output_data* od, Address address)
1072 {
1073 this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
1074- address, true, true, false));
1075+ address, true, true, false, false));
1076 }
1077
1078 void
1079@@ -1600,7 +1608,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1080 Output_data* od, unsigned int shndx, Address address)
1081 {
1082 this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
1083- address, true, true, false));
1084+ address, true, true, false, false));
1085 }
1086
1087 // Add a local relocation which does not use a symbol for the relocation,
1088@@ -1612,7 +1620,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1089 Output_data* od, Address address)
1090 {
1091 this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
1092- address, false, true, false));
1093+ address, false, true, false, false));
1094 }
1095
1096 void
1097@@ -1622,7 +1630,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1098 Address address)
1099 {
1100 this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
1101- address, false, true, false));
1102+ address, false, true, false, false));
1103 }
1104
1105 // Add a reloc against a local section symbol. This will be
1106@@ -1635,7 +1643,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1107 Output_data* od, Address address)
1108 {
1109 this->add(od, Output_reloc_type(relobj, input_shndx, type, od,
1110- address, false, false, true));
1111+ address, false, false, true, false));
1112 }
1113
1114 void
1115@@ -1644,7 +1652,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
1116 Output_data* od, unsigned int shndx, Address address)
1117 {
1118 this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
1119- address, false, false, true));
1120+ address, false, false, true, false));
1121 }
1122
1123 // A reloc against the STT_SECTION symbol of an output section.
1124@@ -1767,7 +1775,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1125 Output_data* od, Address address, Addend addend)
1126 {
1127 this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
1128- addend, false, false, false));
1129+ addend, false, false, false, false));
1130 }
1131
1132 void
1133@@ -1777,7 +1785,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1134 Addend addend)
1135 {
1136 this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
1137- address, addend, false, false, false));
1138+ address, addend, false, false, false,
1139+ false));
1140 }
1141
1142 // Add a RELATIVE reloc against a local symbol.
1143@@ -1785,20 +1794,23 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1144 void
1145 add_local_relative(Sized_relobj<size, big_endian>* relobj,
1146 unsigned int local_sym_index, unsigned int type,
1147- Output_data* od, Address address, Addend addend)
1148+ Output_data* od, Address address, Addend addend,
1149+ bool use_plt_offset)
1150 {
1151 this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
1152- addend, true, true, false));
1153+ addend, true, true, false,
1154+ use_plt_offset));
1155 }
1156
1157 void
1158 add_local_relative(Sized_relobj<size, big_endian>* relobj,
1159 unsigned int local_sym_index, unsigned int type,
1160 Output_data* od, unsigned int shndx, Address address,
1161- Addend addend)
1162+ Addend addend, bool use_plt_offset)
1163 {
1164 this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
1165- address, addend, true, true, false));
1166+ address, addend, true, true, false,
1167+ use_plt_offset));
1168 }
1169
1170 // Add a local relocation which does not use a symbol for the relocation,
1171@@ -1810,7 +1822,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1172 Output_data* od, Address address, Addend addend)
1173 {
1174 this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
1175- addend, false, true, false));
1176+ addend, false, true, false, false));
1177 }
1178
1179 void
1180@@ -1820,7 +1832,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1181 Address address, Addend addend)
1182 {
1183 this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
1184- address, addend, false, true, false));
1185+ address, addend, false, true, false,
1186+ false));
1187 }
1188
1189 // Add a reloc against a local section symbol. This will be
1190@@ -1833,7 +1846,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1191 Output_data* od, Address address, Addend addend)
1192 {
1193 this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address,
1194- addend, false, false, true));
1195+ addend, false, false, true, false));
1196 }
1197
1198 void
1199@@ -1843,7 +1856,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
1200 Addend addend)
1201 {
1202 this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
1203- address, addend, false, false, true));
1204+ address, addend, false, false, true,
1205+ false));
1206 }
1207
1208 // A reloc against the STT_SECTION symbol of an output section.
1209diff --git a/gold/plugin.cc b/gold/plugin.cc
1210index 3ccd8d0..b4e68f8 100644
1211--- a/gold/plugin.cc
1212+++ b/gold/plugin.cc
1213@@ -818,7 +818,9 @@ Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
1214 }
1215
1216 // Return TRUE if a defined symbol is referenced from outside the
1217-// universe of claimed objects.
1218+// universe of claimed objects. Only references from relocatable,
1219+// non-IR (unclaimed) objects count as a reference. References from
1220+// dynamic objects count only as "visible".
1221
1222 static inline bool
1223 is_referenced_from_outside(Symbol* lsym)
1224@@ -838,6 +840,8 @@ is_referenced_from_outside(Symbol* lsym)
1225 static inline bool
1226 is_visible_from_outside(Symbol* lsym)
1227 {
1228+ if (lsym->in_dyn())
1229+ return true;
1230 if (parameters->options().export_dynamic() || parameters->options().shared())
1231 return lsym->is_externally_visible();
1232 return false;
1233@@ -1244,14 +1248,18 @@ Sized_pluginobj<size, big_endian>::do_initialize_xindex()
1234 return NULL;
1235 }
1236
1237-// Get symbol counts. Not used for plugin objects.
1238+// Get symbol counts. Don't count plugin objects; the replacement
1239+// files will provide the counts.
1240
1241 template<int size, bool big_endian>
1242 void
1243-Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_table*,
1244- size_t*, size_t*) const
1245+Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(
1246+ const Symbol_table*,
1247+ size_t* defined,
1248+ size_t* used) const
1249 {
1250- gold_unreachable();
1251+ *defined = 0;
1252+ *used = 0;
1253 }
1254
1255 // Get symbols. Not used for plugin objects.
1256diff --git a/gold/powerpc.cc b/gold/powerpc.cc
1257index 45783c3..62a17ca 100644
1258--- a/gold/powerpc.cc
1259+++ b/gold/powerpc.cc
1260@@ -1329,7 +1329,7 @@ Target_powerpc<size, big_endian>::Scan::local(
1261 rela_dyn->add_local_relative(object, r_sym, r_type,
1262 output_section, data_shndx,
1263 reloc.get_r_offset(),
1264- reloc.get_r_addend());
1265+ reloc.get_r_addend(), false);
1266 }
1267 }
1268 break;
1269@@ -1372,7 +1372,7 @@ Target_powerpc<size, big_endian>::Scan::local(
1270 object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
1271 rela_dyn->add_local_relative(object, r_sym,
1272 elfcpp::R_POWERPC_RELATIVE,
1273- got, off, 0);
1274+ got, off, 0, false);
1275 }
1276 }
1277 else
1278diff --git a/gold/readsyms.cc b/gold/readsyms.cc
1279index 1e50942..9974722 100644
1280--- a/gold/readsyms.cc
1281+++ b/gold/readsyms.cc
1282@@ -161,8 +161,10 @@ void
1283 Read_symbols::run(Workqueue* workqueue)
1284 {
1285 // If we didn't queue a new task, then we need to explicitly unblock
1286- // the token.
1287- if (!this->do_read_symbols(workqueue))
1288+ // the token. If the object is a member of a lib group, however,
1289+ // the token was already added to the list of locks for the task,
1290+ // and it will be unblocked automatically at the end of the task.
1291+ if (!this->do_read_symbols(workqueue) && this->member_ == NULL)
1292 workqueue->queue_soon(new Unblock_token(this->this_blocker_,
1293 this->next_blocker_));
1294 }
1295diff --git a/gold/resolve.cc b/gold/resolve.cc
1296index 03288ec..780038a 100644
1297--- a/gold/resolve.cc
1298+++ b/gold/resolve.cc
1299@@ -296,7 +296,7 @@ Symbol_table::resolve(Sized_symbol<size>* to,
1300
1301 // Record if we've seen this symbol in a real ELF object (i.e., the
1302 // symbol is referenced from outside the world known to the plugin).
1303- if (object->pluginobj() == NULL)
1304+ if (object->pluginobj() == NULL && !object->is_dynamic())
1305 to->set_in_real_elf();
1306
1307 // If we're processing replacement files, allow new symbols to override
1308@@ -336,9 +336,9 @@ Symbol_table::resolve(Sized_symbol<size>* to,
1309 && to->name()[0] == '_' && to->name()[1] == 'Z')
1310 {
1311 Symbol_location fromloc
1312- = { object, orig_st_shndx, sym.get_st_value() };
1313+ = { object, orig_st_shndx, static_cast<off_t>(sym.get_st_value()) };
1314 Symbol_location toloc = { to->object(), to->shndx(&to_is_ordinary),
1315- to->value() };
1316+ static_cast<off_t>(to->value()) };
1317 this->candidate_odr_violations_[to->name()].insert(fromloc);
1318 this->candidate_odr_violations_[to->name()].insert(toloc);
1319 }
1320diff --git a/gold/script-sections.cc b/gold/script-sections.cc
1321index 1fad88d..f90c0b3 100644
1322--- a/gold/script-sections.cc
1323+++ b/gold/script-sections.cc
1324@@ -680,7 +680,7 @@ class Sections_element_assignment : public Sections_element
1325 set_section_addresses(Symbol_table* symtab, Layout* layout,
1326 uint64_t* dot_value, uint64_t*, uint64_t*)
1327 {
1328- this->assignment_.set_if_absolute(symtab, layout, true, *dot_value);
1329+ this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, NULL);
1330 }
1331
1332 // Print for debugging.
1333@@ -714,7 +714,7 @@ class Sections_element_dot_assignment : public Sections_element
1334 // output section definition the dot symbol is always considered
1335 // to be absolute.
1336 *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
1337- NULL, NULL, NULL);
1338+ NULL, NULL, NULL, false);
1339 }
1340
1341 // Update the dot symbol while setting section addresses.
1342@@ -724,7 +724,7 @@ class Sections_element_dot_assignment : public Sections_element
1343 uint64_t* load_address)
1344 {
1345 *dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value,
1346- NULL, NULL, dot_alignment);
1347+ NULL, NULL, dot_alignment, false);
1348 *load_address = *dot_value;
1349 }
1350
1351@@ -866,9 +866,11 @@ class Output_section_element_assignment : public Output_section_element
1352 void
1353 set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
1354 uint64_t, uint64_t* dot_value, uint64_t*,
1355- Output_section**, std::string*, Input_section_list*)
1356+ Output_section** dot_section, std::string*,
1357+ Input_section_list*)
1358 {
1359- this->assignment_.set_if_absolute(symtab, layout, true, *dot_value);
1360+ this->assignment_.set_if_absolute(symtab, layout, true, *dot_value,
1361+ *dot_section);
1362 }
1363
1364 // Print for debugging.
1365@@ -892,20 +894,28 @@ class Output_section_element_dot_assignment : public Output_section_element
1366 : val_(val)
1367 { }
1368
1369+ // An assignment to dot within an output section is enough to force
1370+ // the output section to exist.
1371+ bool
1372+ needs_output_section() const
1373+ { return true; }
1374+
1375 // Finalize the symbol.
1376 void
1377 finalize_symbols(Symbol_table* symtab, const Layout* layout,
1378 uint64_t* dot_value, Output_section** dot_section)
1379 {
1380 *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
1381- *dot_section, dot_section, NULL);
1382+ *dot_section, dot_section, NULL,
1383+ true);
1384 }
1385
1386 // Update the dot symbol while setting section addresses.
1387 void
1388 set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
1389 uint64_t, uint64_t* dot_value, uint64_t*,
1390- Output_section**, std::string*, Input_section_list*);
1391+ Output_section** dot_section, std::string*,
1392+ Input_section_list*);
1393
1394 // Print for debugging.
1395 void
1396@@ -936,7 +946,8 @@ Output_section_element_dot_assignment::set_section_addresses(
1397 {
1398 uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false,
1399 *dot_value, *dot_section,
1400- dot_section, dot_alignment);
1401+ dot_section, dot_alignment,
1402+ true);
1403 if (next_dot < *dot_value)
1404 gold_error(_("dot may not move backward"));
1405 if (next_dot > *dot_value && output_section != NULL)
1406@@ -1037,7 +1048,8 @@ Output_data_expression::do_write_to_buffer(unsigned char* buf)
1407 {
1408 uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_,
1409 true, this->dot_value_,
1410- this->dot_section_, NULL, NULL);
1411+ this->dot_section_, NULL, NULL,
1412+ false);
1413
1414 if (parameters->target().is_big_endian())
1415 this->endian_write_to_buffer<true>(val, buf);
1416@@ -1187,7 +1199,7 @@ class Output_section_element_fill : public Output_section_element
1417 Output_section* fill_section;
1418 uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false,
1419 *dot_value, *dot_section,
1420- &fill_section, NULL);
1421+ &fill_section, NULL, false);
1422 if (fill_section != NULL)
1423 gold_warning(_("fill value is not absolute"));
1424 // FIXME: The GNU linker supports fill values of arbitrary length.
1425@@ -2108,13 +2120,13 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab,
1426 {
1427 address = this->address_->eval_with_dot(symtab, layout, true,
1428 *dot_value, NULL,
1429- NULL, NULL);
1430+ NULL, NULL, false);
1431 }
1432 if (this->align_ != NULL)
1433 {
1434 uint64_t align = this->align_->eval_with_dot(symtab, layout, true,
1435 *dot_value, NULL,
1436- NULL, NULL);
1437+ NULL, NULL, false);
1438 address = align_address(address, align);
1439 }
1440 *dot_value = address;
1441@@ -2303,7 +2315,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
1442 else
1443 address = this->address_->eval_with_dot(symtab, layout, true,
1444 *dot_value, NULL, NULL,
1445- dot_alignment);
1446+ dot_alignment, false);
1447 uint64_t align;
1448 if (this->align_ == NULL)
1449 {
1450@@ -2316,7 +2328,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
1451 {
1452 Output_section* align_section;
1453 align = this->align_->eval_with_dot(symtab, layout, true, *dot_value,
1454- NULL, &align_section, NULL);
1455+ NULL, &align_section, NULL, false);
1456 if (align_section != NULL)
1457 gold_warning(_("alignment of section %s is not absolute"),
1458 this->name_.c_str());
1459@@ -2401,7 +2413,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
1460 laddr = this->load_address_->eval_with_dot(symtab, layout, true,
1461 *dot_value,
1462 this->output_section_,
1463- NULL, NULL);
1464+ NULL, NULL, false);
1465 if (this->output_section_ != NULL)
1466 this->output_section_->set_load_address(laddr);
1467 }
1468@@ -2416,7 +2428,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
1469 Output_section* subalign_section;
1470 subalign = this->subalign_->eval_with_dot(symtab, layout, true,
1471 *dot_value, NULL,
1472- &subalign_section, NULL);
1473+ &subalign_section, NULL,
1474+ false);
1475 if (subalign_section != NULL)
1476 gold_warning(_("subalign of section %s is not absolute"),
1477 this->name_.c_str());
1478@@ -2431,7 +2444,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
1479 uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true,
1480 *dot_value,
1481 NULL, &fill_section,
1482- NULL);
1483+ NULL, false);
1484 if (fill_section != NULL)
1485 gold_warning(_("fill of section %s is not absolute"),
1486 this->name_.c_str());
1487diff --git a/gold/script.cc b/gold/script.cc
1488index 7df0c9e..b471cf9 100644
1489--- a/gold/script.cc
1490+++ b/gold/script.cc
1491@@ -983,18 +983,20 @@ Symbol_assignment::sized_finalize(Symbol_table* symtab, const Layout* layout,
1492 uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true,
1493 is_dot_available,
1494 dot_value, dot_section,
1495- &section, NULL);
1496+ &section, NULL, false);
1497 Sized_symbol<size>* ssym = symtab->get_sized_symbol<size>(this->sym_);
1498 ssym->set_value(final_val);
1499 if (section != NULL)
1500 ssym->set_output_section(section);
1501 }
1502
1503-// Set the symbol value if the expression yields an absolute value.
1504+// Set the symbol value if the expression yields an absolute value or
1505+// a value relative to DOT_SECTION.
1506
1507 void
1508 Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
1509- bool is_dot_available, uint64_t dot_value)
1510+ bool is_dot_available, uint64_t dot_value,
1511+ Output_section* dot_section)
1512 {
1513 if (this->sym_ == NULL)
1514 return;
1515@@ -1002,8 +1004,9 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
1516 Output_section* val_section;
1517 uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false,
1518 is_dot_available, dot_value,
1519- NULL, &val_section, NULL);
1520- if (val_section != NULL)
1521+ dot_section, &val_section, NULL,
1522+ false);
1523+ if (val_section != NULL && val_section != dot_section)
1524 return;
1525
1526 if (parameters->target().get_size() == 32)
1527@@ -1026,6 +1029,8 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
1528 }
1529 else
1530 gold_unreachable();
1531+ if (val_section != NULL)
1532+ this->sym_->set_output_section(val_section);
1533 }
1534
1535 // Print for debugging.
1536@@ -1215,7 +1220,7 @@ Script_options::set_section_addresses(Symbol_table* symtab, Layout* layout)
1537 for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
1538 p != this->symbol_assignments_.end();
1539 ++p)
1540- (*p)->set_if_absolute(symtab, layout, false, 0);
1541+ (*p)->set_if_absolute(symtab, layout, false, 0, NULL);
1542
1543 return this->script_sections_.set_section_addresses(symtab, layout);
1544 }
1545diff --git a/gold/script.h b/gold/script.h
1546index 73079a4..f41f438 100644
1547--- a/gold/script.h
1548+++ b/gold/script.h
1549@@ -90,20 +90,28 @@ class Expression
1550 // the section address. If RESULT_ALIGNMENT is not NULL, this sets
1551 // *RESULT_ALIGNMENT to the alignment of the value of that alignment
1552 // is larger than *RESULT_ALIGNMENT; this will only be non-zero if
1553- // this is an ALIGN expression.
1554+ // this is an ALIGN expression. If IS_SECTION_DOT_ASSIGMENT is true,
1555+ // we are evaluating an assignment to dot within an output section,
1556+ // and an absolute value should be interpreted as an offset within
1557+ // the section.
1558 uint64_t
1559 eval_with_dot(const Symbol_table*, const Layout*, bool check_assertions,
1560 uint64_t dot_value, Output_section* dot_section,
1561- Output_section** result_section, uint64_t* result_alignment);
1562+ Output_section** result_section, uint64_t* result_alignment,
1563+ bool is_section_dot_assignment);
1564
1565 // Return the value of an expression which may or may not be
1566 // permitted to refer to the dot symbol, depending on
1567- // is_dot_available.
1568+ // is_dot_available. If IS_SECTION_DOT_ASSIGMENT is true,
1569+ // we are evaluating an assignment to dot within an output section,
1570+ // and an absolute value should be interpreted as an offset within
1571+ // the section.
1572 uint64_t
1573 eval_maybe_dot(const Symbol_table*, const Layout*, bool check_assertions,
1574 bool is_dot_available, uint64_t dot_value,
1575 Output_section* dot_section,
1576- Output_section** result_section, uint64_t* result_alignment);
1577+ Output_section** result_section, uint64_t* result_alignment,
1578+ bool is_section_dot_assignment);
1579
1580 // Print the expression to the FILE. This is for debugging.
1581 virtual void
1582@@ -339,12 +347,12 @@ class Symbol_assignment
1583 finalize_with_dot(Symbol_table*, const Layout*, uint64_t dot_value,
1584 Output_section* dot_section);
1585
1586- // Set the symbol value, but only if the value is absolute. This is
1587- // used while processing a SECTIONS clause. We assume that dot is
1588- // an absolute value here. We do not check assertions.
1589+ // Set the symbol value, but only if the value is absolute or relative to
1590+ // DOT_SECTION. This is used while processing a SECTIONS clause.
1591+ // We assume that dot is an absolute value here. We do not check assertions.
1592 void
1593 set_if_absolute(Symbol_table*, const Layout*, bool is_dot_available,
1594- uint64_t dot_value);
1595+ uint64_t dot_value, Output_section* dot_section);
1596
1597 const std::string&
1598 name() const
1599diff --git a/gold/sparc.cc b/gold/sparc.cc
1600index 5f67a4e..12e1dee 100644
1601--- a/gold/sparc.cc
1602+++ b/gold/sparc.cc
1603@@ -1855,7 +1855,7 @@ Target_sparc<size, big_endian>::Scan::local(
1604 rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_RELATIVE,
1605 output_section, data_shndx,
1606 reloc.get_r_offset(),
1607- reloc.get_r_addend());
1608+ reloc.get_r_addend(), false);
1609 }
1610 break;
1611
1612@@ -1946,7 +1946,7 @@ Target_sparc<size, big_endian>::Scan::local(
1613 object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
1614 rela_dyn->add_local_relative(object, r_sym,
1615 elfcpp::R_SPARC_RELATIVE,
1616- got, off, 0);
1617+ got, off, 0, false);
1618 }
1619 }
1620 else
1621diff --git a/gold/symtab.cc b/gold/symtab.cc
1622index ff1b5ca..f0ba1d5 100644
1623--- a/gold/symtab.cc
1624+++ b/gold/symtab.cc
1625@@ -602,20 +602,16 @@ Symbol_table::gc_mark_undef_symbols(Layout* layout)
1626 }
1627
1628 void
1629-Symbol_table::gc_mark_symbol_for_shlib(Symbol* sym)
1630+Symbol_table::gc_mark_symbol(Symbol* sym)
1631 {
1632- if (!sym->is_from_dynobj()
1633- && sym->is_externally_visible())
1634+ // Add the object and section to the work list.
1635+ Relobj* obj = static_cast<Relobj*>(sym->object());
1636+ bool is_ordinary;
1637+ unsigned int shndx = sym->shndx(&is_ordinary);
1638+ if (is_ordinary && shndx != elfcpp::SHN_UNDEF)
1639 {
1640- //Add the object and section to the work list.
1641- Relobj* obj = static_cast<Relobj*>(sym->object());
1642- bool is_ordinary;
1643- unsigned int shndx = sym->shndx(&is_ordinary);
1644- if (is_ordinary && shndx != elfcpp::SHN_UNDEF)
1645- {
1646- gold_assert(this->gc_!= NULL);
1647- this->gc_->worklist().push(Section_id(obj, shndx));
1648- }
1649+ gold_assert(this->gc_!= NULL);
1650+ this->gc_->worklist().push(Section_id(obj, shndx));
1651 }
1652 }
1653
1654@@ -626,16 +622,7 @@ Symbol_table::gc_mark_dyn_syms(Symbol* sym)
1655 {
1656 if (sym->in_dyn() && sym->source() == Symbol::FROM_OBJECT
1657 && !sym->object()->is_dynamic())
1658- {
1659- Relobj* obj = static_cast<Relobj*>(sym->object());
1660- bool is_ordinary;
1661- unsigned int shndx = sym->shndx(&is_ordinary);
1662- if (is_ordinary && shndx != elfcpp::SHN_UNDEF)
1663- {
1664- gold_assert(this->gc_ != NULL);
1665- this->gc_->worklist().push(Section_id(obj, shndx));
1666- }
1667- }
1668+ this->gc_mark_symbol(sym);
1669 }
1670
1671 // Make TO a symbol which forwards to FROM.
1672@@ -1143,6 +1130,14 @@ Symbol_table::add_from_relobj(
1673 bool is_default_version = false;
1674 bool is_forced_local = false;
1675
1676+ // FIXME: For incremental links, we don't store version information,
1677+ // so we need to ignore version symbols for now.
1678+ if (parameters->incremental_update() && ver != NULL)
1679+ {
1680+ namelen = ver - name;
1681+ ver = NULL;
1682+ }
1683+
1684 if (ver != NULL)
1685 {
1686 // The symbol name is of the form foo@VERSION or foo@@VERSION
1687@@ -1243,11 +1238,16 @@ Symbol_table::add_from_relobj(
1688 if (is_forced_local)
1689 this->force_local(res);
1690
1691- // If building a shared library using garbage collection, do not
1692- // treat externally visible symbols as garbage.
1693- if (parameters->options().gc_sections()
1694- && parameters->options().shared())
1695- this->gc_mark_symbol_for_shlib(res);
1696+ // Do not treat this symbol as garbage if this symbol will be
1697+ // exported to the dynamic symbol table. This is true when
1698+ // building a shared library or using --export-dynamic and
1699+ // the symbol is externally visible.
1700+ if (parameters->options().gc_sections()
1701+ && res->is_externally_visible()
1702+ && !res->is_from_dynobj()
1703+ && (parameters->options().shared()
1704+ || parameters->options().export_dynamic()))
1705+ this->gc_mark_symbol(res);
1706
1707 if (is_defined_in_discarded_section)
1708 res->set_is_defined_in_discarded_section();
1709@@ -1346,6 +1346,11 @@ Symbol_table::add_from_dynobj(
1710 return;
1711 }
1712
1713+ // FIXME: For incremental links, we don't store version information,
1714+ // so we need to ignore version symbols for now.
1715+ if (parameters->incremental_update())
1716+ versym = NULL;
1717+
1718 if (versym != NULL && versym_size / 2 < count)
1719 {
1720 dynobj->error(_("too few symbol versions"));
1721@@ -2809,6 +2814,12 @@ Symbol_table::sized_write_globals(const Stringpool* sympool,
1722 typename elfcpp::Elf_types<size>::Elf_Addr sym_value = sym->value();
1723 typename elfcpp::Elf_types<size>::Elf_Addr dynsym_value = sym_value;
1724 elfcpp::STB binding = sym->binding();
1725+
1726+ // If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL.
1727+ if (binding == elfcpp::STB_GNU_UNIQUE
1728+ && !parameters->options().gnu_unique())
1729+ binding = elfcpp::STB_GLOBAL;
1730+
1731 switch (sym->source())
1732 {
1733 case Symbol::FROM_OBJECT:
1734diff --git a/gold/symtab.h b/gold/symtab.h
1735index b9b9e00..427f72f 100644
1736--- a/gold/symtab.h
1737+++ b/gold/symtab.h
1738@@ -1308,10 +1308,9 @@ class Symbol_table
1739 void
1740 gc_mark_undef_symbols(Layout*);
1741
1742- // During garbage collection, this ensures externally visible symbols
1743- // are not treated as garbage while building shared objects.
1744+ // This tells garbage collection that this symbol is referenced.
1745 void
1746- gc_mark_symbol_for_shlib(Symbol* sym);
1747+ gc_mark_symbol(Symbol* sym);
1748
1749 // During garbage collection, this keeps sections that correspond to
1750 // symbols seen in dynamic objects.
1751diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
1752index 67149fb..785dcdd 100644
1753--- a/gold/testsuite/Makefile.in
1754+++ b/gold/testsuite/Makefile.in
1755@@ -1844,6 +1844,8 @@ EGREP = @EGREP@
1756 EXEEXT = @EXEEXT@
1757 GENCAT = @GENCAT@
1758 GMSGFMT = @GMSGFMT@
1759+GOLD_LDADD = @GOLD_LDADD@
1760+GOLD_LDFLAGS = @GOLD_LDFLAGS@
1761 GREP = @GREP@
1762 INCINTL = @INCINTL@
1763 INSTALL = @INSTALL@
1764diff --git a/gold/testsuite/plugin_test_2.sh b/gold/testsuite/plugin_test_2.sh
1765index a47d22a..293b1f0 100755
1766--- a/gold/testsuite/plugin_test_2.sh
1767+++ b/gold/testsuite/plugin_test_2.sh
1768@@ -45,7 +45,7 @@ check plugin_test_2.err "two_file_test_main.o: claim file hook called"
1769 check plugin_test_2.err "two_file_test_1.syms: claim file hook called"
1770 check plugin_test_2.err "two_file_test_1b.syms: claim file hook called"
1771 check plugin_test_2.err "two_file_shared_2.so: claim file hook called"
1772-check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_REG"
1773+check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_IRONLY_EXP"
1774 check plugin_test_2.err "two_file_test_1.syms: _Z2t2v: PREVAILING_DEF_REG"
1775 check plugin_test_2.err "two_file_test_1.syms: v2: RESOLVED_DYN"
1776 check plugin_test_2.err "two_file_test_1.syms: t17data: RESOLVED_DYN"
1777diff --git a/gold/testsuite/script_test_2.t b/gold/testsuite/script_test_2.t
1778index 73d39df..6a0188f 100644
1779--- a/gold/testsuite/script_test_2.t
1780+++ b/gold/testsuite/script_test_2.t
1781@@ -49,7 +49,7 @@ SECTIONS
1782 /* This should match the remaining sections. */
1783 *(.gold_test)
1784
1785- . = . + 4;
1786+ . = 60;
1787 start_data = .;
1788 BYTE(1)
1789 SHORT(2)
1790diff --git a/gold/x86_64.cc b/gold/x86_64.cc
1791index e6b0021..e7c981b 100644
1792--- a/gold/x86_64.cc
1793+++ b/gold/x86_64.cc
1794@@ -1549,7 +1549,7 @@ Target_x86_64::reserve_local_got_entry(
1795 case GOT_TYPE_STANDARD:
1796 if (parameters->options().output_is_position_independent())
1797 rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_X86_64_RELATIVE,
1798- this->got_, got_offset, 0);
1799+ this->got_, got_offset, 0, false);
1800 break;
1801 case GOT_TYPE_TLS_OFFSET:
1802 rela_dyn->add_local(obj, r_sym, elfcpp::R_X86_64_TPOFF64,
1803@@ -1953,8 +1953,8 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
1804 const elfcpp::Sym<64, false>& lsym)
1805 {
1806 // A local STT_GNU_IFUNC symbol may require a PLT entry.
1807- if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC
1808- && this->reloc_needs_plt_for_ifunc(object, r_type))
1809+ bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
1810+ if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type))
1811 {
1812 unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info());
1813 target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
1814@@ -1982,7 +1982,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
1815 elfcpp::R_X86_64_RELATIVE,
1816 output_section, data_shndx,
1817 reloc.get_r_offset(),
1818- reloc.get_r_addend());
1819+ reloc.get_r_addend(), is_ifunc);
1820 }
1821 break;
1822
1823@@ -2058,7 +2058,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
1824 // lets function pointers compare correctly with shared
1825 // libraries. Otherwise we would need an IRELATIVE reloc.
1826 bool is_new;
1827- if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC)
1828+ if (is_ifunc)
1829 is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
1830 else
1831 is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
1832@@ -2076,7 +2076,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
1833 object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
1834 rela_dyn->add_local_relative(object, r_sym,
1835 elfcpp::R_X86_64_RELATIVE,
1836- got, got_offset, 0);
1837+ got, got_offset, 0, is_ifunc);
1838 }
1839 else
1840 {
1841@@ -3181,12 +3181,6 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
1842 }
1843 if (optimized_type == tls::TLSOPT_TO_IE)
1844 {
1845- if (tls_segment == NULL)
1846- {
1847- gold_assert(parameters->errors()->error_count() > 0
1848- || issue_undefined_symbol_error(gsym));
1849- return;
1850- }
1851 value = target->got_plt_section()->address() + got_offset;
1852 this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type,
1853 value, view, address, view_size);
1854@@ -3867,42 +3861,51 @@ Target_x86_64::do_code_fill(section_size_type length) const
1855 }
1856
1857 // Nop sequences of various lengths.
1858- const char nop1[1] = { 0x90 }; // nop
1859- const char nop2[2] = { 0x66, 0x90 }; // xchg %ax %ax
1860- const char nop3[3] = { 0x0f, 0x1f, 0x00 }; // nop (%rax)
1861- const char nop4[4] = { 0x0f, 0x1f, 0x40, 0x00}; // nop 0(%rax)
1862- const char nop5[5] = { 0x0f, 0x1f, 0x44, 0x00, // nop 0(%rax,%rax,1)
1863- 0x00 };
1864- const char nop6[6] = { 0x66, 0x0f, 0x1f, 0x44, // nopw 0(%rax,%rax,1)
1865- 0x00, 0x00 };
1866- const char nop7[7] = { 0x0f, 0x1f, 0x80, 0x00, // nopl 0L(%rax)
1867- 0x00, 0x00, 0x00 };
1868- const char nop8[8] = { 0x0f, 0x1f, 0x84, 0x00, // nopl 0L(%rax,%rax,1)
1869- 0x00, 0x00, 0x00, 0x00 };
1870- const char nop9[9] = { 0x66, 0x0f, 0x1f, 0x84, // nopw 0L(%rax,%rax,1)
1871- 0x00, 0x00, 0x00, 0x00,
1872- 0x00 };
1873- const char nop10[10] = { 0x66, 0x2e, 0x0f, 0x1f, // nopw %cs:0L(%rax,%rax,1)
1874- 0x84, 0x00, 0x00, 0x00,
1875- 0x00, 0x00 };
1876- const char nop11[11] = { 0x66, 0x66, 0x2e, 0x0f, // data16
1877- 0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1)
1878- 0x00, 0x00, 0x00 };
1879- const char nop12[12] = { 0x66, 0x66, 0x66, 0x2e, // data16; data16
1880- 0x0f, 0x1f, 0x84, 0x00, // nopw %cs:0L(%rax,%rax,1)
1881- 0x00, 0x00, 0x00, 0x00 };
1882- const char nop13[13] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16
1883- 0x2e, 0x0f, 0x1f, 0x84, // nopw %cs:0L(%rax,%rax,1)
1884- 0x00, 0x00, 0x00, 0x00,
1885- 0x00 };
1886- const char nop14[14] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16
1887- 0x66, 0x2e, 0x0f, 0x1f, // data16
1888- 0x84, 0x00, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1)
1889- 0x00, 0x00 };
1890- const char nop15[15] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16
1891- 0x66, 0x66, 0x2e, 0x0f, // data16; data16
1892- 0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1)
1893- 0x00, 0x00, 0x00 };
1894+ const char nop1[1] = { '\x90' }; // nop
1895+ const char nop2[2] = { '\x66', '\x90' }; // xchg %ax %ax
1896+ const char nop3[3] = { '\x0f', '\x1f', '\x00' }; // nop (%rax)
1897+ const char nop4[4] = { '\x0f', '\x1f', '\x40', // nop 0(%rax)
1898+ '\x00'};
1899+ const char nop5[5] = { '\x0f', '\x1f', '\x44', // nop 0(%rax,%rax,1)
1900+ '\x00', '\x00' };
1901+ const char nop6[6] = { '\x66', '\x0f', '\x1f', // nopw 0(%rax,%rax,1)
1902+ '\x44', '\x00', '\x00' };
1903+ const char nop7[7] = { '\x0f', '\x1f', '\x80', // nopl 0L(%rax)
1904+ '\x00', '\x00', '\x00',
1905+ '\x00' };
1906+ const char nop8[8] = { '\x0f', '\x1f', '\x84', // nopl 0L(%rax,%rax,1)
1907+ '\x00', '\x00', '\x00',
1908+ '\x00', '\x00' };
1909+ const char nop9[9] = { '\x66', '\x0f', '\x1f', // nopw 0L(%rax,%rax,1)
1910+ '\x84', '\x00', '\x00',
1911+ '\x00', '\x00', '\x00' };
1912+ const char nop10[10] = { '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1)
1913+ '\x1f', '\x84', '\x00',
1914+ '\x00', '\x00', '\x00',
1915+ '\x00' };
1916+ const char nop11[11] = { '\x66', '\x66', '\x2e', // data16
1917+ '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1)
1918+ '\x00', '\x00', '\x00',
1919+ '\x00', '\x00' };
1920+ const char nop12[12] = { '\x66', '\x66', '\x66', // data16; data16
1921+ '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1)
1922+ '\x84', '\x00', '\x00',
1923+ '\x00', '\x00', '\x00' };
1924+ const char nop13[13] = { '\x66', '\x66', '\x66', // data16; data16; data16
1925+ '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1)
1926+ '\x1f', '\x84', '\x00',
1927+ '\x00', '\x00', '\x00',
1928+ '\x00' };
1929+ const char nop14[14] = { '\x66', '\x66', '\x66', // data16; data16; data16
1930+ '\x66', '\x66', '\x2e', // data16
1931+ '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1)
1932+ '\x00', '\x00', '\x00',
1933+ '\x00', '\x00' };
1934+ const char nop15[15] = { '\x66', '\x66', '\x66', // data16; data16; data16
1935+ '\x66', '\x66', '\x66', // data16; data16
1936+ '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1)
1937+ '\x84', '\x00', '\x00',
1938+ '\x00', '\x00', '\x00' };
1939
1940 const char* nops[16] = {
1941 NULL,
1942--
19431.7.9.5
1944