diff options
author | H. Peter Anvin <hpa@zytor.com> | 2017-02-23 18:39:00 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2017-02-23 18:39:00 -0800 |
commit | 9222364607599b2e64f817aebb47d078da2ed700 (patch) | |
tree | 57cd503bdd03269d14c78a4e4bb5ad3c9768b94e /nasmlib | |
parent | f7aae402dacef1bbabc974b721a50fb8ba9de634 (diff) | |
download | nasm-9222364607599b2e64f817aebb47d078da2ed700.tar.gz |
nasmlib/file: move memory-mapping functions out of file.c
Move memory-mapping functions from file.c into a separate mmap.c.
This will be cleaner especially once (if) we end up doing a Windows
implementation, which is likely to look entirely different.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'nasmlib')
-rw-r--r-- | nasmlib/file.c | 159 | ||||
-rw-r--r-- | nasmlib/file.h | 101 | ||||
-rw-r--r-- | nasmlib/mmap.c | 139 |
3 files changed, 241 insertions, 158 deletions
diff --git a/nasmlib/file.c b/nasmlib/file.c index 1f1e63bc..a6e7d565 100644 --- a/nasmlib/file.c +++ b/nasmlib/file.c @@ -31,69 +31,7 @@ * * ----------------------------------------------------------------------- */ -#include "compiler.h" -#include "nasmlib.h" - -#include <errno.h> - -#ifdef HAVE_FCNTL_H -# include <fcntl.h> -#endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef HAVE_IO_H -# include <io.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif -#ifdef HAVE_SYS_MMAN_H -# include <sys/mman.h> -#endif - -#if !defined(HAVE_FILENO) && defined(HAVE__FILENO) -# define HAVE_FILENO 1 -# define fileno _fileno -#endif - -#if !defined(HAVE_ACCESS) && defined(HAVE__ACCESS) -# define HAVE_ACCESS 1 -# define access _access -#endif -#ifndef R_OK -# define R_OK 4 /* Classic Unix constant, same on Windows */ -#endif - -/* Can we adjust the file size without actually writing all the bytes? */ -#ifdef HAVE_FILENO /* Useless without fileno() */ -# ifdef HAVE__CHSIZE_S -# define nasm_ftruncate(fd,size) _chsize_s(fd,size) -# elif defined(HAVE__CHSIZE) -# define nasm_ftruncate(fd,size) _chsize(fd,size) -# elif defined(HAVE_FTRUNCATE) -# define nasm_ftruncate(fd,size) ftruncate(fd,size) -# endif -#endif - -/* - * On Win32, stat has a 32-bit file size but _stati64 has a 64-bit file - * size. However, as "stat" is already a macro, don't confuse the situation - * further by redefining it, instead we create our own. - */ -#ifdef HAVE__STATI64 -# define nasm_stat _stati64 -#elif defined(HAVE_STAT) -# define nasm_stat stat -#endif - -#ifdef HAVE_FILENO -# ifdef HAVE__FSTATI64 -# define nasm_fstat _fstati64 -# elif defined(HAVE_FSTAT) -# define nasm_fstat fstat -# endif -#endif +#include "file.h" void nasm_write(const void *ptr, size_t size, FILE *f) { @@ -291,98 +229,3 @@ off_t nasm_file_size_by_path(const char *pathname) return len; #endif } - -/* - * System page size - * - * Not needed unless we have mmap(), and can cause compile failures, - * e.g. on MinGW32, so we #if around it. - */ -#if defined(HAVE_FILENO) && defined(HAVE_MMAP) - -/* File scope since not all compilers like static data in inline functions */ -static size_t nasm_pagemask; - -static size_t get_pagemask(void) -{ - size_t ps = 0; - -# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) - ps = sysconf(_SC_PAGESIZE); -# elif defined(HAVE_GETPAGESIZE) - ps = getpagesize(); -# endif - - nasm_pagemask = ps = is_power2(ps) ? (ps - 1) : 0; - return ps; -} - -static inline size_t pagemask(void) -{ - size_t pm = nasm_pagemask; - - if (unlikely(!pm)) - return get_pagemask(); - - return pm; -} - -#endif - -/* - * Try to map an input file into memory - */ -const void *nasm_map_file(FILE *fp, off_t start, off_t len) -{ -#if defined(HAVE_FILENO) && defined(HAVE_MMAP) - const char *p; - off_t astart; /* Aligned start */ - size_t salign; /* Amount of start adjustment */ - size_t alen; /* Aligned length */ - const size_t page_mask = pagemask(); - - if (unlikely(!page_mask)) - return NULL; /* Page size undefined? */ - - if (unlikely(!len)) - return NULL; /* Mapping nothing... */ - - if (unlikely(len != (off_t)(size_t)len)) - return NULL; /* Address space insufficient */ - - astart = start & ~(off_t)page_mask; - salign = start - astart; - alen = (len + salign + page_mask) & ~page_mask; - - p = mmap(NULL, alen, PROT_READ, MAP_SHARED, fileno(fp), astart); - return unlikely(p == MAP_FAILED) ? NULL : p + salign; -#else - /* XXX: add Windows support? */ - (void)fp; (void)start; (void)len; - return NULL; -#endif -} - -/* - * Unmap an input file - */ -void nasm_unmap_file(const void *p, size_t len) -{ -#if defined(HAVE_FILENO) && defined(HAVE_MMAP) - const size_t page_mask = pagemask(); - uintptr_t astart; - size_t salign; - size_t alen; - - if (unlikely(!page_mask)) - return; - - astart = (uintptr_t)p & ~(uintptr_t)page_mask; - salign = (uintptr_t)p - astart; - alen = (len + salign + page_mask) & ~page_mask; - - munmap((void *)astart, alen); -#else - (void)p; (void)len; -#endif -} diff --git a/nasmlib/file.h b/nasmlib/file.h new file mode 100644 index 00000000..85957938 --- /dev/null +++ b/nasmlib/file.h @@ -0,0 +1,101 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#ifndef NASMLIB_FILE_H +#define NASMLIB_FILE_H + +#include "compiler.h" +#include "nasmlib.h" + +#include <errno.h> + +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef HAVE_IO_H +# include <io.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif + +#if !defined(HAVE_FILENO) && defined(HAVE__FILENO) +# define HAVE_FILENO 1 +# define fileno _fileno +#endif + +#if !defined(HAVE_ACCESS) && defined(HAVE__ACCESS) +# define HAVE_ACCESS 1 +# define access _access +#endif +#ifndef R_OK +# define R_OK 4 /* Classic Unix constant, same on Windows */ +#endif + +/* Can we adjust the file size without actually writing all the bytes? */ +#ifdef HAVE_FILENO /* Useless without fileno() */ +# ifdef HAVE__CHSIZE_S +# define nasm_ftruncate(fd,size) _chsize_s(fd,size) +# elif defined(HAVE__CHSIZE) +# define nasm_ftruncate(fd,size) _chsize(fd,size) +# elif defined(HAVE_FTRUNCATE) +# define nasm_ftruncate(fd,size) ftruncate(fd,size) +# endif +#endif + +/* + * On Win32, stat has a 32-bit file size but _stati64 has a 64-bit file + * size. However, as "stat" is already a macro, don't confuse the situation + * further by redefining it, instead we create our own. + */ +#ifdef HAVE__STATI64 +# define nasm_stat _stati64 +#elif defined(HAVE_STAT) +# define nasm_stat stat +#endif + +#ifdef HAVE_FILENO +# ifdef HAVE__FSTATI64 +# define nasm_fstat _fstati64 +# elif defined(HAVE_FSTAT) +# define nasm_fstat fstat +# endif +#endif + +#endif /* NASMLIB_FILE_H */ diff --git a/nasmlib/mmap.c b/nasmlib/mmap.c new file mode 100644 index 00000000..5fc5646f --- /dev/null +++ b/nasmlib/mmap.c @@ -0,0 +1,139 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "file.h" + +/* ----------------------------------------------------------------------- * + * Unix-style memory mapping, using mmap(). + * ----------------------------------------------------------------------- */ +#if defined(HAVE_FILENO) && defined(HAVE_MMAP) + +/* + * System page size + */ + +/* File scope since not all compilers like static data in inline functions */ +static size_t nasm_pagemask; + +static size_t get_pagemask(void) +{ + size_t ps = 0; + +# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) + ps = sysconf(_SC_PAGESIZE); +# elif defined(HAVE_GETPAGESIZE) + ps = getpagesize(); +# elif defined(PAGE_SIZE) + ps = PAGE_SIZE; +# endif + + nasm_pagemask = ps = is_power2(ps) ? (ps - 1) : 0; + return ps; +} + +static inline size_t pagemask(void) +{ + size_t pm = nasm_pagemask; + + if (unlikely(!pm)) + return get_pagemask(); + + return pm; +} + +/* + * Try to map an input file into memory + */ +const void *nasm_map_file(FILE *fp, off_t start, off_t len) +{ + const char *p; + off_t astart; /* Aligned start */ + size_t salign; /* Amount of start adjustment */ + size_t alen; /* Aligned length */ + const size_t page_mask = pagemask(); + + if (unlikely(!page_mask)) + return NULL; /* Page size undefined? */ + + if (unlikely(!len)) + return NULL; /* Mapping nothing... */ + + if (unlikely(len != (off_t)(size_t)len)) + return NULL; /* Address space insufficient */ + + astart = start & ~(off_t)page_mask; + salign = start - astart; + alen = (len + salign + page_mask) & ~page_mask; + + p = mmap(NULL, alen, PROT_READ, MAP_SHARED, fileno(fp), astart); + return unlikely(p == MAP_FAILED) ? NULL : p + salign; +} + +/* + * Unmap an input file + */ +void nasm_unmap_file(const void *p, size_t len) +{ + const size_t page_mask = pagemask(); + uintptr_t astart; + size_t salign; + size_t alen; + + if (unlikely(!page_mask)) + return; + + astart = (uintptr_t)p & ~(uintptr_t)page_mask; + salign = (uintptr_t)p - astart; + alen = (len + salign + page_mask) & ~page_mask; + + munmap((void *)astart, alen); +} + +/* ----------------------------------------------------------------------- * + * No memory map support at all + * XXX: Add a section with Windows support + * ----------------------------------------------------------------------- */ +#else + +const void *nasm_map_file(FILE *fp, off_t start, off_t len) +{ + (void)fp; (void)start; (void)len; + return NULL; +} + +void nasm_unmap_file(const void *p, size_t len) +{ + (void)p; (void)len; +} + +#endif |