diff options
author | Ian Lance Taylor <ian@airs.com> | 2009-03-24 18:04:26 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2009-03-24 18:04:26 +0000 |
commit | 26736d8ec174d5de8d1699ed7b482282d587c270 (patch) | |
tree | 76a45d6b609ebd3aee1166f7bfa8c8bdeb83d520 /gold/output.cc | |
parent | 22fd9730a06b23ad93f31fed3377fcc51f3447df (diff) | |
download | gdb-26736d8ec174d5de8d1699ed7b482282d587c270.zip gdb-26736d8ec174d5de8d1699ed7b482282d587c270.tar.gz gdb-26736d8ec174d5de8d1699ed7b482282d587c270.tar.bz2 |
* 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/output.cc')
-rw-r--r-- | gold/output.cc | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/gold/output.cc b/gold/output.cc index cb9e038..d70c37a 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); } |