* configure.ac: Check for sys/mman.h and mmap. Check for mremap
with MREMAP_MAYMOVE. * output.h (class Output_file): Add map_is_allocated_ field. * output.cc: Only #include <sys/mman.h> if it exists. If mmap is not available, provide stubs. If mremap is not available, #define it to gold_mremap. (MREMAP_MAYMOVE): Define if not defined. (Output_file::Output_file): Initialize map_is_allocated_. (Output_file::resize): Check map_is_allocated_. (Output_file::map_anonymous): If mmap fails, use malloc. (Output_file::unmap): Don't do anything for an anonymous map. * fileread.cc: Only #include <sys/mman.h> if it exists. If mmap is not available, provide stubs. (File_read::View::~View): Use free rather than delete[]. (File_read::make_view): Use malloc rather than new[]. If mmap fails, use malloc. (File_read::find_or_make_view): Use malloc rather than new[]. * gold.h: Remove HAVE_REMAP code. * mremap.c: #include <errno.h>. Only #include <sys/mman.h> if it exists. Rename mremap to gold_mremap. If mmap is not available don't do anything. * configure, config.in: Rebuild.
This commit is contained in:
parent
32a946987b
commit
88597d3422
9 changed files with 317 additions and 54 deletions
|
@ -1,3 +1,28 @@
|
|||
2011-04-12 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* configure.ac: Check for sys/mman.h and mmap. Check for mremap
|
||||
with MREMAP_MAYMOVE.
|
||||
* output.h (class Output_file): Add map_is_allocated_ field.
|
||||
* output.cc: Only #include <sys/mman.h> if it exists. If mmap is
|
||||
not available, provide stubs. If mremap is not available, #define
|
||||
it to gold_mremap.
|
||||
(MREMAP_MAYMOVE): Define if not defined.
|
||||
(Output_file::Output_file): Initialize map_is_allocated_.
|
||||
(Output_file::resize): Check map_is_allocated_.
|
||||
(Output_file::map_anonymous): If mmap fails, use malloc.
|
||||
(Output_file::unmap): Don't do anything for an anonymous map.
|
||||
* fileread.cc: Only #include <sys/mman.h> if it exists. If mmap
|
||||
is not available, provide stubs.
|
||||
(File_read::View::~View): Use free rather than delete[].
|
||||
(File_read::make_view): Use malloc rather than new[]. If mmap
|
||||
fails, use malloc.
|
||||
(File_read::find_or_make_view): Use malloc rather than new[].
|
||||
* gold.h: Remove HAVE_REMAP code.
|
||||
* mremap.c: #include <errno.h>. Only #include <sys/mman.h> if it
|
||||
exists. Rename mremap to gold_mremap. If mmap is not available
|
||||
don't do anything.
|
||||
* configure, config.in: Rebuild.
|
||||
|
||||
2011-04-11 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* incremental.cc (Sized_incr_relobj::do_add_symbols): Always
|
||||
|
|
|
@ -87,7 +87,10 @@
|
|||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mremap' function. */
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the mremap function with MREMAP_MAYMOVE support */
|
||||
#undef HAVE_MREMAP
|
||||
|
||||
/* Define if compiler supports #pragma omp threadprivate */
|
||||
|
@ -120,6 +123,9 @@
|
|||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#undef HAVE_SYSCONF
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
|
|
67
gold/configure
vendored
67
gold/configure
vendored
|
@ -6486,18 +6486,32 @@ WARN_CXXFLAGS=`echo ${WARN_CFLAGS} | sed -e 's/-Wstrict-prototypes//' -e 's/-Wmi
|
|||
LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
|
||||
|
||||
for ac_func in chsize
|
||||
for ac_header in sys/mman.h
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "chsize" "ac_cv_func_chsize"
|
||||
if test "x$ac_cv_func_chsize" = x""yes; then :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_sys_mman_h" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_CHSIZE 1
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_func in chsize mmap
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
eval as_val=\$$as_ac_var
|
||||
if test "x$as_val" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
for ac_func in pread ftruncate mremap ffsll
|
||||
for ac_func in pread ftruncate ffsll
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
|
@ -6519,6 +6533,49 @@ done
|
|||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking mremap with MREMAP_MAYMOVE" >&5
|
||||
$as_echo_n "checking mremap with MREMAP_MAYMOVE... " >&6; }
|
||||
if test "${gold_cv_lib_mremap_maymove+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
|
||||
#include <sys/mman.h>
|
||||
void f() { mremap (0, 0, 0, MREMAP_MAYMOVE); }
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
gold_cv_lib_mremap_maymove=yes
|
||||
else
|
||||
gold_cv_lib_mremap_maymove=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gold_cv_lib_mremap_maymove" >&5
|
||||
$as_echo "$gold_cv_lib_mremap_maymove" >&6; }
|
||||
if test "$gold_cv_lib_mremap_maymove" = "yes"; then
|
||||
|
||||
$as_echo "#define HAVE_MREMAP 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" mremap.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS mremap.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
# Link in zlib if we can. This allows us to write compressed sections.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing zlibVersion" >&5
|
||||
$as_echo_n "checking for library containing zlibVersion... " >&6; }
|
||||
|
|
|
@ -393,8 +393,22 @@ dnl host dependent. If build == host, we can check getconf LFS_CFLAGS.
|
|||
LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
AC_SUBST(LFS_CFLAGS)
|
||||
|
||||
AC_CHECK_FUNCS(chsize)
|
||||
AC_REPLACE_FUNCS(pread ftruncate mremap ffsll)
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
AC_CHECK_FUNCS(chsize mmap)
|
||||
AC_REPLACE_FUNCS(pread ftruncate ffsll)
|
||||
|
||||
AC_CACHE_CHECK([mremap with MREMAP_MAYMOVE], [gold_cv_lib_mremap_maymove],
|
||||
[AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#include <sys/mman.h>
|
||||
void f() { mremap (0, 0, 0, MREMAP_MAYMOVE); }
|
||||
]])], [gold_cv_lib_mremap_maymove=yes], [gold_cv_lib_mremap_maymove=no])])
|
||||
if test "$gold_cv_lib_mremap_maymove" = "yes"; then
|
||||
AC_DEFINE(HAVE_MREMAP, 1,
|
||||
[Define to 1 if you have the mremap function with MREMAP_MAYMOVE support])
|
||||
else
|
||||
AC_LIBOBJ(mremap)
|
||||
fi
|
||||
|
||||
# Link in zlib if we can. This allows us to write compressed sections.
|
||||
AC_SEARCH_LIBS(zlibVersion, z, [AC_CHECK_HEADERS(zlib.h)])
|
||||
|
|
|
@ -27,7 +27,10 @@
|
|||
#include <climits>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_READV
|
||||
#include <sys/uio.h>
|
||||
|
@ -46,6 +49,40 @@
|
|||
#include "gold-threads.h"
|
||||
#include "fileread.h"
|
||||
|
||||
// For systems without mmap support.
|
||||
#ifndef HAVE_MMAP
|
||||
# define mmap gold_mmap
|
||||
# define munmap gold_munmap
|
||||
# ifndef MAP_FAILED
|
||||
# define MAP_FAILED (reinterpret_cast<void*>(-1))
|
||||
# endif
|
||||
# ifndef PROT_READ
|
||||
# define PROT_READ 0
|
||||
# endif
|
||||
# ifndef MAP_PRIVATE
|
||||
# define MAP_PRIVATE 0
|
||||
# endif
|
||||
|
||||
# ifndef ENOSYS
|
||||
# define ENOSYS EINVAL
|
||||
# endif
|
||||
|
||||
static void *
|
||||
gold_mmap(void *, size_t, int, int, int, off_t)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
static int
|
||||
gold_munmap(void *, size_t)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_READV
|
||||
struct iovec { void* iov_base; size_t iov_len; };
|
||||
ssize_t
|
||||
|
@ -96,7 +133,7 @@ File_read::View::~View()
|
|||
switch (this->data_ownership_)
|
||||
{
|
||||
case DATA_ALLOCATED_ARRAY:
|
||||
delete[] this->data_;
|
||||
free(const_cast<unsigned char*>(this->data_));
|
||||
break;
|
||||
case DATA_MMAPPED:
|
||||
if (::munmap(const_cast<unsigned char*>(this->data_), this->size_) != 0)
|
||||
|
@ -440,34 +477,40 @@ File_read::make_view(off_t start, section_size_type size,
|
|||
gold_assert(psize >= size);
|
||||
}
|
||||
|
||||
File_read::View* v;
|
||||
void* p;
|
||||
View::Data_ownership ownership;
|
||||
if (byteshift != 0)
|
||||
{
|
||||
unsigned char* p = new unsigned char[psize + byteshift];
|
||||
p = malloc(psize + byteshift);
|
||||
if (p == NULL)
|
||||
gold_nomem();
|
||||
memset(p, 0, byteshift);
|
||||
this->do_read(poff, psize, p + byteshift);
|
||||
v = new File_read::View(poff, psize, p, byteshift, cache,
|
||||
View::DATA_ALLOCATED_ARRAY);
|
||||
this->do_read(poff, psize, static_cast<unsigned char*>(p) + byteshift);
|
||||
ownership = View::DATA_ALLOCATED_ARRAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->reopen_descriptor();
|
||||
void* p = ::mmap(NULL, psize, PROT_READ, MAP_PRIVATE,
|
||||
this->descriptor_, poff);
|
||||
if (p == MAP_FAILED)
|
||||
gold_fatal(_("%s: mmap offset %lld size %lld failed: %s"),
|
||||
this->filename().c_str(),
|
||||
static_cast<long long>(poff),
|
||||
static_cast<long long>(psize),
|
||||
strerror(errno));
|
||||
|
||||
this->mapped_bytes_ += psize;
|
||||
|
||||
const unsigned char* pbytes = static_cast<const unsigned char*>(p);
|
||||
v = new File_read::View(poff, psize, pbytes, 0, cache,
|
||||
View::DATA_MMAPPED);
|
||||
p = ::mmap(NULL, psize, PROT_READ, MAP_PRIVATE, this->descriptor_, poff);
|
||||
if (p != MAP_FAILED)
|
||||
{
|
||||
ownership = View::DATA_MMAPPED;
|
||||
this->mapped_bytes_ += psize;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = malloc(psize);
|
||||
if (p == NULL)
|
||||
gold_nomem();
|
||||
this->do_read(poff, psize, p);
|
||||
ownership = View::DATA_ALLOCATED_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned char* pbytes = static_cast<const unsigned char*>(p);
|
||||
File_read::View* v = new File_read::View(poff, psize, pbytes, byteshift,
|
||||
cache, ownership);
|
||||
|
||||
this->add_view(v);
|
||||
|
||||
return v;
|
||||
|
@ -525,7 +568,10 @@ File_read::find_or_make_view(off_t offset, off_t start,
|
|||
{
|
||||
gold_assert(aligned);
|
||||
|
||||
unsigned char* pbytes = new unsigned char[v->size() + byteshift];
|
||||
unsigned char* pbytes;
|
||||
pbytes = static_cast<unsigned char*>(malloc(v->size() + byteshift));
|
||||
if (pbytes == NULL)
|
||||
gold_nomem();
|
||||
memset(pbytes, 0, byteshift);
|
||||
memcpy(pbytes + byteshift, v->data() + v->byteshift(), v->size());
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// gold.h -- general definitions for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
|
@ -135,11 +135,6 @@ extern "C" ssize_t pread(int, void*, size_t, off_t);
|
|||
extern "C" int ftruncate(int, off_t);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MREMAP
|
||||
#define MREMAP_MAYMOVE 1
|
||||
extern "C" void *mremap(void *, size_t, size_t, int, ...);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FFSLL
|
||||
extern "C" int ffsll(long long);
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* mremap.c -- version of mremap for gold. */
|
||||
|
||||
/* Copyright 2009 Free Software Foundation, Inc.
|
||||
/* Copyright 2009, 2011 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
This file is part of gold.
|
||||
|
@ -23,9 +23,17 @@
|
|||
#include "config.h"
|
||||
#include "ansidecl.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
extern void *gold_mremap (void *, size_t, size_t, int);
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
|
||||
/* This file implements mremap for systems which don't have it. The
|
||||
gold code requires support for mmap. However, there are systems
|
||||
|
@ -40,11 +48,9 @@
|
|||
# define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
extern void *mremap (void *, size_t, size_t, int, ...);
|
||||
|
||||
void *
|
||||
mremap (void *old_address, size_t old_size, size_t new_size,
|
||||
int flags ATTRIBUTE_UNUSED, ...)
|
||||
gold_mremap (void *old_address, size_t old_size, size_t new_size,
|
||||
int flags ATTRIBUTE_UNUSED)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
|
@ -57,3 +63,25 @@ mremap (void *old_address, size_t old_size, size_t new_size,
|
|||
(void) munmap (old_address, old_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* !defined(HAVE_MMAP) */
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
#endif
|
||||
|
||||
#ifndef ENOSYS
|
||||
#define ENOSYS EINVAL
|
||||
#endif
|
||||
|
||||
void *
|
||||
gold_mremap (void *old_address ATTRIBUTE_UNUSED,
|
||||
size_t old_size ATTRIBUTE_UNUSED,
|
||||
size_t new_size ATTRIBUTE_UNUSED,
|
||||
int flags ATTRIBUTE_UNUSED)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
#endif /* !defined(HAVE_MMAP) */
|
||||
|
|
116
gold/output.cc
116
gold/output.cc
|
@ -1,6 +1,6 @@
|
|||
// output.cc -- manage the output file for gold
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
|
@ -27,9 +27,13 @@
|
|||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "libiberty.h"
|
||||
|
||||
#include "parameters.h"
|
||||
|
@ -40,11 +44,71 @@
|
|||
#include "descriptors.h"
|
||||
#include "output.h"
|
||||
|
||||
// For systems without mmap support.
|
||||
#ifndef HAVE_MMAP
|
||||
# define mmap gold_mmap
|
||||
# define munmap gold_munmap
|
||||
# define mremap gold_mremap
|
||||
# ifndef MAP_FAILED
|
||||
# define MAP_FAILED (reinterpret_cast<void*>(-1))
|
||||
# endif
|
||||
# ifndef PROT_READ
|
||||
# define PROT_READ 0
|
||||
# endif
|
||||
# ifndef PROT_WRITE
|
||||
# define PROT_WRITE 0
|
||||
# endif
|
||||
# ifndef MAP_PRIVATE
|
||||
# define MAP_PRIVATE 0
|
||||
# endif
|
||||
# ifndef MAP_ANONYMOUS
|
||||
# define MAP_ANONYMOUS 0
|
||||
# endif
|
||||
# ifndef MAP_SHARED
|
||||
# define MAP_SHARED 0
|
||||
# endif
|
||||
|
||||
# ifndef ENOSYS
|
||||
# define ENOSYS EINVAL
|
||||
# endif
|
||||
|
||||
static void *
|
||||
gold_mmap(void *, size_t, int, int, int, off_t)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
static int
|
||||
gold_munmap(void *, size_t)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void *
|
||||
gold_mremap(void *, size_t, size_t, int)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MMAP) && !defined(HAVE_MREMAP)
|
||||
# define mremap gold_mremap
|
||||
extern "C" void *gold_mremap(void *, size_t, size_t, int);
|
||||
#endif
|
||||
|
||||
// Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS
|
||||
#ifndef MAP_ANONYMOUS
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
#ifndef MREMAP_MAYMOVE
|
||||
# define MREMAP_MAYMOVE 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_POSIX_FALLOCATE
|
||||
// A dummy, non general, version of posix_fallocate. Here we just set
|
||||
// the file size and hope that there is enough disk space. FIXME: We
|
||||
|
@ -4415,6 +4479,7 @@ Output_file::Output_file(const char* name)
|
|||
file_size_(0),
|
||||
base_(NULL),
|
||||
map_is_anonymous_(false),
|
||||
map_is_allocated_(false),
|
||||
is_temporary_(false)
|
||||
{
|
||||
}
|
||||
|
@ -4522,10 +4587,23 @@ Output_file::resize(off_t file_size)
|
|||
// to unmap to flush to the file, then remap after growing the file.
|
||||
if (this->map_is_anonymous_)
|
||||
{
|
||||
void* base = ::mremap(this->base_, this->file_size_, file_size,
|
||||
MREMAP_MAYMOVE);
|
||||
if (base == MAP_FAILED)
|
||||
gold_fatal(_("%s: mremap: %s"), this->name_, strerror(errno));
|
||||
void* base;
|
||||
if (!this->map_is_allocated_)
|
||||
{
|
||||
base = ::mremap(this->base_, this->file_size_, file_size,
|
||||
MREMAP_MAYMOVE);
|
||||
if (base == MAP_FAILED)
|
||||
gold_fatal(_("%s: mremap: %s"), this->name_, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
base = realloc(this->base_, file_size);
|
||||
if (base == NULL)
|
||||
gold_nomem();
|
||||
if (file_size > this->file_size_)
|
||||
memset(static_cast<char*>(base) + this->file_size_, 0,
|
||||
file_size - this->file_size_);
|
||||
}
|
||||
this->base_ = static_cast<unsigned char*>(base);
|
||||
this->file_size_ = file_size;
|
||||
}
|
||||
|
@ -4546,13 +4624,17 @@ Output_file::map_anonymous()
|
|||
{
|
||||
void* base = ::mmap(NULL, this->file_size_, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (base != MAP_FAILED)
|
||||
if (base == MAP_FAILED)
|
||||
{
|
||||
this->map_is_anonymous_ = true;
|
||||
this->base_ = static_cast<unsigned char*>(base);
|
||||
return true;
|
||||
base = malloc(this->file_size_);
|
||||
if (base == NULL)
|
||||
return false;
|
||||
memset(base, 0, this->file_size_);
|
||||
this->map_is_allocated_ = true;
|
||||
}
|
||||
return false;
|
||||
this->base_ = static_cast<unsigned char*>(base);
|
||||
this->map_is_anonymous_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Map the file into memory. Return whether the mapping succeeded.
|
||||
|
@ -4624,8 +4706,16 @@ Output_file::map()
|
|||
void
|
||||
Output_file::unmap()
|
||||
{
|
||||
if (::munmap(this->base_, this->file_size_) < 0)
|
||||
gold_error(_("%s: munmap: %s"), this->name_, strerror(errno));
|
||||
if (this->map_is_anonymous_)
|
||||
{
|
||||
// We've already written out the data, so there is no reason to
|
||||
// waste time unmapping or freeing the memory.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (::munmap(this->base_, this->file_size_) < 0)
|
||||
gold_error(_("%s: munmap: %s"), this->name_, strerror(errno));
|
||||
}
|
||||
this->base_ = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// output.h -- manage the output file for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
|
@ -4221,6 +4221,8 @@ class Output_file
|
|||
unsigned char* base_;
|
||||
// True iff base_ points to a memory buffer rather than an output file.
|
||||
bool map_is_anonymous_;
|
||||
// True if base_ was allocated using new rather than mmap.
|
||||
bool map_is_allocated_;
|
||||
// True if this is a temporary file which should not be output.
|
||||
bool is_temporary_;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue