This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[gold patch] Fix problem where --incremental-base with huge file reports "file too short"
- From: Cary Coutant <ccoutant at google dot com>
- To: Ian Lance Taylor <iant at google dot com>, Binutils <binutils at sourceware dot org>
- Date: Tue, 11 Oct 2011 16:34:26 -0700
- Subject: [gold patch] Fix problem where --incremental-base with huge file reports "file too short"
When running the linker with --incremental-base pointing to a file
larger than 2GB, I found that I forgot to handle the case where read()
might return early. This patch adds a loop around the read().
Tested on x86_64. OK to commit?
-cary
2011-10-11 Cary Coutant <ccoutant@google.com>
* gold/output.cc (Output_file::open_base_file): Handle case where
::read returns less than requested size.
commit 70a0d37b350ac98d58a27a0df20a2c2137d74016
Author: Cary Coutant <ccoutant@google.com>
Date: Tue Oct 11 16:27:17 2011 -0700
Add loop around ::read when reading base file.
diff --git a/gold/output.cc b/gold/output.cc
index d6bdaba..2618f88 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -4893,17 +4893,27 @@ Output_file::open_base_file(const char*
base_name, bool writable)
if (use_base_file)
{
this->open(s.st_size);
- ssize_t len = ::read(o, this->base_, s.st_size);
- if (len < 0)
- {
- gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
- return false;
- }
- if (len < s.st_size)
- {
- gold_info(_("%s: file too short"), base_name);
- return false;
- }
+ ssize_t base_size = s.st_size;
+ unsigned char* base = this->base_;
+ while (base_size > 0)
+ {
+ ssize_t len = ::read(o, base, base_size);
+ if (len < 0)
+ {
+ gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
+ return false;
+ }
+ if (len == 0)
+ {
+ gold_info(_("%s: file too short: read only %lld of %lld bytes"),
+ base_name,
+ static_cast<long long>(s.st_size - base_size),
+ static_cast<long long>(s.st_size));
+ return false;
+ }
+ base += len;
+ base_size -= len;
+ }
::close(o);
return true;
}