This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
     }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]