From 9a634693e7307d8bc42bad7720224ba32921dd9c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 5 Nov 2000 04:49:13 +0000 Subject: [PATCH] Added debug_channels support. --- tools/winebuild/build.h | 2 ++ tools/winebuild/main.c | 2 ++ tools/winebuild/parser.c | 26 ++++++++++++++++++ tools/winebuild/spec32.c | 59 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index cd75f79b791..62227e505ad 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -166,6 +166,7 @@ extern int Limit; extern int DLLHeapSize; extern int UsePIC; extern int debugging; +extern int nb_debug_channels; extern char DLLName[80]; extern char DLLFileName[80]; @@ -173,6 +174,7 @@ extern char DLLInitFunc[80]; extern char owner_name[80]; extern const char *input_file_name; extern const char *output_file_name; +extern char **debug_channels; extern ORDDEF EntryPoints[MAX_ORDINALS]; extern ORDDEF *Ordinals[MAX_ORDINALS]; diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 19479d4af55..fbe6936d7b8 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -29,11 +29,13 @@ int UsePIC = 0; int nb_entry_points = 0; int nb_names = 0; int debugging = 1; +int nb_debug_channels = 0; char DLLName[80]; char DLLFileName[80]; char DLLInitFunc[80]; char owner_name[80]; +char **debug_channels; const char *input_file_name; const char *output_file_name; diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 66948cf5a0c..958ecd7fffc 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -111,6 +111,26 @@ static char * GetToken(void) } +/******************************************************************* + * ParseDebug + * + * Parse a debug channel definition. + */ +static void ParseDebug(void) +{ + char *token = GetToken(); + if (*token != '(') fatal_error( "Expected '(' got '%s'\n", token ); + while ((token = GetToken())) + { + if (*token == ')') break; + debug_channels = xrealloc( debug_channels, + (nb_debug_channels + 1) * sizeof(*debug_channels)); + debug_channels[nb_debug_channels++] = xstrdup(token); + } + if (!token) fatal_error( "End of file in dbch declaration\n" ); +} + + /******************************************************************* * ParseVariable * @@ -490,6 +510,12 @@ SPEC_TYPE ParseTopLevel( FILE *file ) fatal_error( "Owner only supported for Win16 spec files\n" ); strcpy( owner_name, GetToken() ); } + else if (strcmp(token, "debug_channels") == 0) + { + if (SpecType != SPEC_WIN32) + fatal_error( "debug channels only supported for Win32 spec files\n" ); + ParseDebug(); + } else if (strcmp(token, "@") == 0) { if (SpecType != SPEC_WIN32) diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 79c75a00657..c1ded913340 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -23,6 +23,13 @@ static int name_compare( const void *name1, const void *name2 ) return strcmp( odp1->name, odp2->name ); } +static int string_compare( const void *ptr1, const void *ptr2 ) +{ + const char * const *str1 = ptr1; + const char * const *str2 = ptr2; + return strcmp( *str1, *str2 ); +} + /******************************************************************* * AssignOrdinals * @@ -66,6 +73,35 @@ static void AssignOrdinals(void) } +/******************************************************************* + * output_debug + * + * Output the debug channels. + */ +static int output_debug( FILE *outfile ) +{ + int i; + + if (!nb_debug_channels) return 0; + qsort( debug_channels, nb_debug_channels, sizeof(debug_channels[0]), string_compare ); + + for (i = 0; i < nb_debug_channels; i++) + fprintf( outfile, "char __wine_dbch_%s[] = \"\\003%s\";\n", + debug_channels[i], debug_channels[i] ); + + fprintf( outfile, "\nstatic char * const debug_channels[%d] =\n{\n", nb_debug_channels ); + for (i = 0; i < nb_debug_channels; i++) + { + fprintf( outfile, " __wine_dbch_%s", debug_channels[i] ); + if (i < nb_debug_channels - 1) fprintf( outfile, ",\n" ); + } + fprintf( outfile, "\n};\n\n" ); + fprintf( outfile, "static void *debug_registration;\n\n" ); + + return nb_debug_channels; +} + + /******************************************************************* * output_exports * @@ -263,7 +299,7 @@ static void output_exports( FILE *outfile, int nr_exports, int nr_names, int fwd } #endif /* __i386__ */ - fprintf( outfile, " }\n};\n" ); + fprintf( outfile, " }\n};\n\n" ); } @@ -276,7 +312,7 @@ void BuildSpec32File( FILE *outfile ) { ORDDEF *odp; int i, fwd_size = 0, have_regs = FALSE; - int nr_exports, nr_imports, nr_resources; + int nr_exports, nr_imports, nr_resources, nr_debug; int characteristics, subsystem; const char *init_func; DWORD page_size; @@ -414,6 +450,10 @@ void BuildSpec32File( FILE *outfile ) nr_resources = output_resources( outfile ); + /* Output the debug channels */ + + nr_debug = output_debug( outfile ); + /* Output LibMain function */ init_func = DLLInitFunc[0] ? DLLInitFunc : NULL; @@ -566,14 +606,25 @@ void BuildSpec32File( FILE *outfile ) fprintf( outfile, "#ifdef __GNUC__\n" ); fprintf( outfile, "static void %s_init(void) __attribute__((constructor));\n", DLLName ); + fprintf( outfile, "static void %s_fini(void) __attribute__((destructor));\n", DLLName ); fprintf( outfile, "#else /* defined(__GNUC__) */\n" ); fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" ); fprintf( outfile, " \"\\tcall %s_init\\n\"\n", DLLName ); fprintf( outfile, " \"\\t.previous\\n\");\n" ); + fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" ); + fprintf( outfile, " \"\\tcall %s_fini\\n\"\n", DLLName ); + fprintf( outfile, " \"\\t.previous\\n\");\n" ); fprintf( outfile, "}\n" ); - fprintf( outfile, "#endif /* defined(__GNUC__) */\n" ); + fprintf( outfile, "#endif /* defined(__GNUC__) */\n\n" ); fprintf( outfile, "static void %s_init(void)\n{\n", DLLName ); fprintf( outfile, " extern void BUILTIN32_RegisterDLL( const struct image_nt_headers *, const char * );\n" ); - fprintf( outfile, " BUILTIN32_RegisterDLL( &nt_header, \"%s\" );\n}\n", DLLFileName ); + fprintf( outfile, " extern void *wine_dbg_register( char * const *, int );\n"); + fprintf( outfile, " BUILTIN32_RegisterDLL( &nt_header, \"%s\" );\n", DLLFileName ); + if (nr_debug) fprintf( outfile, " debug_registration = wine_dbg_register( debug_channels, %d );\n", nr_debug ); + fprintf( outfile, "}\n\n" ); + fprintf( outfile, "static void %s_fini(void)\n{\n", DLLName ); + fprintf( outfile, " extern void wine_dbg_unregister( void * );\n"); + if (nr_debug) fprintf( outfile, " wine_dbg_unregister( debug_registration );\n" ); + fprintf( outfile, "}\n" ); }