aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-03-24 18:04:26 +0000
committerIan Lance Taylor <ian@airs.com>2009-03-24 18:04:26 +0000
commit26736d8ec174d5de8d1699ed7b482282d587c270 (patch)
tree76a45d6b609ebd3aee1166f7bfa8c8bdeb83d520 /gold
parent * target-select.cc (instantiate_target): Don't acquire the lock if (diff)
downloadbinutils-gdb-26736d8ec174d5de8d1699ed7b482282d587c270.tar.gz
binutils-gdb-26736d8ec174d5de8d1699ed7b482282d587c270.tar.bz2
binutils-gdb-26736d8ec174d5de8d1699ed7b482282d587c270.zip
* 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.
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog7
-rw-r--r--gold/output.cc29
-rw-r--r--gold/output.h6
3 files changed, 35 insertions, 7 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index bb76e937068..d233ab560b0 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,10 @@
+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.
+
2009-03-24 Ian Lance Taylor <iant@google.com>
* target-select.cc (instantiate_target): Don't acquire the lock if
diff --git a/gold/output.cc b/gold/output.cc
index cb9e0385020..d70c37a8300 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -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);
}
diff --git a/gold/output.h b/gold/output.h
index 6c37dfd0191..5d2c62f3e3c 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -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();