diff options
author | dannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-05 07:28:27 +0000 |
---|---|---|
committer | dannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-05 07:28:27 +0000 |
commit | 62b4d90e930cf306be641282558f65fec69f3754 (patch) | |
tree | 546ccfa4f253ff907aa47680a32cadae4b2a9bc1 /gcc/config/i386/host-mingw32.c | |
parent | 3cdc65fb5d7b881e06e1995e6a3f6020245febba (diff) | |
download | gcc-62b4d90e930cf306be641282558f65fec69f3754.tar.gz |
* toplev.c (init_asm_output): Add explicit 'b' to mode when
opening asm_out_file.
* c-pch.c (c_common_write_pch): Remove unnecessary fflush before
reading asm_out_file. Replace fflush after reading asm_out_file
with fseek.
* hosthooks-def.h (HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY): Define
default and add to HOST_HOOKS_INITIALIZER.
* hosthooks.h (gt_pch_alloc_granularity): Declare hook function.
* ggc-common.c (default_gt_pch_alloc_granularity): New function.
(gt_pch_save): Use host_hooks.gt_pch_alloc_granularity
to set mmi.offset padding.
* config.gcc (i[34567]86-*-mingw32*): Set target_gtfiles to
$(srcdir)/config/i386/winnt.c.
(i[34567]86-*-pe | i[34567]86-*-cygwin*): Likewise.
(i[34567]86-*-uwin*): Likewise.
*i[34567]86-*-interix3*): Likewise.
* config.host (i[34567]86-*-mingw32*): Set out_host_hook_obj.
* config/i386/host-mingw32.c: New file.
* config/i386/x-mingw32: Add rule for host-mingw32.o.
* config/i386/winnt.c: (struct extern_list) Tag as GTY.
(extern_head): Likewise.
(struct export_list) Likewise.
(export_head): Likewise.
(i386_pe_record_external_function): Use ggc_alloc.
(i386_pe_record_exported_symbol): Likewise.
Include "gt-winnt.h" at end.
* doc/hostconfig.texi: Document
HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82643 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386/host-mingw32.c')
-rw-r--r-- | gcc/config/i386/host-mingw32.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/gcc/config/i386/host-mingw32.c b/gcc/config/i386/host-mingw32.c new file mode 100644 index 00000000000..0e3fdd7caf1 --- /dev/null +++ b/gcc/config/i386/host-mingw32.c @@ -0,0 +1,148 @@ +/* mingw32 host-specific hook definitions. + Copyright (C) 2004 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "hosthooks.h" +#include "hosthooks-def.h" +#include "toplev.h" +#include "diagnostic.h" + + +#define WIN32_LEAN_AND_MEAN /* Not so important if we have windows.h.gch. */ +#include <windows.h> + +static void * mingw32_gt_pch_get_address (size_t, int); +static int mingw32_gt_pch_use_address (void *, size_t, int, size_t); +static size_t mingw32_gt_pch_alloc_granularity (void); + +#undef HOST_HOOKS_GT_PCH_GET_ADDRESS +#define HOST_HOOKS_GT_PCH_GET_ADDRESS mingw32_gt_pch_get_address +#undef HOST_HOOKS_GT_PCH_USE_ADDRESS +#define HOST_HOOKS_GT_PCH_USE_ADDRESS mingw32_gt_pch_use_address +#undef HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY +#define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY mingw32_gt_pch_alloc_granularity + +static inline void w32_error(const char*, const char*, int, const char*); + +/* FIXME: Is this big enough? */ +static const size_t pch_VA_max_size = 128 * 1024 * 1024; + +/* Granularity for reserving address space. */ +static const size_t va_granularity = 0x10000; + +/* Print out the GetLastError() translation. */ +static inline void +w32_error (const char* function, const char* file, int line, + const char* my_msg) +{ + LPSTR w32_msgbuf; + FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS + | FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &w32_msgbuf, 0, NULL); + fprintf(stderr, "internal error in %s, at %s:%d: %s: %s\n", + function, trim_filename (file), line, my_msg, w32_msgbuf); + LocalFree ((HLOCAL)w32_msgbuf); +} + +/* Granularity for reserving address space. */ +static size_t mingw32_gt_pch_alloc_granularity (void) +{ + return va_granularity; +} + +/* Identify an address that's likely to be free in a subsequent invocation + of the compiler. The area should be able to hold SIZE bytes. FD is an + open file descriptor if the host would like to probe with mmap. */ + +static void * +mingw32_gt_pch_get_address (size_t size, int fd ATTRIBUTE_UNUSED) +{ + void* res; + size = (size + va_granularity - 1) & ~(va_granularity - 1); + if (size > pch_VA_max_size) + return NULL; + + /* FIXME: We let system determine base by setting first arg to NULL. + Allocating at top of available address space avoids unnecessary + fragmentation of "ordinary" (malloc's) address space but may not be safe + with delayed load of system dll's. Preferred addresses for NT system + dlls is in 0x70000000 to 0x78000000 range. + If we allocate at bottom we need to reserve the address as early as possible + and at the same point in each invocation. */ + + res = VirtualAlloc (NULL, pch_VA_max_size, + MEM_RESERVE | MEM_TOP_DOWN, + PAGE_NOACCESS); + if (!res) + w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc"); + else + /* We do not need the address space for now, so free it. */ + VirtualFree (res, 0, MEM_RELEASE); + + return res; +} + +/* ADDR is an address returned by gt_pch_get_address. Attempt to allocate + SIZE bytes at the same address and load it with the data from FD at + OFFSET. Return -1 if we couldn't allocate memory at ADDR, return 0 + if the memory is allocated but the data not loaded, return 1 if done. */ + +static int +mingw32_gt_pch_use_address (void *addr, size_t size, int fd, + size_t offset) +{ + void * mmap_addr; + static HANDLE mmap_handle; + + if (size == 0) + return 0; + + /* Offset must be also be a multiple of allocation granularity for + this to work. We can't change the offset. */ + if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size) + return -1; + + mmap_handle = CreateFileMapping ((HANDLE) _get_osfhandle (fd), + NULL, PAGE_WRITECOPY | SEC_COMMIT, + 0, 0, NULL); + if (mmap_handle == NULL) + { + w32_error (__FUNCTION__, __FILE__, __LINE__, "CreateFileMapping"); + return -1; + } + mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset, + size, addr); + if (mmap_addr != addr) + { + w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx"); + CloseHandle(mmap_handle); + return -1; + } + + return 1; +} + +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; |