+2004-06-05 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * 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.
+
2004-06-04 Bernardo Innocenti <bernie@develer.com>
* config/m68k/m68k.h: Remove comments copied over from tm.texi.
fatal_error ("can't write %s: %m", pch_file);
buf = xmalloc (16384);
- fflush (asm_out_file);
if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
fatal_error ("can't seek in %s: %m", asm_file_name);
written += size;
}
free (buf);
- /* asm_out_file can be written afterwards, so must be flushed first. */
- fflush (asm_out_file);
+ /* asm_out_file can be written afterwards, so fseek to clear
+ _IOREAD flag. */
+ if (fseek (asm_out_file, 0, SEEK_END) != 0)
+ fatal_error ("can't seek in %s: %m", asm_file_name);
gt_pch_save (pch_outfile);
cpp_write_pch_state (parse_in, pch_outfile);
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/cygwin.h"
xm_file=i386/xm-cygwin.h
tmake_file="i386/t-cygwin i386/t-cygming"
+ target_gtfiles="\$(srcdir)/config/i386/winnt.c"
extra_objs=winnt.o
c_target_objs=cygwin2.o
cxx_target_objs=cygwin2.o
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h"
xm_file=i386/xm-mingw32.h
tmake_file="i386/t-cygming i386/t-mingw32"
+ target_gtfiles="\$(srcdir)/config/i386/winnt.c"
extra_objs=winnt.o
if test x$enable_threads = xyes; then
thread_file='win32'
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygwin.h i386/uwin.h"
tmake_file="i386/t-cygwin i386/t-uwin"
extra_objs=winnt.o
+ target_gtfiles="\$(srcdir)/config/i386/winnt.c"
if test x$enable_threads = xyes; then
thread_file='win32'
fi
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h i386/i386-interix3.h interix.h interix3.h"
tmake_file="i386/t-interix"
extra_objs=winnt.o
+ target_gtfiles="\$(srcdir)/config/i386/winnt.c"
if test x$enable_threads = xyes ; then
thread_file='posix'
fi
host_xmake_file=i386/x-mingw32
host_exeext=.exe
host_can_use_collect2=no
+ out_host_hook_obj=host-mingw32.o
;;
i[34567]86-*-uwin*)
echo "*** UWIN may not be used as a host platform because"
--- /dev/null
+/* 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;
/* Keep a list of external functions. */
-struct extern_list
+struct extern_list GTY(())
{
struct extern_list *next;
const char *name;
};
-static struct extern_list *extern_head;
+static GTY(()) struct extern_list *extern_head;
/* Assemble an external function reference. We need to keep a list of
these, so that we can output the function types at the end of the
{
struct extern_list *p;
- p = (struct extern_list *) xmalloc (sizeof *p);
+ p = (struct extern_list *) ggc_alloc (sizeof *p);
p->next = extern_head;
p->name = name;
extern_head = p;
/* Keep a list of exported symbols. */
-struct export_list
+struct export_list GTY(())
{
struct export_list *next;
const char *name;
int is_data; /* used to type tag exported symbols. */
};
-static struct export_list *export_head;
+static GTY(()) struct export_list *export_head;
/* Assemble an export symbol entry. We need to keep a list of
these, so that we can output the export list at the end of the
{
struct export_list *p;
- p = (struct export_list *) xmalloc (sizeof *p);
+ p = (struct export_list *) ggc_alloc (sizeof *p);
p->next = export_head;
p->name = name;
p->is_data = is_data;
}
}
}
+
+#include "gt-winnt.h"
# Make local_includedir relative to EXEC_PREFIX
#
local_includedir=$(libsubdir)/$(unlibsubdir)/..`echo $(exec_prefix) | sed -e 's|^$(prefix)||' -e 's|/[^/]*|/..|g'`/include
+
+host-mingw32.o : $(srcdir)/config/i386/host-mingw32.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/host-mingw32.c
and such a PCH file won't work.
@end deftypefn
+@deftypefn {Host Hook} size_t HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY (void);
+This host hook returns the alignment required for allocating virtual
+memory. Usually this is the same as getpagesize, but on some hosts the
+alignment for reserving memory differs from the pagesize for committing
+memory.
+@end deftypefn
+
@node Filesystem
@section Host Filesystem
@cindex configuration file
char *this_object = NULL;
size_t this_object_size = 0;
struct mmap_info mmi;
- size_t page_size = getpagesize();
+ const size_t mmap_offset_alignment = host_hooks.gt_pch_alloc_granularity();
gt_pch_save_stringpool ();
ggc_pch_prepare_write (state.d, state.f);
- /* Pad the PCH file so that the mmapped area starts on a page boundary. */
+ /* Pad the PCH file so that the mmapped area starts on an allocation
+ granularity (usually page) boundary. */
{
long o;
o = ftell (state.f) + sizeof (mmi);
if (o == -1)
fatal_error ("can't get position in PCH file: %m");
- mmi.offset = page_size - o % page_size;
- if (mmi.offset == page_size)
+ mmi.offset = mmap_offset_alignment - o % mmap_offset_alignment;
+ if (mmi.offset == mmap_offset_alignment)
mmi.offset = 0;
mmi.offset += o;
}
return (addr == base) - 1;
}
+/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS. Return the
+ alignment required for allocating virtual memory. Usually this is the
+ same as pagesize. */
+
+size_t
+default_gt_pch_alloc_granularity (void)
+{
+ return getpagesize();
+}
+
#if HAVE_MMAP_FILE
/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is present.
We temporarily allocate SIZE bytes, and let the kernel place the data
#define HOST_HOOKS_GT_PCH_USE_ADDRESS default_gt_pch_use_address
#endif
+#define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY \
+ default_gt_pch_alloc_granularity
+
extern void* default_gt_pch_get_address (size_t, int);
extern int default_gt_pch_use_address (void *, size_t, int, size_t);
+extern size_t default_gt_pch_alloc_granularity (void);
extern void* mmap_gt_pch_get_address (size_t, int);
extern int mmap_gt_pch_use_address (void *, size_t, int, size_t);
#define HOST_HOOKS_INITIALIZER { \
HOST_HOOKS_EXTRA_SIGNALS, \
HOST_HOOKS_GT_PCH_GET_ADDRESS, \
- HOST_HOOKS_GT_PCH_USE_ADDRESS \
+ HOST_HOOKS_GT_PCH_USE_ADDRESS, \
+ HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY \
}
#endif /* GCC_HOST_HOOKS_DEF_H */
if the memory is allocated but the data not loaded, return 1 if done. */
int (*gt_pch_use_address) (void *addr, size_t size, int fd, size_t offset);
+ /* Return the alignment required for allocating virtual memory. Usually
+ this is the same as pagesize. */
+ size_t (*gt_pch_alloc_granularity) (void);
+
/* Whenever you add entries here, make sure you adjust hosthooks-def.h. */
};
if (!strcmp (asm_file_name, "-"))
asm_out_file = stdout;
else
- asm_out_file = fopen (asm_file_name, "w+");
+ asm_out_file = fopen (asm_file_name, "w+b");
if (asm_out_file == 0)
fatal_error ("can't open %s for writing: %m", asm_file_name);
}