summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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