This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gold patch committed: If file mmap fails, try anonymous mmap
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Tue, 24 Mar 2009 11:05:40 -0700
- Subject: gold patch committed: If file mmap fails, try anonymous mmap
In some cases the file system does not support mmap of a file with
PROT_WRITE set. Reportedly this happens on some FUSE file systems. I
committed this gold patch from Elliott Hughes at Google to use an
anonymous mmap if the regular mmap fails.
Ian
2009-03-24 Elliott Hughes <enh@google.com>
* output.cc (Output_file::map_anonymous): Define.
(Output_file::map): Use map_anonymous. If the regular mmap fails,
try an anonymous one. Report the size if the mmap fails.
* output.h (class Output_file): Declare map_anonymous.
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.88
diff -u -p -r1.88 output.cc
--- output.cc 24 Mar 2009 00:31:28 -0000 1.88
+++ output.cc 24 Mar 2009 18:02:08 -0000
@@ -3380,6 +3380,17 @@ Output_file::resize(off_t file_size)
}
}
+// Map a block of memory which will later be written to the file.
+// Return a pointer to the memory.
+
+void*
+Output_file::map_anonymous()
+{
+ this->map_is_anonymous_ = true;
+ return ::mmap(NULL, this->file_size_, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+}
+
// Map the file into memory.
void
@@ -3396,11 +3407,7 @@ Output_file::map()
|| ::fstat(o, &statbuf) != 0
|| !S_ISREG(statbuf.st_mode)
|| this->is_temporary_)
- {
- this->map_is_anonymous_ = true;
- base = ::mmap(NULL, this->file_size_, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- }
+ base = this->map_anonymous();
else
{
// Ensure that we have disk space available for the file. If we
@@ -3418,9 +3425,19 @@ Output_file::map()
this->map_is_anonymous_ = false;
base = ::mmap(NULL, this->file_size_, PROT_READ | PROT_WRITE,
MAP_SHARED, o, 0);
+
+ // The mmap call might fail because of file system issues: the
+ // file system might not support mmap at all, or it might not
+ // support mmap with PROT_WRITE. I'm not sure which errno
+ // values we will see in all cases, so if the mmap fails for any
+ // reason try for an anonymous map.
+ if (base == MAP_FAILED)
+ base = this->map_anonymous();
}
if (base == MAP_FAILED)
- gold_fatal(_("%s: mmap: %s"), this->name_, strerror(errno));
+ gold_fatal(_("%s: mmap: failed to allocate %lu bytes for output file: %s"),
+ this->name_, static_cast<unsigned long>(this->file_size_),
+ strerror(errno));
this->base_ = static_cast<unsigned char*>(base);
}
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.77
diff -u -p -r1.77 output.h
--- output.h 28 Feb 2009 00:12:26 -0000 1.77
+++ output.h 24 Mar 2009 18:02:08 -0000
@@ -3115,10 +3115,14 @@ class Output_file
{ }
private:
- // Map the file into memory and return a pointer to the map.
+ // Map the file into memory.
void
map();
+ // Allocate anonymous memory for the file.
+ void*
+ map_anonymous();
+
// Unmap the file from memory (and flush to disk buffers).
void
unmap();