- added size information about most of the generated thunks (import,

16/32 relay...)
- marked the wine thunks by inserting specific symbols (to be managed
  by wine's dbghelp)
- removed the stabs generation:
  + mostly used by winedbg, and the previous item will replace it for
    dbghelp
  + still broken for gdb anyway
- enhanced const correctness
This commit is contained in:
Eric Pouech 2004-05-18 21:27:44 +00:00 committed by Alexandre Julliard
parent b38b6821fb
commit d3f8f78c3a
5 changed files with 56 additions and 75 deletions

View File

@ -133,14 +133,14 @@ static const char * const ppc_reg[32] = { "0", "1", "2", "3", "4", "5", "6", "7"
/* compare function names; helper for resolve_imports */ /* compare function names; helper for resolve_imports */
static int name_cmp( const void *name, const void *entry ) static int name_cmp( const void *name, const void *entry )
{ {
return strcmp( *(char **)name, *(char **)entry ); return strcmp( *(const char* const *)name, *(const char* const *)entry );
} }
/* compare function names; helper for resolve_imports */ /* compare function names; helper for resolve_imports */
static int func_cmp( const void *func1, const void *func2 ) static int func_cmp( const void *func1, const void *func2 )
{ {
const ORDDEF *odp1 = *(const ORDDEF **)func1; const ORDDEF *odp1 = *(const ORDDEF * const *)func1;
const ORDDEF *odp2 = *(const ORDDEF **)func2; const ORDDEF *odp2 = *(const ORDDEF * const *)func2;
return strcmp( odp1->name ? odp1->name : odp1->export_name, return strcmp( odp1->name ? odp1->name : odp1->export_name,
odp2->name ? odp2->name : odp2->export_name ); odp2->name ? odp2->name : odp2->export_name );
} }
@ -621,6 +621,7 @@ static int output_immediate_imports( FILE *outfile )
{ {
int i, j, pos; int i, j, pos;
int nb_imm = nb_imports - nb_delayed; int nb_imm = nb_imports - nb_delayed;
static const char import_thunks[] = "__wine_spec_import_thunks";
if (!nb_imm) goto done; if (!nb_imm) goto done;
@ -678,6 +679,8 @@ static int output_immediate_imports( FILE *outfile )
fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" ); fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" );
pos = 20 * (nb_imm + 1); /* offset of imports.data from start of imports */ pos = 20 * (nb_imm + 1); /* offset of imports.data from start of imports */
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(8) );
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", import_thunks);
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
if (dll_imports[i]->delay) continue; if (dll_imports[i]->delay) continue;
@ -737,10 +740,12 @@ static int output_immediate_imports( FILE *outfile )
#error You need to define import thunks for your architecture! #error You need to define import thunks for your architecture!
#endif #endif
fprintf( outfile, "\"\n" ); fprintf( outfile, "\"\n" );
fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", name, name);
} }
pos += 4; pos += 4;
} }
fprintf( outfile, "\".text\");\n#ifndef __GNUC__\n}\n#endif\n\n" ); fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", import_thunks, import_thunks);
fprintf( outfile, " \".text\");\n#ifndef __GNUC__\n}\n#endif\n\n" );
done: done:
return nb_imm; return nb_imm;
@ -750,6 +755,8 @@ static int output_immediate_imports( FILE *outfile )
static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{ {
int i, idx, j, pos; int i, idx, j, pos;
static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders";
static const char delayed_import_thunks[] = "__wine_spec_delayed_import_thunks";
if (!nb_delayed) goto done; if (!nb_delayed) goto done;
@ -868,6 +875,7 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
fprintf( outfile, "#endif\n" ); fprintf( outfile, "#endif\n" );
fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) );
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_loaders);
fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" ); fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" );
fprintf( outfile, " \"" __ASM_NAME("__wine_delay_load_asm") ":\\n\"\n" ); fprintf( outfile, " \"" __ASM_NAME("__wine_delay_load_asm") ":\\n\"\n" );
#if defined(__i386__) #if defined(__i386__)
@ -928,6 +936,7 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
#else #else
#error You need to defined delayed import thunks for your architecture! #error You need to defined delayed import thunks for your architecture!
#endif #endif
fprintf( outfile, " \"\\t.size " __ASM_NAME("__wine_delay_load_asm") ", . - " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
for (i = idx = 0; i < nb_imports; i++) for (i = idx = 0; i < nb_imports; i++)
{ {
@ -956,11 +965,14 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
#else #else
#error You need to defined delayed import thunks for your architecture! #error You need to defined delayed import thunks for your architecture!
#endif #endif
fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", name, name);
} }
idx++; idx++;
} }
fprintf( outfile, "\n \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", delayed_import_loaders, delayed_import_loaders);
fprintf( outfile, "\n \".data\\n\\t.align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, "\n \".data\\n\\t.align %d\\n\"\n", get_alignment(8) );
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_thunks);
pos = nb_delayed * 32; pos = nb_delayed * 32;
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
@ -1020,8 +1032,10 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
#error You need to define delayed import thunks for your architecture! #error You need to define delayed import thunks for your architecture!
#endif #endif
fprintf( outfile, "\n" ); fprintf( outfile, "\n" );
fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", name, name);
} }
} }
fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", delayed_import_thunks, delayed_import_thunks);
fprintf( outfile, "\".text\");\n" ); fprintf( outfile, "\".text\");\n" );
fprintf( outfile, "#ifndef __GNUC__\n" ); fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" ); fprintf( outfile, "}\n" );

View File

@ -540,8 +540,8 @@ error:
static int name_compare( const void *name1, const void *name2 ) static int name_compare( const void *name1, const void *name2 )
{ {
ORDDEF *odp1 = *(ORDDEF **)name1; const ORDDEF *odp1 = *(const ORDDEF * const *)name1;
ORDDEF *odp2 = *(ORDDEF **)name2; const ORDDEF *odp2 = *(const ORDDEF * const *)name2;
return strcmp( odp1->name, odp2->name ); return strcmp( odp1->name, odp2->name );
} }

View File

@ -32,25 +32,22 @@
#include "build.h" #include "build.h"
#if defined(__GNUC__) && !defined(__svr4__)
static const int use_stabs = 1;
#else
static const int use_stabs = 0;
#endif
#ifdef __i386__ #ifdef __i386__
static void function_header( FILE *outfile, const char *name ) static void function_header( FILE *outfile, const char *name )
{ {
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
if (use_stabs)
fprintf( outfile, "\t.stabs \"%s:F1\",36,0,0," __ASM_NAME("%s") "\n", name, name);
fprintf( outfile, "\t" __ASM_FUNC("%s") "\n", name ); fprintf( outfile, "\t" __ASM_FUNC("%s") "\n", name );
fprintf( outfile, "\t.globl " __ASM_NAME("%s") "\n", name ); fprintf( outfile, "\t.globl " __ASM_NAME("%s") "\n", name );
fprintf( outfile, __ASM_NAME("%s") ":\n", name ); fprintf( outfile, __ASM_NAME("%s") ":\n", name );
} }
static void function_footer( FILE *outfile, const char *name )
{
fprintf( outfile, ".size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\n", name, name );
}
/******************************************************************* /*******************************************************************
* BuildCallFrom16Core * BuildCallFrom16Core
* *
@ -444,6 +441,10 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
/* Return to return stub which will return to caller */ /* Return to return stub which will return to caller */
fprintf( outfile, "\tlret $12\n" ); fprintf( outfile, "\tlret $12\n" );
} }
if (thunk) function_footer( outfile, "__wine_call_from_16_thunk" );
else if (reg_func) function_footer( outfile, "__wine_call_from_16_regs" );
else if (short_ret) function_footer( outfile, "__wine_call_from_16_word" );
else function_footer( outfile, "__wine_call_from_16_long" );
} }
@ -605,6 +606,9 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
/* Jump to the called routine */ /* Jump to the called routine */
fprintf( outfile, "\t.byte 0x66\n" ); fprintf( outfile, "\t.byte 0x66\n" );
fprintf( outfile, "\tlret\n" ); fprintf( outfile, "\tlret\n" );
/* Function footer */
function_footer( outfile, name );
} }
@ -648,6 +652,9 @@ static void BuildRet16Func( FILE *outfile )
fprintf( outfile, "\tlret\n" ); fprintf( outfile, "\tlret\n" );
/* Function footer */
function_footer( outfile, "CallTo16_Ret" );
/* Declare the return address and data selector variables */ /* Declare the return address and data selector variables */
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
@ -756,9 +763,6 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
/* Function header */ /* Function header */
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
if (use_stabs)
fprintf( outfile, ".stabs \"CALL32_%s:F1\",36,0,0," __ASM_NAME("CALL32_%s") "\n",
name, name );
fprintf( outfile, "\t.globl " __ASM_NAME("CALL32_%s") "\n", name ); fprintf( outfile, "\t.globl " __ASM_NAME("CALL32_%s") "\n", name );
fprintf( outfile, __ASM_NAME("CALL32_%s") ":\n", name ); fprintf( outfile, __ASM_NAME("CALL32_%s") ":\n", name );
@ -882,6 +886,7 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
fprintf( outfile, "\tpopl %%edi\n" ); fprintf( outfile, "\tpopl %%edi\n" );
fprintf( outfile, "\tpopl %%ebp\n" ); fprintf( outfile, "\tpopl %%ebp\n" );
fprintf( outfile, "\tret\n" ); fprintf( outfile, "\tret\n" );
fprintf( outfile, ".size " __ASM_NAME("CALL32_%s") ", . - " __ASM_NAME("CALL32_%s") "\n", name, name );
} }
static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx ) static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx )
@ -907,6 +912,8 @@ static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx )
} }
fprintf( outfile, "\tlret\n" ); fprintf( outfile, "\tlret\n" );
fprintf( outfile, ".size " __ASM_NAME("CALL32_%s_Ret") ", . - " __ASM_NAME("CALL32_%s_Ret") "\n", name, name );
/* Declare the return address variable */ /* Declare the return address variable */
fprintf( outfile, "\n\t.globl " __ASM_NAME("CALL32_%s_RetAddr") "\n", name ); fprintf( outfile, "\n\t.globl " __ASM_NAME("CALL32_%s_RetAddr") "\n", name );
@ -1036,10 +1043,12 @@ static void BuildCallFrom32Regs( FILE *outfile )
fprintf( outfile, "\tpopl %%ds\n" ); fprintf( outfile, "\tpopl %%ds\n" );
fprintf( outfile, "\tiret\n" ); fprintf( outfile, "\tiret\n" );
function_footer( outfile, "__wine_call_from_32_regs" );
function_header( outfile, "__wine_call_from_32_restore_regs" ); function_header( outfile, "__wine_call_from_32_restore_regs" );
fprintf( outfile, "\tleal 4(%%esp),%%ecx\n" ); fprintf( outfile, "\tleal 4(%%esp),%%ecx\n" );
fprintf( outfile, "\tjmp 2b\n" ); fprintf( outfile, "\tjmp 2b\n" );
function_footer( outfile, "__wine_call_from_32_restore_regs" );
} }
@ -1059,7 +1068,7 @@ static void BuildCallFrom32Regs( FILE *outfile )
* On entry to function, fs register points to a valid TEB. * On entry to function, fs register points to a valid TEB.
* On exit from function, stack will be popped. * On exit from function, stack will be popped.
*/ */
void BuildPendingEventCheck( FILE *outfile ) static void BuildPendingEventCheck( FILE *outfile )
{ {
/* Function header */ /* Function header */
@ -1091,6 +1100,8 @@ void BuildPendingEventCheck( FILE *outfile )
fprintf( outfile, ".globl " __ASM_NAME("DPMI_PendingEventCheck_Return") "\n" ); fprintf( outfile, ".globl " __ASM_NAME("DPMI_PendingEventCheck_Return") "\n" );
fprintf( outfile, __ASM_NAME("DPMI_PendingEventCheck_Return") ":\n" ); fprintf( outfile, __ASM_NAME("DPMI_PendingEventCheck_Return") ":\n" );
fprintf( outfile, "\tiret\n" ); fprintf( outfile, "\tiret\n" );
function_footer( outfile, "DPMI_PendingEventCheck" );
} }
@ -1101,26 +1112,12 @@ void BuildPendingEventCheck( FILE *outfile )
*/ */
void BuildRelays16( FILE *outfile ) void BuildRelays16( FILE *outfile )
{ {
char buffer[1024];
/* File header */ /* File header */
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" ); fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
fprintf( outfile, "\t.text\n" ); fprintf( outfile, "\t.text\n" );
if (output_file_name && use_stabs) fprintf( outfile, __ASM_NAME("__wine_spec_thunk_text_16") ":\n\n" );
{
getcwd(buffer, sizeof(buffer));
fprintf( outfile, "\t.file\t\"%s\"\n", output_file_name );
/*
* The stabs help the internal debugger as they are an indication that it
* is sensible to step into a thunk/trampoline.
*/
fprintf( outfile, ".stabs \"%s/\",100,0,0,Code_Start\n", buffer);
fprintf( outfile, ".stabs \"%s\",100,0,0,Code_Start\n", output_file_name );
fprintf( outfile, "Code_Start:\n\n" );
}
fprintf( outfile, __ASM_NAME("Call16_Start") ":\n" ); fprintf( outfile, __ASM_NAME("Call16_Start") ":\n" );
fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Start") "\n" ); fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Start") "\n" );
@ -1152,24 +1149,11 @@ void BuildRelays16( FILE *outfile )
fprintf( outfile, __ASM_NAME("Call16_End") ":\n" ); fprintf( outfile, __ASM_NAME("Call16_End") ":\n" );
fprintf( outfile, "\t.globl " __ASM_NAME("Call16_End") "\n" ); fprintf( outfile, "\t.globl " __ASM_NAME("Call16_End") "\n" );
fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_16") ",. - " __ASM_NAME("__wine_spec_thunk_text_16") "\n" );
if (use_stabs)
{
fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
fprintf( outfile, ".Letext:\n");
/* Some versions of gdb need to have the filename data for
each section, so output it again for the data section. */
if (output_file_name)
{
fprintf( outfile, ".stabs \"%s/\",100,0,0,Data_Start\n", buffer);
fprintf( outfile, ".stabs \"%s\",100,0,0,Data_Start\n", output_file_name );
fprintf( outfile, "Data_Start:\n\n" );
}
}
/* The whole Call16_Ret segment must lie within the .data section */ /* The whole Call16_Ret segment must lie within the .data section */
fprintf( outfile, "\n\t.data\n" ); fprintf( outfile, "\n\t.data\n" );
fprintf( outfile, __ASM_NAME("__wine_spec_thunk_data_16") ":\n\n" );
fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Ret_Start") "\n" ); fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Ret_Start") "\n" );
fprintf( outfile, __ASM_NAME("Call16_Ret_Start") ":\n" ); fprintf( outfile, __ASM_NAME("Call16_Ret_Start") ":\n" );
@ -1188,6 +1172,7 @@ void BuildRelays16( FILE *outfile )
/* End of Call16_Ret segment */ /* End of Call16_Ret segment */
fprintf( outfile, "\n\t.globl " __ASM_NAME("Call16_Ret_End") "\n" ); fprintf( outfile, "\n\t.globl " __ASM_NAME("Call16_Ret_End") "\n" );
fprintf( outfile, __ASM_NAME("Call16_Ret_End") ":\n" ); fprintf( outfile, __ASM_NAME("Call16_Ret_End") ":\n" );
fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_data_16") ",. - " __ASM_NAME("__wine_spec_thunk_data_16") "\n" );
} }
/******************************************************************* /*******************************************************************
@ -1201,30 +1186,12 @@ void BuildRelays32( FILE *outfile )
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" ); fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
fprintf( outfile, "\t.text\n" ); fprintf( outfile, "\t.text\n" );
fprintf( outfile, __ASM_NAME("__wine_spec_thunk_text_32") ":\n\n" );
if (output_file_name && use_stabs)
{
char buffer[1024];
getcwd(buffer, sizeof(buffer));
fprintf( outfile, "\t.file\t\"%s\"\n", output_file_name );
/*
* The stabs help the internal debugger as they are an indication that it
* is sensible to step into a thunk/trampoline.
*/
fprintf( outfile, ".stabs \"%s/\",100,0,0,Code_Start\n", buffer);
fprintf( outfile, ".stabs \"%s\",100,0,0,Code_Start\n", output_file_name );
fprintf( outfile, "Code_Start:\n\n" );
}
/* 32-bit register entry point */ /* 32-bit register entry point */
BuildCallFrom32Regs( outfile ); BuildCallFrom32Regs( outfile );
if (use_stabs) fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_32") ",. - " __ASM_NAME("__wine_spec_thunk_text_32") "\n" );
{
fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
fprintf( outfile, ".Letext:\n");
}
} }
#else /* __i386__ */ #else /* __i386__ */

View File

@ -133,7 +133,7 @@ static struct res_type *add_type( struct res_tree *tree, const struct resource *
/* get the next word from the current resource file */ /* get the next word from the current resource file */
static WORD get_word(void) static WORD get_word(void)
{ {
WORD ret = *(WORD *)file_pos; WORD ret = *(const WORD *)file_pos;
file_pos += sizeof(WORD); file_pos += sizeof(WORD);
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name ); if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
return ret; return ret;
@ -142,7 +142,7 @@ static WORD get_word(void)
/* get the next dword from the current resource file */ /* get the next dword from the current resource file */
static DWORD get_dword(void) static DWORD get_dword(void)
{ {
DWORD ret = *(DWORD *)file_pos; DWORD ret = *(const DWORD *)file_pos;
file_pos += sizeof(DWORD); file_pos += sizeof(DWORD);
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name ); if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
return ret; return ret;
@ -151,7 +151,7 @@ static DWORD get_dword(void)
/* get a string from the current resource file */ /* get a string from the current resource file */
static void get_string( struct string_id *str ) static void get_string( struct string_id *str )
{ {
if (*(WCHAR *)file_pos == 0xffff) if (*(const WCHAR *)file_pos == 0xffff)
{ {
get_word(); /* skip the 0xffff */ get_word(); /* skip the 0xffff */
str->str = NULL; str->str = NULL;
@ -159,7 +159,7 @@ static void get_string( struct string_id *str )
} }
else else
{ {
WCHAR *p = xmalloc( (strlenW((WCHAR*)file_pos) + 1) * sizeof(WCHAR) ); WCHAR *p = xmalloc( (strlenW((const WCHAR*)file_pos) + 1) * sizeof(WCHAR) );
str->str = p; str->str = p;
str->id = 0; str->id = 0;
while ((*p++ = get_word())); while ((*p++ = get_word()));
@ -202,7 +202,7 @@ static void load_next_resource( DLLSPEC *spec )
get_dword(); /* skip version */ get_dword(); /* skip version */
get_dword(); /* skip characteristics */ get_dword(); /* skip characteristics */
file_pos = (char *)res->data + res->data_size; file_pos = (const char *)res->data + res->data_size;
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name ); if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
} }

View File

@ -471,8 +471,8 @@ static const char *get_function_name( const ORDDEF *odp )
*/ */
static int Spec16TypeCompare( const void *e1, const void *e2 ) static int Spec16TypeCompare( const void *e1, const void *e2 )
{ {
const ORDDEF *odp1 = *(const ORDDEF **)e1; const ORDDEF *odp1 = *(const ORDDEF * const *)e1;
const ORDDEF *odp2 = *(const ORDDEF **)e2; const ORDDEF *odp2 = *(const ORDDEF * const *)e2;
int retval; int retval;
int type1 = odp1->type; int type1 = odp1->type;
int type2 = odp2->type; int type2 = odp2->type;