mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
* gold.cc (queue_initial_tasks): Pass incremental base filename
to Output_file::open_base_file; don't print error message. * incremental-dump.cc (main): Adjust call to Output_file::open_for_modification. * incremental-dump.cc (main): Likewise. * incremental.cc (Incremental_inputs::report_command_line): Ignore --incremental-base option when comparing command lines. Ignore parameter when given as separate argument. * options.h (class General_options): Add --incremental-base. * output.cc (Output_file::Output_file): (Output_file::open_base_file): Add base_name and writable parameters; read base file into new file; print error message here. (Output_file::map_no_anonymous): Add writable parameter; adjust all callers. * output.h (Output_file::open_for_modification): Rename to... (Output_file::open_base_file): ...this; add base_name and writable parameters; adjust all callers. (Output_file::map_no_anonymous): Add writable parameter; adjust all callers. * testsuite/Makefile.am (incremental_test_4): Test --incremental-base. * testsuite/Makefile.in: Regenerate.
This commit is contained in:
parent
2eedd7063f
commit
aa92d6edc4
@ -1,3 +1,28 @@
|
|||||||
|
2011-05-24 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
|
* gold.cc (queue_initial_tasks): Pass incremental base filename
|
||||||
|
to Output_file::open_base_file; don't print error message.
|
||||||
|
* incremental-dump.cc (main): Adjust call to
|
||||||
|
Output_file::open_for_modification.
|
||||||
|
* incremental-dump.cc (main): Likewise.
|
||||||
|
* incremental.cc (Incremental_inputs::report_command_line):
|
||||||
|
Ignore --incremental-base option when comparing command lines.
|
||||||
|
Ignore parameter when given as separate argument.
|
||||||
|
* options.h (class General_options): Add --incremental-base.
|
||||||
|
* output.cc (Output_file::Output_file):
|
||||||
|
(Output_file::open_base_file): Add base_name and writable parameters;
|
||||||
|
read base file into new file; print error message here.
|
||||||
|
(Output_file::map_no_anonymous): Add writable parameter; adjust all
|
||||||
|
callers.
|
||||||
|
* output.h (Output_file::open_for_modification): Rename to...
|
||||||
|
(Output_file::open_base_file): ...this; add base_name and
|
||||||
|
writable parameters; adjust all callers.
|
||||||
|
(Output_file::map_no_anonymous): Add writable parameter; adjust all
|
||||||
|
callers.
|
||||||
|
* testsuite/Makefile.am (incremental_test_4): Test
|
||||||
|
--incremental-base.
|
||||||
|
* testsuite/Makefile.in: Regenerate.
|
||||||
|
|
||||||
2011-05-24 Cary Coutant <ccoutant@google.com>
|
2011-05-24 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
* testsuite/Makefile.am: Add incremental_test_2, incremental_test_3,
|
* testsuite/Makefile.am: Add incremental_test_2, incremental_test_3,
|
||||||
|
@ -204,11 +204,7 @@ queue_initial_tasks(const General_options& options,
|
|||||||
if (parameters->incremental_update())
|
if (parameters->incremental_update())
|
||||||
{
|
{
|
||||||
Output_file* of = new Output_file(options.output_file_name());
|
Output_file* of = new Output_file(options.output_file_name());
|
||||||
if (!of->open_for_modification())
|
if (of->open_base_file(options.incremental_base(), true))
|
||||||
gold_info(_("incremental update not possible: "
|
|
||||||
"cannot open %s"),
|
|
||||||
options.output_file_name());
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ibase = open_incremental_binary(of);
|
ibase = open_incremental_binary(of);
|
||||||
if (ibase != NULL
|
if (ibase != NULL
|
||||||
|
@ -449,10 +449,10 @@ main(int argc, char** argv)
|
|||||||
|
|
||||||
Output_file* file = new Output_file(filename);
|
Output_file* file = new Output_file(filename);
|
||||||
|
|
||||||
bool t = file->open_for_modification();
|
bool t = file->open_base_file(NULL, false);
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: open_for_modification(%s): %s\n", argv[0], filename,
|
fprintf(stderr, "%s: open_base_file(%s): %s\n", argv[0], filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -861,8 +861,17 @@ Incremental_inputs::report_command_line(int argc, const char* const* argv)
|
|||||||
|| strcmp(argv[i], "--incremental-changed") == 0
|
|| strcmp(argv[i], "--incremental-changed") == 0
|
||||||
|| strcmp(argv[i], "--incremental-unchanged") == 0
|
|| strcmp(argv[i], "--incremental-unchanged") == 0
|
||||||
|| strcmp(argv[i], "--incremental-unknown") == 0
|
|| strcmp(argv[i], "--incremental-unknown") == 0
|
||||||
|
|| is_prefix_of("--incremental-base=", argv[i])
|
||||||
|| is_prefix_of("--debug=", argv[i]))
|
|| is_prefix_of("--debug=", argv[i]))
|
||||||
continue;
|
continue;
|
||||||
|
if (strcmp(argv[i], "--incremental-base") == 0
|
||||||
|
|| strcmp(argv[i], "--debug") == 0)
|
||||||
|
{
|
||||||
|
// When these options are used without the '=', skip the
|
||||||
|
// following parameter as well.
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
args.append(" '");
|
args.append(" '");
|
||||||
// Now append argv[i], but with all single-quotes escaped
|
// Now append argv[i], but with all single-quotes escaped
|
||||||
|
@ -787,6 +787,11 @@ class General_options
|
|||||||
DEFINE_special(incremental_update, options::TWO_DASHES, '\0',
|
DEFINE_special(incremental_update, options::TWO_DASHES, '\0',
|
||||||
N_("Do an incremental link; exit if not possible"), NULL);
|
N_("Do an incremental link; exit if not possible"), NULL);
|
||||||
|
|
||||||
|
DEFINE_string(incremental_base, options::TWO_DASHES, '\0', NULL,
|
||||||
|
N_("Set base file for incremental linking"
|
||||||
|
" (default is output file)"),
|
||||||
|
N_("FILE"));
|
||||||
|
|
||||||
DEFINE_special(incremental_changed, options::TWO_DASHES, '\0',
|
DEFINE_special(incremental_changed, options::TWO_DASHES, '\0',
|
||||||
N_("Assume files changed"), NULL);
|
N_("Assume files changed"), NULL);
|
||||||
|
|
||||||
|
@ -4562,31 +4562,77 @@ Output_file::Output_file(const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to open an existing file. Returns false if the file doesn't
|
// Try to open an existing file. Returns false if the file doesn't
|
||||||
// exist, has a size of 0 or can't be mmapped.
|
// exist, has a size of 0 or can't be mmapped. If BASE_NAME is not
|
||||||
|
// NULL, open that file as the base for incremental linking, and
|
||||||
|
// copy its contents to the new output file. This routine can
|
||||||
|
// be called for incremental updates, in which case WRITABLE should
|
||||||
|
// be true, or by the incremental-dump utility, in which case
|
||||||
|
// WRITABLE should be false.
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Output_file::open_for_modification()
|
Output_file::open_base_file(const char* base_name, bool writable)
|
||||||
{
|
{
|
||||||
// The name "-" means "stdout".
|
// The name "-" means "stdout".
|
||||||
if (strcmp(this->name_, "-") == 0)
|
if (strcmp(this->name_, "-") == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool use_base_file = base_name != NULL;
|
||||||
|
if (!use_base_file)
|
||||||
|
base_name = this->name_;
|
||||||
|
else if (strcmp(base_name, this->name_) == 0)
|
||||||
|
gold_fatal(_("%s: incremental base and output file name are the same"),
|
||||||
|
base_name);
|
||||||
|
|
||||||
// Don't bother opening files with a size of zero.
|
// Don't bother opening files with a size of zero.
|
||||||
struct stat s;
|
struct stat s;
|
||||||
if (::stat(this->name_, &s) != 0 || s.st_size == 0)
|
if (::stat(base_name, &s) != 0)
|
||||||
return false;
|
{
|
||||||
|
gold_info(_("%s: stat: %s"), base_name, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (s.st_size == 0)
|
||||||
|
{
|
||||||
|
gold_info(_("%s: incremental base file is empty"), base_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int o = open_descriptor(-1, this->name_, O_RDWR, 0);
|
// If we're using a base file, we want to open it read-only.
|
||||||
|
if (use_base_file)
|
||||||
|
writable = false;
|
||||||
|
|
||||||
|
int oflags = writable ? O_RDWR : O_RDONLY;
|
||||||
|
int o = open_descriptor(-1, base_name, oflags, 0);
|
||||||
if (o < 0)
|
if (o < 0)
|
||||||
gold_fatal(_("%s: open: %s"), this->name_, strerror(errno));
|
{
|
||||||
|
gold_info(_("%s: open: %s"), base_name, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the base file and the output file are different, open a
|
||||||
|
// new output file and read the contents from the base file into
|
||||||
|
// the newly-mapped region.
|
||||||
|
if (use_base_file)
|
||||||
|
{
|
||||||
|
this->open(s.st_size);
|
||||||
|
ssize_t len = ::read(o, this->base_, s.st_size);
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (len < s.st_size)
|
||||||
|
{
|
||||||
|
gold_info(_("%s: file too short"), base_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
::close(o);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
this->o_ = o;
|
this->o_ = o;
|
||||||
this->file_size_ = s.st_size;
|
this->file_size_ = s.st_size;
|
||||||
|
|
||||||
// If the file can't be mmapped, copying the content to an anonymous
|
if (!this->map_no_anonymous(writable))
|
||||||
// map will probably negate the performance benefits of incremental
|
|
||||||
// linking. This could be helped by using views and loading only
|
|
||||||
// the necessary parts, but this is not supported as of now.
|
|
||||||
if (!this->map_no_anonymous())
|
|
||||||
{
|
{
|
||||||
release_descriptor(o, true);
|
release_descriptor(o, true);
|
||||||
this->o_ = -1;
|
this->o_ = -1;
|
||||||
@ -4688,7 +4734,7 @@ Output_file::resize(off_t file_size)
|
|||||||
{
|
{
|
||||||
this->unmap();
|
this->unmap();
|
||||||
this->file_size_ = file_size;
|
this->file_size_ = file_size;
|
||||||
if (!this->map_no_anonymous())
|
if (!this->map_no_anonymous(true))
|
||||||
gold_fatal(_("%s: mmap: %s"), this->name_, strerror(errno));
|
gold_fatal(_("%s: mmap: %s"), this->name_, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4715,9 +4761,10 @@ Output_file::map_anonymous()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Map the file into memory. Return whether the mapping succeeded.
|
// Map the file into memory. Return whether the mapping succeeded.
|
||||||
|
// If WRITABLE is true, map with write access.
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Output_file::map_no_anonymous()
|
Output_file::map_no_anonymous(bool writable)
|
||||||
{
|
{
|
||||||
const int o = this->o_;
|
const int o = this->o_;
|
||||||
|
|
||||||
@ -4739,12 +4786,14 @@ Output_file::map_no_anonymous()
|
|||||||
// output file will wind up incomplete, but we will have already
|
// output file will wind up incomplete, but we will have already
|
||||||
// exited. The alternative to fallocate would be to use fdatasync,
|
// exited. The alternative to fallocate would be to use fdatasync,
|
||||||
// but that would be a more significant performance hit.
|
// but that would be a more significant performance hit.
|
||||||
if (::posix_fallocate(o, 0, this->file_size_) < 0)
|
if (writable && ::posix_fallocate(o, 0, this->file_size_) < 0)
|
||||||
gold_fatal(_("%s: %s"), this->name_, strerror(errno));
|
gold_fatal(_("%s: %s"), this->name_, strerror(errno));
|
||||||
|
|
||||||
// Map the file into memory.
|
// Map the file into memory.
|
||||||
base = ::mmap(NULL, this->file_size_, PROT_READ | PROT_WRITE,
|
int prot = PROT_READ;
|
||||||
MAP_SHARED, o, 0);
|
if (writable)
|
||||||
|
prot |= PROT_WRITE;
|
||||||
|
base = ::mmap(NULL, this->file_size_, prot, MAP_SHARED, o, 0);
|
||||||
|
|
||||||
// The mmap call might fail because of file system issues: the file
|
// The mmap call might fail because of file system issues: the file
|
||||||
// system might not support mmap at all, or it might not support
|
// system might not support mmap at all, or it might not support
|
||||||
@ -4762,7 +4811,7 @@ Output_file::map_no_anonymous()
|
|||||||
void
|
void
|
||||||
Output_file::map()
|
Output_file::map()
|
||||||
{
|
{
|
||||||
if (this->map_no_anonymous())
|
if (this->map_no_anonymous(true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// The mmap call might fail because of file system issues: the file
|
// The mmap call might fail because of file system issues: the file
|
||||||
|
@ -4188,9 +4188,10 @@ class Output_file
|
|||||||
|
|
||||||
// Try to open an existing file. Returns false if the file doesn't
|
// Try to open an existing file. Returns false if the file doesn't
|
||||||
// exist, has a size of 0 or can't be mmaped. This method is
|
// exist, has a size of 0 or can't be mmaped. This method is
|
||||||
// thread-unsafe.
|
// thread-unsafe. If BASE_NAME is not NULL, use the contents of
|
||||||
|
// that file as the base for incremental linking.
|
||||||
bool
|
bool
|
||||||
open_for_modification();
|
open_base_file(const char* base_name, bool writable);
|
||||||
|
|
||||||
// Open the output file. FILE_SIZE is the final size of the file.
|
// Open the output file. FILE_SIZE is the final size of the file.
|
||||||
// If the file already exists, it is deleted/truncated. This method
|
// If the file already exists, it is deleted/truncated. This method
|
||||||
@ -4275,7 +4276,7 @@ class Output_file
|
|||||||
|
|
||||||
// Map the file into memory.
|
// Map the file into memory.
|
||||||
bool
|
bool
|
||||||
map_no_anonymous();
|
map_no_anonymous(bool);
|
||||||
|
|
||||||
// Unmap the file from memory (and flush to disk buffers).
|
// Unmap the file from memory (and flush to disk buffers).
|
||||||
void
|
void
|
||||||
|
@ -1840,13 +1840,15 @@ incremental_test_3: two_file_test_1.o two_file_test_1b_v1.o two_file_test_1b.o \
|
|||||||
$(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ two_file_test_1.o two_file_test_tmp.o two_file_test_2.o two_file_test_main.o
|
$(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ two_file_test_1.o two_file_test_tmp.o two_file_test_2.o two_file_test_main.o
|
||||||
|
|
||||||
check_PROGRAMS += incremental_test_4
|
check_PROGRAMS += incremental_test_4
|
||||||
|
MOSTLYCLEANFILES += incremental_test_4.base
|
||||||
incremental_test_4: two_file_test_1.o two_file_test_1b.o two_file_test_2_v1.o \
|
incremental_test_4: two_file_test_1.o two_file_test_1b.o two_file_test_2_v1.o \
|
||||||
two_file_test_2.o two_file_test_main.o gcctestdir/ld
|
two_file_test_2.o two_file_test_main.o gcctestdir/ld
|
||||||
cp -f two_file_test_2_v1.o two_file_test_tmp.o
|
cp -f two_file_test_2_v1.o two_file_test_tmp.o
|
||||||
$(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
$(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
||||||
|
mv -f incremental_test_4 incremental_test_4.base
|
||||||
@sleep 1
|
@sleep 1
|
||||||
cp -f two_file_test_2.o two_file_test_tmp.o
|
cp -f two_file_test_2.o two_file_test_tmp.o
|
||||||
$(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
$(CXXLINK) -Wl,--incremental-update,--incremental-base=incremental_test_4.base -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
||||||
|
|
||||||
endif DEFAULT_TARGET_X86_64
|
endif DEFAULT_TARGET_X86_64
|
||||||
|
|
||||||
|
@ -436,7 +436,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_35 = incremental_test_2 \
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_35 = incremental_test_2 \
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_3 \
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_3 \
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_36 = two_file_test_tmp.o
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_36 = two_file_test_tmp.o \
|
||||||
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4.base
|
||||||
|
|
||||||
# These tests work with native and cross linkers.
|
# These tests work with native and cross linkers.
|
||||||
|
|
||||||
@ -4605,9 +4606,10 @@ uninstall-am:
|
|||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_test_2.o two_file_test_main.o gcctestdir/ld
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_test_2.o two_file_test_main.o gcctestdir/ld
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f two_file_test_2_v1.o two_file_test_tmp.o
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f two_file_test_2_v1.o two_file_test_tmp.o
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
||||||
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ mv -f incremental_test_4 incremental_test_4.base
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ @sleep 1
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ @sleep 1
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f two_file_test_2.o two_file_test_tmp.o
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f two_file_test_2.o two_file_test_tmp.o
|
||||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-update,--incremental-base=incremental_test_4.base -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
|
||||||
@NATIVE_OR_CROSS_LINKER_TRUE@script_test_10.o: script_test_10.s
|
@NATIVE_OR_CROSS_LINKER_TRUE@script_test_10.o: script_test_10.s
|
||||||
@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $<
|
@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $<
|
||||||
@NATIVE_OR_CROSS_LINKER_TRUE@script_test_10: $(srcdir)/script_test_10.t script_test_10.o gcctestdir/ld
|
@NATIVE_OR_CROSS_LINKER_TRUE@script_test_10: $(srcdir)/script_test_10.t script_test_10.o gcctestdir/ld
|
||||||
|
Loading…
Reference in New Issue
Block a user