This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[GOLD] add new method for computing a build ID
- From: gpike at chromium dot org
- To: binutils at sourceware dot org
- Date: Wed, 3 Oct 2012 12:20:17 -0700 (PDT)
- Subject: [GOLD] add new method for computing a build ID
Motivation for the change: computing a build ID is currently a
sequential bottleneck. E.g., in the example I mentioned in my email
yesterday, a 24.5s link was spending 5.2s on the build ID computation.
The patch adds a new mathematical function for build ID, in addition
to the two that are available now (SHA-1 and MD5). The new function
does MD5 on chunks of the output file and then does SHA-1 on the MD5
hashes of the chunks. This is easy to parallelize.
I am new to gold and binutils so I may well have screwed up the coding
style or made other errors.
* layout.cc (Chunk_hasher): New class.
(Layout::create_build_id): Allow --build-id=tree.
(Layout::write_build_id): Use parallel build ID computation if
must_use_chunked_build_id_computation() says to. Otherwise use
SHA-1 or MD5 as before. Replace {sha1,md5}_process_bytes with
{sha1,md5}_buffer to get the same functionality in fewer lines of code.
(Layout::must_use_chunked_build_id_computation): New function.
(Close_task_runner::run): adjust to new interface for
Layout::write_build_id.
* layout.h (Layout::must_use_chunked_build_id_computation): New
function declaration.
(Layout::create_build_id): Modified function declaration.
* Makefile.am: add testing of --build-id=tree and related new options
(these tests will be invoked by "make check")
* Makefile.in: regenerate
* options.h (General_options): make "--build-id" default to tree
rather than sha1. Add two new options related to --build-id=tree:
--build-id-chunk-size-for-treehash and
--build-id-min-file-size-for-treehash.
Index: gold/layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.238
diff -u -u -r1.238 layout.cc
--- gold/layout.cc 10 Sep 2012 23:10:41 -0000 1.238
+++ gold/layout.cc 2 Oct 2012 21:41:41 -0000
@@ -236,6 +236,151 @@
program_name, Free_list::num_allocate_visits);
}
+static const size_t MD5_OUTPUT_SIZE_IN_BYTES = 16;
+
+class Chunk_hasher
+{
+ public:
+ Chunk_hasher(const unsigned char* s,
+ size_t len,
+ unsigned char* output,
+ int num_threads,
+ Workqueue* workqueue)
+ : lock_(),
+ condvar_(this->lock_),
+ s_(s),
+ len_(len),
+ output_(output),
+ num_threads_(num_threads),
+ workqueue_(workqueue),
+ num_hashes_((len == 0) ? 0
+ : ((len - 1) / (parameters->options()
+ .build_id_chunk_size_for_treehash())
+ + 1)),
+ num_hashes_started_(0),
+ num_hashes_finished_(0),
+ bytes_for_md5_hashes_(this->num_hashes_ * MD5_OUTPUT_SIZE_IN_BYTES),
+ array_of_hashes_(new unsigned char[this->bytes_for_md5_hashes_]),
+ waiting_(false)
+ { }
+
+ ~Chunk_hasher()
+ { delete[] this->array_of_hashes_; }
+
+ void
+ run();
+
+ void
+ do_work();
+
+ private:
+ class Chunk_hash_task : public Task
+ {
+ public:
+ explicit Chunk_hash_task(Chunk_hasher* hasher)
+ : hasher_(hasher)
+ { }
+
+ void
+ run(Workqueue*)
+ { this->hasher_->do_work(); }
+
+ Task_token*
+ is_runnable()
+ { return NULL; }
+
+ void
+ locks(Task_locker*)
+ { }
+
+ std::string
+ get_name() const
+ { return "Chunk_hash_task"; }
+
+ private:
+ Chunk_hasher* hasher_;
+ };
+
+ Lock lock_;
+ Condvar condvar_;
+ const unsigned char* s_;
+ size_t len_;
+ unsigned char* output_;
+ int num_threads_;
+ Workqueue* workqueue_;
+ size_t num_hashes_;
+ size_t num_hashes_started_;
+ size_t num_hashes_finished_;
+ size_t bytes_for_md5_hashes_;
+ unsigned char* array_of_hashes_;
+ bool waiting_;
+};
+
+void
+Chunk_hasher::run()
+{
+ // Begin computation of MD5 hashes.
+ if (parameters->options().threads())
+ {
+ if (this->num_threads_ < 1)
+ this->num_threads_ = this->num_hashes_;
+ for (int i = 0; i < this->num_threads_; i++)
+ this->workqueue_->queue(new Chunk_hash_task(this));
+ }
+ else
+ this->do_work();
+
+ this->lock_.acquire();
+ // If there's still work to do, set waiting_ to true and wait() on
+ // the CondVar. Then, when some other thread finishes the last bit
+ // of work, it will signal() if waiting_ is true.
+ this->waiting_ = (this->num_hashes_finished_ < this->num_hashes_);
+ if (this->waiting_)
+ this->condvar_.wait();
+ gold_assert(this->num_hashes_started_ == this->num_hashes_);
+ gold_assert(this->num_hashes_finished_ == this->num_hashes_);
+ this->lock_.release();
+ // MD5 hashes are done. Compute SHA-1 hash of MD5 hashes.
+ sha1_buffer(reinterpret_cast<const char*>(this->array_of_hashes_),
+ this->bytes_for_md5_hashes_,
+ this->output_);
+}
+
+void
+Chunk_hasher::do_work()
+{
+ const size_t default_chunk_size =
+ parameters->options().build_id_chunk_size_for_treehash();
+ for (;;)
+ {
+ const unsigned char* chunk;
+ size_t chunk_size;
+ size_t chunk_index;
+ // Find work to do, or return if there's none.
+ {
+ Hold_lock h(this->lock_);
+ if (this->len_ == 0)
+ return;
+ chunk = this->s_;
+ chunk_size = std::min<size_t>(this->len_, default_chunk_size);
+ chunk_index = this->num_hashes_started_++;
+ this->s_ += chunk_size;
+ this->len_ -= chunk_size;
+ }
+ // Compute MD5 hash of one chunk.
+ md5_buffer(reinterpret_cast<const char*>(chunk), chunk_size,
+ (this->array_of_hashes_
+ + (chunk_index * MD5_OUTPUT_SIZE_IN_BYTES)));
+ // Record that one more chunk is done.
+ {
+ Hold_lock h(this->lock_);
+ if (++this->num_hashes_finished_ == this->num_hashes_
+ && this->waiting_)
+ this->condvar_.signal();
+ }
+ }
+}
+
// Layout::Relaxation_debug_check methods.
// Check that sections and special data are in reset states.
@@ -2872,7 +3017,7 @@
std::string desc;
if (strcmp(style, "md5") == 0)
descsz = 128 / 8;
- else if (strcmp(style, "sha1") == 0)
+ else if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
descsz = 160 / 8;
else if (strcmp(style, "uuid") == 0)
{
@@ -5144,12 +5289,15 @@
this->section_headers_->write(of);
}
-// If the build ID requires computing a checksum, do so here, and
-// write it out. We compute a checksum over the entire file because
-// that is simplest.
+// Build IDs can be computed as a "flat" sha1 or md5 of a string of bytes,
+// or as a "tree" where each chunk of the string is hashed and then those
+// hashes are put into a (much smaller) string which is hashed with sha1.
+// We compute a checksum over the entire file because that is simplest.
void
-Layout::write_build_id(Output_file* of) const
+Layout::write_build_id(Workqueue* workqueue,
+ int num_threads,
+ Output_file* of) const
{
if (this->build_id_note_ == NULL)
return;
@@ -5157,31 +5305,50 @@
const unsigned char* iv = of->get_input_view(0, this->output_file_size_);
unsigned char* ov = of->get_output_view(this->build_id_note_->offset(),
- this->build_id_note_->data_size());
+ this->build_id_note_->data_size());
const char* style = parameters->options().build_id();
- if (strcmp(style, "sha1") == 0)
+
+ const size_t output_file_size = this->output_file_size();
+
+ if (this->must_use_chunked_build_id_computation())
{
- sha1_ctx ctx;
- sha1_init_ctx(&ctx);
- sha1_process_bytes(iv, this->output_file_size_, &ctx);
- sha1_finish_ctx(&ctx, ov);
- }
- else if (strcmp(style, "md5") == 0)
- {
- md5_ctx ctx;
- md5_init_ctx(&ctx);
- md5_process_bytes(iv, this->output_file_size_, &ctx);
- md5_finish_ctx(&ctx, ov);
+ gold_assert(strcmp(style, "tree") == 0);
+ Chunk_hasher(iv,
+ output_file_size,
+ ov,
+ num_threads,
+ workqueue).run();
}
else
- gold_unreachable();
+ {
+ // If we get here with style == "tree" then the output must be
+ // too small for chunking, and we use SHA-1 in that case.
+ if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
+ sha1_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+ else if (strcmp(style, "md5") == 0)
+ md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+ else
+ gold_unreachable();
+ }
of->write_output_view(this->build_id_note_->offset(),
this->build_id_note_->data_size(),
ov);
- of->free_input_view(0, this->output_file_size_, iv);
+ of->free_input_view(0, output_file_size, iv);
+}
+
+bool
+Layout::must_use_chunked_build_id_computation() const
+{
+ uint64_t filesize = (this->output_file_size_ <= 0 ? 0
+ : static_cast<uint64_t>(this->output_file_size_));
+ return this->build_id_note_ != NULL
+ && (strcmp(parameters->options().build_id(), "tree") == 0)
+ && (parameters->options().build_id_chunk_size_for_treehash() > 0)
+ && (filesize >=
+ parameters->options().build_id_min_file_size_for_treehash());
}
// Write out a binary file. This is called after the link is
@@ -5374,10 +5541,12 @@
// Run the task--close the file.
void
-Close_task_runner::run(Workqueue*, const Task*)
+Close_task_runner::run(Workqueue* workqueue, const Task*)
{
// If we need to compute a checksum for the BUILD if, we do so here.
- this->layout_->write_build_id(this->of_);
+ this->layout_->write_build_id(workqueue,
+ this->options_->thread_count_final(),
+ this->of_);
// If we've been asked to create a binary file, we do so here.
if (this->options_->oformat_enum() != General_options::OBJECT_FORMAT_ELF)
Index: gold/layout.h
===================================================================
RCS file: /cvs/src/src/gold/layout.h,v
retrieving revision 1.105
diff -u -u -r1.105 layout.h
--- gold/layout.h 24 Aug 2012 18:35:34 -0000 1.105
+++ gold/layout.h 2 Oct 2012 21:41:41 -0000
@@ -884,9 +884,12 @@
const Output_data_reloc_generic* dyn_rel,
bool add_debug, bool dynrel_includes_plt);
+ bool
+ must_use_chunked_build_id_computation() const;
+
// Compute and write out the build ID if needed.
void
- write_build_id(Output_file*) const;
+ write_build_id(Workqueue* workqueue, int num_threads, Output_file* of) const;
// Rewrite output file in binary format.
void
Index: gold/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/Makefile.am,v
retrieving revision 1.67
diff -u -u -r1.67 Makefile.am
--- gold/Makefile.am 15 Sep 2012 17:11:28 -0000 1.67
+++ gold/Makefile.am 2 Oct 2012 21:41:41 -0000
@@ -276,5 +276,52 @@
check_PROGRAMS = ld1 ld2 ld1-r ld2-r
TESTS = bootstrap-test bootstrap-test-r
+# If THREADS then we verify that changing the number of threads doesn't
+# change the treehash computation, by building ld1 and ld3 the same way
+# except for the number of threads. However, the build ID should change
+# if we change the chunk size for --build-id=tree, so ld4 should be different.
+if THREADS
+check_PROGRAMS += ld3 ld4
+TESTS += bootstrap-test-treehash bootstrap-test-treehash-chunksize
+
+gcctestdir3/ld: ld-new
+ test -d gcctestdir3 || mkdir -p gcctestdir3
+ rm -f gcctestdir3/ld
+ (cd gcctestdir3 && $(LN_S) ../ld-new ld)
+
+ld3_SOURCES = $(sources_var)
+ld3_DEPENDENCIES = $(deps_var) gcctestdir3/ld
+ld3_LDADD = $(ldadd_var)
+ld3_LDFLAGS = -Bgcctestdir3/
+
+gcctestdir4/ld: ld-new
+ test -d gcctestdir4 || mkdir -p gcctestdir4
+ rm -f gcctestdir4/ld
+ (cd gcctestdir4 && $(LN_S) ../ld-new ld)
+
+ld4_SOURCES = $(sources_var)
+ld4_DEPENDENCIES = $(deps_var) gcctestdir4/ld
+ld4_LDADD = $(ldadd_var)
+ld4_LDFLAGS = -Bgcctestdir4/
+
+ld1_LDFLAGS += -Wl,--build-id=tree -Wl,--build-id-chunk-size-for-treehash=12345 -Wl,--build-id-min-file-size-for-treehash=0 -Wl,--thread-count=3
+ld2_LDFLAGS += -Wl,--build-id=tree -Wl,--build-id-chunk-size-for-treehash=12345 -Wl,--build-id-min-file-size-for-treehash=0 -Wl,--thread-count=3
+ld3_LDFLAGS += -Wl,--build-id=tree -Wl,--build-id-chunk-size-for-treehash=12345 -Wl,--build-id-min-file-size-for-treehash=0 -Wl,--thread-count=13
+ld4_LDFLAGS += -Wl,--build-id=tree -Wl,--build-id-chunk-size-for-treehash=12346 -Wl,--build-id-min-file-size-for-treehash=0 -Wl,--thread-count=3
+
+bootstrap-test-treehash: ld1 ld3
+ rm -f $@
+ echo "#!/bin/sh" > $@
+ echo "cmp ld1 ld3" > $@
+ chmod +x $@
+
+bootstrap-test-treehash-chunksize: ld1 ld4
+ rm -f $@
+ echo "#!/bin/sh" > $@
+ echo "cmp ld1 ld4 | grep ." > $@
+ chmod +x $@
+
+endif
+
endif
endif
Index: gold/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/Makefile.in,v
retrieving revision 1.94
diff -u -u -r1.94 Makefile.in
--- gold/Makefile.in 15 Sep 2012 17:11:28 -0000 1.94
+++ gold/Makefile.in 2 Oct 2012 21:41:41 -0000
@@ -41,7 +41,16 @@
noinst_PROGRAMS = ld-new$(EXEEXT) incremental-dump$(EXEEXT)
@GCC_TRUE@@NATIVE_LINKER_TRUE@check_PROGRAMS = ld1$(EXEEXT) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2$(EXEEXT) ld1-r$(EXEEXT) \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2-r$(EXEEXT)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2-r$(EXEEXT) $(am__EXEEXT_1)
+
+# If THREADS then we verify that changing the number of threads doesn't
+# change the treehash computation, by building ld1 and ld3 the same way
+# except for the number of threads. However, the build ID should change
+# if we change the chunk size for --build-id=tree, so ld4 should be different.
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@am__append_1 = ld3 ld4
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@am__append_2 = bootstrap-test-treehash bootstrap-test-treehash-chunksize
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@am__append_3 = -Wl,--build-id=tree -Wl,--build-id-chunk-size-for-treehash=12345 -Wl,--build-id-min-file-size-for-treehash=0 -Wl,--thread-count=3
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@am__append_4 = -Wl,--build-id=tree -Wl,--build-id-chunk-size-for-treehash=12345 -Wl,--build-id-min-file-size-for-treehash=0 -Wl,--thread-count=3
subdir = .
DIST_COMMON = NEWS README ChangeLog $(srcdir)/Makefile.in \
$(srcdir)/Makefile.am $(top_srcdir)/configure \
@@ -94,6 +103,9 @@
am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_2)
libgold_a_OBJECTS = $(am_libgold_a_OBJECTS)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@am__EXEEXT_1 = \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ ld3$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ ld4$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
am_incremental_dump_OBJECTS = incremental-dump.$(OBJEXT)
incremental_dump_OBJECTS = $(am_incremental_dump_OBJECTS)
@@ -122,6 +134,16 @@
ld2_r_OBJECTS = $(am_ld2_r_OBJECTS)
ld2_r_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(ld2_r_LDFLAGS) \
$(LDFLAGS) -o $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@am_ld3_OBJECTS = \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ $(am__objects_4)
+ld3_OBJECTS = $(am_ld3_OBJECTS)
+ld3_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(ld3_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@am_ld4_OBJECTS = \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ $(am__objects_4)
+ld4_OBJECTS = $(am_ld4_OBJECTS)
+ld4_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(ld4_LDFLAGS) \
+ $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
@@ -140,7 +162,8 @@
YLWRAP = $(top_srcdir)/../ylwrap
SOURCES = $(libgold_a_SOURCES) $(incremental_dump_SOURCES) \
$(ld_new_SOURCES) $(EXTRA_ld_new_SOURCES) $(ld1_SOURCES) \
- $(ld1_r_SOURCES) $(ld2_SOURCES) $(ld2_r_SOURCES)
+ $(ld1_r_SOURCES) $(ld2_SOURCES) $(ld2_r_SOURCES) \
+ $(ld3_SOURCES) $(ld4_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
@@ -518,11 +541,13 @@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_SOURCES = $(sources_var)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_DEPENDENCIES = $(deps_var) gcctestdir1/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_LDADD = $(ldadd_var)
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_LDFLAGS = -Bgcctestdir1/
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_LDFLAGS = -Bgcctestdir1/ \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(am__append_3)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_SOURCES = $(sources_var)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_DEPENDENCIES = $(deps_var) gcctestdir2/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_LDADD = $(ldadd_var)
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_LDFLAGS = -Bgcctestdir2/
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_LDFLAGS = -Bgcctestdir2/ \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(am__append_4)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_SOURCES = $(sources_var)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_DEPENDENCIES = libgold-1-r.o $(deps_var) gcctestdir1/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_LDADD = libgold-1-r.o $(ldadd_var)
@@ -531,7 +556,26 @@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_DEPENDENCIES = libgold-2-r.o $(deps_var) gcctestdir2-r/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_LDADD = libgold-2-r.o $(ldadd_var)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_LDFLAGS = -Bgcctestdir2-r/
-@GCC_TRUE@@NATIVE_LINKER_TRUE@TESTS = bootstrap-test bootstrap-test-r
+@GCC_TRUE@@NATIVE_LINKER_TRUE@TESTS = bootstrap-test bootstrap-test-r \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(am__append_2)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld3_SOURCES = $(sources_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld3_DEPENDENCIES = $(deps_var) gcctestdir3/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld3_LDADD = $(ldadd_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld3_LDFLAGS = \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Bgcctestdir3/ \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--build-id=tree \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--build-id-chunk-size-for-treehash=12345 \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--build-id-min-file-size-for-treehash=0 \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--thread-count=13
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld4_SOURCES = $(sources_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld4_DEPENDENCIES = $(deps_var) gcctestdir4/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld4_LDADD = $(ldadd_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ld4_LDFLAGS = \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Bgcctestdir4/ \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--build-id=tree \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--build-id-chunk-size-for-treehash=12346 \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--build-id-min-file-size-for-treehash=0 \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ -Wl,--thread-count=3
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -626,6 +670,12 @@
ld2-r$(EXEEXT): $(ld2_r_OBJECTS) $(ld2_r_DEPENDENCIES)
@rm -f ld2-r$(EXEEXT)
$(ld2_r_LINK) $(ld2_r_OBJECTS) $(ld2_r_LDADD) $(LIBS)
+ld3$(EXEEXT): $(ld3_OBJECTS) $(ld3_DEPENDENCIES)
+ @rm -f ld3$(EXEEXT)
+ $(ld3_LINK) $(ld3_OBJECTS) $(ld3_LDADD) $(LIBS)
+ld4$(EXEEXT): $(ld4_OBJECTS) $(ld4_DEPENDENCIES)
+ @rm -f ld4$(EXEEXT)
+ $(ld4_LINK) $(ld4_OBJECTS) $(ld4_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -686,6 +736,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symtab.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target-select.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tilegx.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workqueue-threads.Po@am__quote@
@@ -1015,6 +1066,10 @@
@p='bootstrap-test'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
bootstrap-test-r.log: bootstrap-test-r
@p='bootstrap-test-r'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+bootstrap-test-treehash.log: bootstrap-test-treehash
+ @p='bootstrap-test-treehash'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+bootstrap-test-treehash-chunksize.log: bootstrap-test-treehash-chunksize
+ @p='bootstrap-test-treehash-chunksize'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
.test.log:
@p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
@am__EXEEXT_TRUE@.test$(EXEEXT).log:
@@ -1227,6 +1282,28 @@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "cmp ld1-r ld2-r" > $@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ chmod +x $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@gcctestdir3/ld: ld-new
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ test -d gcctestdir3 || mkdir -p gcctestdir3
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ rm -f gcctestdir3/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ (cd gcctestdir3 && $(LN_S) ../ld-new ld)
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@gcctestdir4/ld: ld-new
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ test -d gcctestdir4 || mkdir -p gcctestdir4
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ rm -f gcctestdir4/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ (cd gcctestdir4 && $(LN_S) ../ld-new ld)
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@bootstrap-test-treehash: ld1 ld3
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ rm -f $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ echo "#!/bin/sh" > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ echo "cmp ld1 ld3" > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ chmod +x $@
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@bootstrap-test-treehash-chunksize: ld1 ld4
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ rm -f $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ echo "#!/bin/sh" > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ echo "cmp ld1 ld4 | grep ." > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@THREADS_TRUE@ chmod +x $@
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
Index: gold/options.h
===================================================================
RCS file: /cvs/src/src/gold/options.h,v
retrieving revision 1.177
diff -u -u -r1.177 options.h
--- gold/options.h 7 Jun 2012 05:14:44 -0000 1.177
+++ gold/options.h 2 Oct 2012 21:41:41 -0000
@@ -652,10 +652,19 @@
DEFINE_bool(Bsymbolic_functions, options::ONE_DASH, '\0', false,
N_("Bind defined function symbols locally"), NULL);
- DEFINE_optional_string(build_id, options::TWO_DASHES, '\0', "sha1",
+ DEFINE_optional_string(build_id, options::TWO_DASHES, '\0', "tree",
N_("Generate build ID note"),
N_("[=STYLE]"));
+ DEFINE_uint64(build_id_chunk_size_for_treehash,
+ options::TWO_DASHES, '\0', 2 << 20,
+ N_("Chunk size for '--build-id=tree'"), N_("SIZE"));
+
+ DEFINE_uint64(build_id_min_file_size_for_treehash, options::TWO_DASHES,
+ '\0', 200 << 20,
+ N_("Minimum output file size for '--build-id=tree' to work"
+ " differently than '--build-id=sha1'"), N_("SIZE"));
+
DEFINE_bool(check_sections, options::TWO_DASHES, '\0', true,
N_("Check segment addresses for overlaps (default)"),
N_("Do not check segment addresses for overlaps"));