Hi Kevin,
Many thanks for working on this.
I've now reviewed your patch, and it looks OK.
Just a few notes:
You seen to miss two lines of code in the revert of crt1.c, so
I've played it safe, and used svn merge -r 824:345 crt1.c
to get the real original back.
Another thing is the ChangeLog entry. We are using the GNU style, so the idea
is to put the just enough to know what changed, and leave the 'why' descriptions
for the mailing lists. I've taken the liberty to tweak it a little,
but I didn't want to step in your toes, so I left most of your text unchanged.
(Just take a look to the existing entries in mingw/ChangeLog, not
ChangeLog.mingw32ce, to get a feeling.)
When we will submit our code up for upstream inclusion, we will be asked for
ChangeLogs in GNU style, so we better use it too from the beginning.
Attached is the committed patch.
Cheers,
Pedro Alves
2006-11-25 Kevin O'Connor <[EMAIL PROTECTED]>
* crt1_ce.c: New file. Implement WinMainCRTStartup for CE
programs in its own CE specific file.
* winmain_ce.c: New file. Implement a WinMain function that calls
main, for those CE programs that define main instead of WinMain.
* Makefile.in: Modify so that these two new CE specific files are
only built for mingw32ce.
* crt1.c, init.c, main.c: Revert them back to their x86 MinGW
originals.
Index: Makefile.in
===================================================================
--- Makefile.in (revision 785)
+++ Makefile.in (working copy)
@@ -167,13 +167,13 @@
endif
MINGW_OBJS = CRTglob.o CRTfmode.o CRTinit.o dllmain.o gccmain.o \
- main.o crtst.o mthr_stub.o \
+ crtst.o mthr_stub.o \
pseudo-reloc.o pseudo-reloc-list.o cpu_features.o
ifneq (,$(findstring wince,$(target_alias)))
-MINGW_OBJS += abort.o atexit.o assert.o
+MINGW_OBJS += winmain_ce.o abort.o atexit.o assert.o
else
-MINGW_OBJS += CRT_fp10.o txtmode.o
+MINGW_OBJS += main.o CRT_fp10.o txtmode.o
endif
MOLD_OBJS = isascii.o iscsym.o iscsymf.o toascii.o \
@@ -498,8 +498,13 @@
CRTfmode.o: CRTfmode.c
CRTglob.o: CRTglob.c
CRTinit.o: CRTinit.c
+ifneq (,$(findstring wince,$(target_alias)))
+crt1.o: crt1_ce.c
+crt2.o: crt1_ce.c
+else
crt1.o: crt1.c init.c
crt2.o: crt1.c init.c
+endif
crtmt.o: crtmt.c
crtst.o: crtst.c
ctype_old.o: ctype_old.c
@@ -507,6 +512,7 @@
dllcrt2.o: dllcrt1.c
dllmain.o: dllmain.c
main.o: main.c
+winmain_ce.o: winmain_ce.c
oldnames.o: oldnames.c
string_old.o: string_old.c
CRT_fp8.o: CRT_fp8.c
Index: init.c
===================================================================
--- init.c (revision 785)
+++ init.c (working copy)
@@ -35,10 +35,8 @@
int newmode;
} _startupinfo;
extern void __getmainargs (int *, char ***, char ***, int, _startupinfo *);
-#elif defined (__CRTDLL__)
+#else
extern void __GetMainArgs (int *, char ***, char ***, int);
-#elif defined (__COREDLL__)
-static void __GetMainArgs (int *, char ***, char ***, int);
#endif
/*
@@ -58,127 +56,12 @@
/*
* Microsoft's runtime provides a function for doing just that.
*/
-#if defined (__MSVCRT__)
+#ifdef __MSVCRT__
(void) __getmainargs (&_argc, &_argv, &dummy_environ, _CRT_glob,
&start_info);
#else
- /* CRTDLL/COREDLL version */
+ /* CRTDLL version */
(void) __GetMainArgs (&_argc, &_argv, &dummy_environ, _CRT_glob);
#endif
}
-#ifdef __COREDLL__
-
-static int
-_parse_tokens(char* string, char*** tokens, int length)
-{
- /* Extract whitespace- and quotes- delimited tokens from the given string
- and put them into the tokens array. Returns number of tokens
- extracted. Length specifies the current size of tokens[].
- THIS METHOD MODIFIES string. */
-
- const char* whitespace = " \t\r\n";
- char* tokenEnd;
- const char* quoteCharacters = "\"\'";
- char* end = string + strlen (string);
-
- if (string == NULL)
- return length;
-
- while (1)
- {
- const char* q;
- /* Skip over initial whitespace. */
- string += strspn(string, whitespace);
- if (*string == '\0')
- break;
-
- for (q = quoteCharacters; *q; ++q)
- {
- if (*string == *q)
- break;
- }
- if (*q)
- {
- /* Token is quoted. */
- char quote = *string++;
- tokenEnd = strchr(string, quote);
- /* If there is no endquote, the token is the rest of the string.
*/
- if (!tokenEnd)
- tokenEnd = end;
- }
- else
- {
- tokenEnd = string + strcspn(string, whitespace);
- }
-
- *tokenEnd = '\0';
-
- {
- char** new_tokens;
- int newlen = length + 1;
- new_tokens = realloc (*tokens, sizeof (char**) * newlen);
- if (!new_tokens)
- {
- /* Out of memory. */
- return -1;
- }
-
- *tokens = new_tokens;
- (*tokens)[length] = string;
- length = newlen;
- }
- if (tokenEnd == end)
- break;
- string = tokenEnd + 1;
- }
-exit:
- return length;
-}
-
-static void
-__GetMainArgs (int *argc, char ***argv, char *** env, int glob)
-{
- wchar_t cmdnameBufW[512];
- char buf[MAX_PATH];
- int cmdlineLen = 0;
- wchar_t* cmdlinePtrW;
- int modlen;
- char* __cmdlinebuf;
-
- /* argv[0] is the path of invoked program - get this from CE. */
- cmdnameBufW[0] = 0;
- modlen = GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof
(cmdnameBufW[0]));
- cmdlinePtrW = GetCommandLineW();
-
- if (!cmdlinePtrW)
- cmdlineLen = 0;
- else
- cmdlineLen = wcslen(cmdlinePtrW);
-
- __cmdlinebuf = malloc (modlen + 1 + cmdlineLen + 1);
- if (!__cmdlinebuf)
- ExitProcess(-1);
-
- *argv = malloc (sizeof (char**) * 1);
- if (!*argv)
- ExitProcess(-1);
-
- (*argv)[0] = __cmdlinebuf;
- wcstombs((*argv)[0], cmdnameBufW, wcslen(cmdnameBufW) + 1);
- /* Add one to account for argv[0] */
- (*argc)++;
-
- if (cmdlineLen > 0)
- {
- char* argv1 = (*argv)[0] + strlen((*argv)[0]) + 1;
- wcstombs(argv1, cmdlinePtrW, cmdlineLen + 1);
- *argc = _parse_tokens(argv1, argv, 1);
- if (*argc < 0)
- ExitProcess(-1);
- }
- (*argv)[*argc] = 0;
- return;
-}
-
-#endif
Index: crt1.c
===================================================================
--- crt1.c (revision 824)
+++ crt1.c (working copy)
@@ -14,17 +14,12 @@
#define __IN_MINGW_RUNTIME
#include <stdlib.h>
#include <stdio.h>
-#ifndef __COREDLL__
#include <io.h>
-#endif
#include <process.h>
#include <float.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-
-#ifndef __COREDLL__
#include <signal.h>
-#endif
/* NOTE: The code for initializing the _argv, _argc, and environ variables
* has been moved to a separate .c file which is included in both
@@ -36,14 +31,7 @@
extern void _pei386_runtime_relocator (void);
-#ifndef UNDER_CE
extern int main (int, char **, char **);
-#else
-/* No environ. */
-extern int main (int, char **);
-/* No atexit on coredll, we must initialize our private version. */
-BOOL __atexit_init(void);
-#endif
/*
* Must have the correct app type for MSVCRT.
@@ -56,8 +44,6 @@
__MINGW_IMPORT void __set_app_type(int);
#endif /* __MSVCRT__ */
-#ifndef __COREDLL__
-
/* Global _fmode for this .exe, not the one in msvcrt.dll,
The default is set in txtmode.o in libmingw32.a */
/* Override the dllimport'd declarations in stdlib.h */
@@ -66,6 +52,7 @@
#ifdef __MSVCRT__
extern int* __p__fmode(void); /* To access the dll _fmode */
#endif
+
/*
* Setup the default file handles to have the _CRT_fmode mode, as well as
* any new files created by the user.
@@ -102,16 +89,13 @@
}
/* Now sync the dll _fmode to the one for this .exe. */
-#if defined (__MSVCRT__)
+#ifdef __MSVCRT__
*__p__fmode() = _fmode;
-#elif defined (__CRTDLL__)
- *__IMP(_fmode_dll) = _fmode;
+#else
+ *_imp___fmode_dll = _fmode;
#endif
}
-#endif
-#ifndef UNDER_CE
-
/* This function will be called when a trap occurs. Thanks to Jacob
Navia for his contribution. */
static CALLBACK long
@@ -193,17 +177,14 @@
return action;
}
-#endif
-
/*
- * The function __mingw_CRTStartup is called from the entry point for all
programs.
+ * The function mainCRTStartup is the entry point for all console programs.
*/
static void __attribute__((noreturn))
__mingw_CRTStartup (void)
{
int nRet;
-#ifdef __i386__
/*
* Set up the top-level exception handler so that signal handling
* works as expected. The mapping between ANSI/POSIX signals and
@@ -211,10 +192,6 @@
*
*/
SetUnhandledExceptionFilter (_gnu_exception_handler);
-#elif defined (__arm__)
- /* Windows CE on RISC architectures uses table based seh.
- We could install a top-level handler using the same technique as cegcc.
*/
-#endif
/*
* Initialize floating point unit.
@@ -227,7 +204,6 @@
*/
_mingw32_init_mainargs ();
-#ifndef __COREDLL__
/*
* Sets the default file mode.
* If _CRT_fmode is set, also set mode for stdin, stdout
@@ -235,36 +211,21 @@
* NOTE: DLLs don't do this because that would be rude!
*/
_mingw32_init_fmode ();
-#endif
/* Adust references to dllimported data that have non-zero offsets. */
_pei386_runtime_relocator ();
-#ifdef __i386__
/* Align the stack to 16 bytes for the sake of SSE ops in main
or in functions inlined into main. */
asm __volatile__ ("andl $-16, %%esp" : : : "%esp");
-#endif
-#ifdef __COREDLL__
/*
- * Initialize the atexit table.
- */
- __atexit_init();
-#endif
-
- /*
* Call the main function. If the user does not supply one
* the one in the 'libmingw32.a' library will be linked in, and
* that one calls WinMain. See main.c in the 'lib' dir
* for more details.
*/
-#ifndef UNDER_CE
nRet = main (_argc, _argv, environ);
-#else
- /* Windows CE has no environ. */
- nRet = main (_argc, _argv);
-#endif
/*
* Perform exit processing for the C library. This means
@@ -275,7 +236,6 @@
ExitProcess (nRet);
}
-#ifndef UNDER_CE
/*
* The function mainCRTStartup is the entry point for all console programs.
*/
@@ -288,8 +248,6 @@
__mingw_CRTStartup ();
}
-#endif
-
/*
* For now the GUI startup function is the same as the console one.
* This simply gets rid of the annoying warning about not being able
@@ -304,24 +262,20 @@
__mingw_CRTStartup ();
}
-#ifndef UNDER_CE
-
/*
* We force use of library version of atexit, which is only
- * visible in import lib as __IMP(atexit)
+ * visible in import lib as _imp__atexit
*/
-extern int (*__IMP(atexit))(void (*)(void));
+extern int (*_imp__atexit)(void (*)(void));
int atexit (void (* pfn )(void) )
{
- return ( (*__IMP(atexit))(pfn));
+ return ( (*_imp__atexit)(pfn));
}
/* Likewise for non-ANSI _onexit */
-extern _onexit_t (*__IMP(_onexit))(_onexit_t);
+extern _onexit_t (*_imp___onexit)(_onexit_t);
_onexit_t
_onexit (_onexit_t pfn )
{
- return (*__IMP(_onexit))(pfn);
+ return (*_imp___onexit)(pfn);
}
-
-#endif
Index: main.c
===================================================================
--- main.c (revision 785)
+++ main.c (working copy)
@@ -16,30 +16,19 @@
#define ISSPACE(a) (a == ' ' || a == '\t')
-#ifndef UNDER_CE
extern int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
LPSTR szCmdLine, int nShow);
-#else
-extern int __cdecl WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
- LPWSTR szCmdLine, int nShow);
-#endif
-
int
main (int argc, char *argv[], char *environ[])
{
+ char *szCmd;
+ STARTUPINFO startinfo;
int nRet;
/* Get the command line passed to the process. */
-#ifndef UNDER_CE
- char *szCmd;
- STARTUPINFOA startinfo;
szCmd = GetCommandLineA ();
GetStartupInfoA (&startinfo);
-#else
- wchar_t *szCmd;
- szCmd = GetCommandLineW ();
-#endif
/* Strip off the name of the application and any leading
* whitespace. */
@@ -81,13 +70,9 @@
}
}
-#ifndef UNDER_CE
nRet = WinMain (GetModuleHandle (NULL), NULL, szCmd,
(startinfo.dwFlags & STARTF_USESHOWWINDOW) ?
startinfo.wShowWindow : SW_SHOWDEFAULT);
-#else
- nRet = WinMain (GetModuleHandle (NULL), NULL, szCmd, SW_SHOW);
-#endif
return nRet;
}
Index: crt1_ce.c
===================================================================
--- crt1_ce.c (revision 0)
+++ crt1_ce.c (revision 0)
@@ -0,0 +1,71 @@
+/*
+ * crt1_ce.c
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Source code for the startup proceedures used by all programs on a
+ * wince system. This code is compiled to make crt1.o, which should be
+ * located in the library path.
+ *
+ */
+
+/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
+ avoid problems with older GCC. */
+#define __IN_MINGW_RUNTIME
+#include <stdlib.h>
+#include <stdio.h>
+#include <process.h>
+#include <float.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+extern void __gccmain ();
+extern void _pei386_runtime_relocator (void);
+
+/* No atexit on coredll, we must initialize our private version. */
+BOOL __atexit_init(void);
+
+/*
+ * This function is called from the entry point for all programs.
+ */
+void
+WinMainCRTStartup (HINSTANCE hInst, HINSTANCE hPrevInst,
+ LPWSTR lpCmdLine, int nCmdShow)
+{
+ int nRet;
+
+ /*
+ * Initialize floating point unit.
+ */
+ _fpreset (); /* Supplied by the runtime library. */
+
+ /* Adust references to dllimported data that have non-zero offsets. */
+ _pei386_runtime_relocator ();
+
+ /*
+ * Initialize the atexit table.
+ */
+ __atexit_init();
+
+ /* From libgcc.a, __main calls global class constructors,
+ __do_global_ctors, which registers __do_global_dtors as the first
+ entry of the private atexit table we have just initialised */
+ __gccmain();
+
+ /*
+ * Call the main function. If the user does not supply one the one
+ * in the 'libmingw32.a' library will be linked in, and that one
+ * calls main. See winmain_ce.c in the 'lib' dir for more details.
+ */
+
+ nRet = WinMain(hInst, hPrevInst, lpCmdLine, nCmdShow);
+
+ /*
+ * Perform exit processing for the C library. This means
+ * flushing output and calling 'atexit' registered functions.
+ */
+ _cexit ();
+
+ ExitProcess (nRet);
+}
Property changes on: crt1_ce.c
___________________________________________________________________
Name: svn:eol-style
+ native
Index: winmain_ce.c
===================================================================
--- winmain_ce.c (revision 0)
+++ winmain_ce.c (revision 0)
@@ -0,0 +1,147 @@
+/*
+ * winmain_ce.c
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Extra startup code for applications which do not have a WinMain
+ * function of their own (but do have a main). Generally these are
+ * non-GUI applications, but they don't *have* to be.
+ *
+ */
+
+#include <stdlib.h>
+#include <process.h>
+#include <windows.h>
+
+/*
+ * Access to a standard 'main'-like argument count and list. Also included
+ * is a table of environment variables.
+ */
+int _argc = 0;
+char **_argv = 0;
+
+static int
+_parse_tokens(char* string, char*** tokens, int length)
+{
+ /* Extract whitespace- and quotes- delimited tokens from the given string
+ and put them into the tokens array. Returns number of tokens
+ extracted. Length specifies the current size of tokens[].
+ THIS METHOD MODIFIES string. */
+
+ const char* whitespace = " \t\r\n";
+ char* tokenEnd;
+ const char* quoteCharacters = "\"\'";
+ char* end = string + strlen (string);
+
+ if (string == NULL)
+ return length;
+
+ while (1)
+ {
+ const char* q;
+ /* Skip over initial whitespace. */
+ string += strspn(string, whitespace);
+ if (*string == '\0')
+ break;
+
+ for (q = quoteCharacters; *q; ++q)
+ {
+ if (*string == *q)
+ break;
+ }
+ if (*q)
+ {
+ /* Token is quoted. */
+ char quote = *string++;
+ tokenEnd = strchr(string, quote);
+ /* If there is no endquote, the token is the rest of the string.
*/
+ if (!tokenEnd)
+ tokenEnd = end;
+ }
+ else
+ {
+ tokenEnd = string + strcspn(string, whitespace);
+ }
+
+ *tokenEnd = '\0';
+
+ {
+ char** new_tokens;
+ int newlen = length + 1;
+ new_tokens = realloc (*tokens, sizeof (char**) * newlen);
+ if (!new_tokens)
+ {
+ /* Out of memory. */
+ return -1;
+ }
+
+ *tokens = new_tokens;
+ (*tokens)[length] = string;
+ length = newlen;
+ }
+ if (tokenEnd == end)
+ break;
+ string = tokenEnd + 1;
+ }
+exit:
+ return length;
+}
+
+static void
+__mainArgs(int *argc, char ***argv, wchar_t *cmdlinePtrW)
+{
+ wchar_t cmdnameBufW[512];
+ char buf[MAX_PATH];
+ int cmdlineLen = 0;
+ int modlen;
+ char* __cmdlinebuf;
+
+ /* argv[0] is the path of invoked program - get this from CE. */
+ cmdnameBufW[0] = 0;
+ modlen = GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof
(cmdnameBufW[0]));
+
+ if (!cmdlinePtrW)
+ cmdlineLen = 0;
+ else
+ cmdlineLen = wcslen(cmdlinePtrW);
+
+ __cmdlinebuf = malloc (modlen + 1 + cmdlineLen + 1);
+ if (!__cmdlinebuf)
+ ExitProcess(-1);
+
+ *argv = malloc (sizeof (char**) * 1);
+ if (!*argv)
+ ExitProcess(-1);
+
+ (*argv)[0] = __cmdlinebuf;
+ wcstombs((*argv)[0], cmdnameBufW, wcslen(cmdnameBufW) + 1);
+ /* Add one to account for argv[0] */
+ (*argc)++;
+
+ if (cmdlineLen > 0)
+ {
+ char* argv1 = (*argv)[0] + strlen((*argv)[0]) + 1;
+ wcstombs(argv1, cmdlinePtrW, cmdlineLen + 1);
+ *argc = _parse_tokens(argv1, argv, 1);
+ if (*argc < 0)
+ ExitProcess(-1);
+ }
+ (*argv)[*argc] = 0;
+ return;
+}
+
+// Normally, the application will define a WinMain function. However,
+// if the main application does not, this dummy WinMain will call a
+// main() function instead.
+extern int __cdecl
+WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
+ LPWSTR szCmdLine, int nShow)
+{
+ /*
+ * Set up __argc, __argv.
+ */
+ __mainArgs(&_argc, &_argv, szCmdLine);
+
+ return main(_argc, _argv);
+}
Property changes on: winmain_ce.c
___________________________________________________________________
Name: svn:eol-style
+ native
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Cegcc-devel mailing list
Cegcc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cegcc-devel