+2001-12-25 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Autogenerate some header files which provide magic
+ numbers. Force dependencies for files which depend on autogenerated
+ headers to ensure that they are always built.
+ * child_info.h (child_info): Add new fields to accommodate new magic
+ number header stuff.
+ * dcrt0.cc: Rely on "child_info_magic.h" to ensure that correct
+ child_info magic numbers are used.
+ (dll_crt0_1): Temporarily remove _cygwin_testing_magic test.
+ (_dll_crt0): Do more testing on magic numbers from fork_info structure.
+ Call "multiple_cygwin_problem" where appropriate.
+ (multiple_cygwin_problem): Rename from multiple_cygwin_die. Issue a
+ warning or die, as appropriate based on cygwin version/magic number
+ mismatch.
+ * pinfo.cc (pinfo::exit): Don't attempt to dereference `this' if it
+ doesn't exist. This can happen when a fatal error occurs early in
+ process initialization.
+ * shared.cc: Rely on "shared_info_magic.h" to accommodate that new
+ magic number header stuff.
+ (shared_info::initialize): Use new magic number stuff, for shared
+ region.
+ (memory_init): Ditto, for mount table.
+ * shared_info.h: Accomodate new magic number stuff for shared region
+ and mount table.
+ * sigproc.cc: Rely on "child_info_magic.h" to accommodate new magic
+ number header stuff.
+ (init_child_info): Initialize new fields in child_info) to accomodate
+ magic numbers.
+ * winsup.h: Rename multiple_cygwin_die to multiple_cygwin_problem.
+ * include/cygwin/version.h: Define macros for manipulating version
+ magic.
+ * cygmagic: New shell script for generating magic numbers.
+
2001-12-20 Christopher Faylor <cgf@redhat.com>
* include/cygwin/version.h: Bump API minor version for below changes.
# FIXME: Which is it, CC or CC_FOR_TARGET?
CC_FOR_TARGET:=$(CC)
CFLAGS:=@CFLAGS@
-CFLAGS+=-MD -fbuiltin
+CFLAGS+=-MMD -fbuiltin
CXX:=@CXX@
CXXFLAGS:=@CXXFLAGS@
version.cc winver.o: winver_stamp
@ :
+shared_info_magic.h: cygmagic shared_info.h
+ /bin/sh ${word 1,$^} $@ $(CC) ${word 2,$^} MOUNT_MAGIC 'class mount_info' SHARED_MAGIC 'class shared_info'
+
+child_info_magic.h: cygmagic child_info.h
+ /bin/sh ${word 1,$^} $@ $(CC) ${word 2,$^} CHILD_INFO_MAGIC 'class child_info'
+
+dcrt0.o sigproc.o: child_info_magic.h
+
+shared.o: shared_info_magic.h
+
winver_stamp: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES)
@echo "Making version.o and winver.o";\
$(SHELL) ${word 1,$^} ${word 2,$^} ${word 3,$^} $(WINDRES) && \
$(w32api_lib)/libshell32.a $(w32api_lib)/libkernel32.a
$(CC) -nodefaultlibs -o $@ $^
-#\f
-
Makefile: cygwin.din
$(DEF_FILE): cygwin.din config.status
enum
{
- PROC_MAGIC = 0xaf12f000,
- _PROC_EXEC = PROC_MAGIC + 2,
- _PROC_SPAWN = PROC_MAGIC + 3,
- _PROC_FORK = PROC_MAGIC + 4, // Newer versions provide stack
- // location information
+ _PROC_EXEC,
+ _PROC_SPAWN,
+ _PROC_FORK
};
-#define PROC_MAGIC_MASK 0xff00f000
-#define PROC_MAGIC_GENERIC 0xaf00f000
-#define PROC_MAGIC_VER_MASK 0x0ff0000
+#define OPROC_MAGIC_MASK 0xff00ff00
+#define OPROC_MAGIC_GENERIC 0xaf00f000
-#define PROC_EXEC (_PROC_EXEC + _cygwin_testing_magic)
-#define PROC_SPAWN (_PROC_SPAWN + _cygwin_testing_magic)
-#define PROC_FORK (_PROC_FORK + _cygwin_testing_magic)
+#define PROC_MAGIC_GENERIC 0xaf00fa00
+
+#define PROC_EXEC (_PROC_EXEC)
+#define PROC_SPAWN (_PROC_SPAWN)
+#define PROC_FORK (_PROC_FORK)
#define EXEC_MAGIC_SIZE sizeof(child_info)
+
+#define CURR_CHILD_INFO_MAGIC 0xba17
+
class child_info
{
public:
DWORD zero[4]; // must be zeroed
DWORD cb; // size of this record
- DWORD type; // type of record
+ DWORD intro; // improbable string
+ unsigned short magic; // magic number unique to child_info
+ unsigned short type; // type of record, exec, spawn, fork
int cygpid; // cygwin pid of child process
HANDLE subproc_ready; // used for synchronization with parent
HANDLE mount_h;
--- /dev/null
+#!/bin/sh
+file_magic=$1; shift
+gcc=$1; shift
+file=$1; shift
+trap "rm -f /tmp/$$.magic" 0 1 2 15
+cat <<EOF > $file_magic
+/* autogenerated - do not edit */
+#include "$file"
+EOF
+while [ -n "$1" ]; do
+ define=$1; shift
+ struct=$1; shift
+ sum=`$gcc -E $file | sed -n "/^$struct/,/^};/p" | sed -e 's/[ ]//g' -e '/^$/d' | sum | awk '{print "obase=16;\"0x\";", $1}' | bc | tr '[A-Z]' '[a-z]'`
+ echo "#define $define $sum"
+ curr=`sed -n "s/^#[ ]*define CURR_$define[ ][ ]*\([^ ][^ ]*\)/\1/p" $file`
+ [ "$curr" == "$sum" ] || echo "*** WARNING WARNING WARNING WARNING WARNING ***
+*** $file: magic number changed old $curr != new $sum
+*** WARNING WARNING WARNING WARNING WARNING ***" 1>&2
+done >> $file_magic
+exit 0
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
-#include "child_info.h"
+#include "child_info_magic.h"
#include "perthread.h"
#include "shared_info.h"
#include "cygwin_version.h"
if (child_proc_info)
{
- switch (child_proc_info->type - _cygwin_testing_magic)
+ switch (child_proc_info->type)
{
case _PROC_FORK:
cygheap_fixup_in_child (child_proc_info, 0);
if (si.cbReserved2 >= EXEC_MAGIC_SIZE &&
memcmp (fork_info->zero, zeros, sizeof (zeros)) == 0)
{
- switch (fork_info->type - _cygwin_testing_magic)
+ if ((fork_info->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
+ multiple_cygwin_problem ("proc", fork_info->intro, 0);
+ else if (fork_info->intro == PROC_MAGIC_GENERIC
+ && fork_info->magic != CHILD_INFO_MAGIC)
+ multiple_cygwin_problem ("proc", fork_info->magic, CHILD_INFO_MAGIC);
+ switch (fork_info->type)
{
case _PROC_FORK:
user_data->forkee = fork_info->cygpid;
break;
}
default:
- if (_cygwin_testing)
- fork_info = NULL;
- else if ((fork_info->type & PROC_MAGIC_MASK) == PROC_MAGIC_GENERIC)
- multiple_cygwin_die ();
+ system_printf ("unknown exec type %d", fork_info->type);
+ fork_info = NULL;
break;
}
}
}
void
-multiple_cygwin_die ()
+multiple_cygwin_problem (const char *what, unsigned magic_version, unsigned version)
{
- api_fatal ("\
+ if (CYGWIN_VERSION_MAGIC_VERSION (magic_version) != version)
+ api_fatal ("%s version mismatch detected - %p/%p.\n\
You have multiple copies of cygwin1.dll on your system.\n\
Search for cygwin1.dll using the Windows Start->Find/Search facility\n\
-and delete all but the most recent version. This will probably be\n\
-the one that resides in x:\\cygwin\\bin, where 'x' is the drive on which\n\
-you have installed the cygwin distribution.\n");
+and delete all but the most recent version. The most recent version *should*\n\
+reside in x:\\cygwin\\bin, where 'x' is the drive on which you have\n\
+installed the cygwin distribution.", what, magic_version, version);
+
+ char buf[1024];
+ if (!GetEnvironmentVariable ("CYGWIN_MISMATCH_OK", buf, sizeof (buf)))
+ system_printf ("%s magic number mismatch detected - %p/%p", what, magic_version, version);
}
#ifdef DEBUGGING
48: Export "posix" regex functions
*/
+ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
+
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 48
cygwin_internal (CW_GETVERSIONINFO).
*/
+#define CYGWIN_VERSION_MAGIC(a, b) ((unsigned) (((unsigned short) a) | (unsigned short) b))
+#define CYGWIN_VERSION_MAGIC_VERSION(a) ((unsigned) ((unsigned)a & 0xffff))
void
_pinfo::exit (UINT n, bool norecord)
{
- if (!norecord)
- process_state = PID_EXITED;
-
- /* FIXME: There is a potential race between an execed process and its
- parent here. I hated to add a mutex just for this, though. */
- struct rusage r;
- fill_rusage (&r, hMainProc);
- add_rusage (&rusage_self, &r);
+ if (this)
+ {
+ if (!norecord)
+ process_state = PID_EXITED;
+
+ /* FIXME: There is a potential race between an execed process and its
+ parent here. I hated to add a mutex just for this, though. */
+ struct rusage r;
+ fill_rusage (&r, hMainProc);
+ add_rusage (&rusage_self, &r);
+ }
sigproc_printf ("Calling ExitProcess %d", n);
ExitProcess (n);
#include "cygerrno.h"
#include "cygheap.h"
#include "heap.h"
-#include "shared_info.h"
+#include "shared_info_magic.h"
#include "registry.h"
#include "cygwin_version.h"
-#define SHAREDVER (unsigned)(cygwin_version.api_major << 16 | \
- cygwin_version.api_minor)
-
shared_info NO_COPY *cygwin_shared = NULL;
mount_info NO_COPY *mount_table = NULL;
HANDLE cygwin_mount_h;
{
if (inited)
{
- if (inited != SHAREDVER)
- multiple_cygwin_die ();
+ if (inited != SHARED_VERSION_MAGIC)
+ multiple_cygwin_problem ("shared", inited, SHARED_VERSION);
return;
}
/* Initialize tty table. */
tty.init ();
- inited = SHAREDVER;
+ inited = SHARED_VERSION_MAGIC;
}
void __stdcall
/* Initialize the Cygwin per-user mount table, if necessary */
if (!mount_table->version)
{
- mount_table->version = MOUNT_VERSION;
+ mount_table->version = MOUNT_VERSION_MAGIC;
debug_printf ("initializing mount table");
mount_table->init (); /* Initialize the mount table. */
}
- else if (mount_table->version != MOUNT_VERSION)
- multiple_cygwin_die ();
+ else if (mount_table->version != MOUNT_VERSION_MAGIC)
+ multiple_cygwin_problem ("mount", mount_table->version, MOUNT_VERSION);
}
scheme should be satisfactory for a long while yet. */
#define MAX_MOUNTS 30
-#define MOUNT_VERSION 27 // increment when mount table changes
+#define MOUNT_VERSION 27 // increment when mount table changes and
+#define MOUNT_VERSION_MAGIC CYGWIN_VERSION_MAGIC (MOUNT_MAGIC, MOUNT_VERSION)
+#define CURR_MOUNT_MAGIC 0xfe35
class reg_key;
class mount_info
/******** Shared Info ********/
/* Data accessible to all tasks */
+#define SHARED_VERSION (unsigned)(cygwin_version.api_major << 8 | \
+ cygwin_version.api_minor)
+#define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION)
+
+#define CURR_SHARED_MAGIC 0x6f6e
+
class shared_info
{
DWORD inited;
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
-#include "child_info.h"
+#include "child_info_magic.h"
#define NEED_VFORK
#include "perthread.h"
#include <assert.h>
{
memset (ch, 0, sizeof *ch);
ch->cb = sizeof *ch;
+ ch->intro = PROC_MAGIC_GENERIC;
+ ch->magic = CHILD_INFO_MAGIC;
ch->type = chtype;
ch->cygpid = pid;
ch->subproc_ready = subproc_ready;
extern "C" void __api_fatal (const char *, ...) __attribute__ ((noreturn));
extern "C" int __small_sprintf (char *dst, const char *fmt, ...) /*__attribute__ ((regparm (2)))*/;
extern "C" int __small_vsprintf (char *dst, const char *fmt, va_list ap) /*__attribute__ ((regparm (3)))*/;
-extern void multiple_cygwin_die () __attribute__ ((noreturn));
+extern void multiple_cygwin_problem (const char *, unsigned, unsigned);
extern "C" void __malloc_lock (struct _reent *);
extern "C" void __malloc_unlock (struct _reent *);