- 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:
parent
b38b6821fb
commit
d3f8f78c3a
|
@ -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 */
|
||||
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 */
|
||||
static int func_cmp( const void *func1, const void *func2 )
|
||||
{
|
||||
const ORDDEF *odp1 = *(const ORDDEF **)func1;
|
||||
const ORDDEF *odp2 = *(const ORDDEF **)func2;
|
||||
const ORDDEF *odp1 = *(const ORDDEF * const *)func1;
|
||||
const ORDDEF *odp2 = *(const ORDDEF * const *)func2;
|
||||
return strcmp( odp1->name ? odp1->name : odp1->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 nb_imm = nb_imports - nb_delayed;
|
||||
static const char import_thunks[] = "__wine_spec_import_thunks";
|
||||
|
||||
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" );
|
||||
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_NAME("%s") ":\\n\"\n", import_thunks);
|
||||
|
||||
for (i = 0; i < nb_imports; i++)
|
||||
{
|
||||
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!
|
||||
#endif
|
||||
fprintf( outfile, "\"\n" );
|
||||
fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", name, name);
|
||||
}
|
||||
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:
|
||||
return nb_imm;
|
||||
|
@ -750,6 +755,8 @@ static int output_immediate_imports( FILE *outfile )
|
|||
static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -868,6 +875,7 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
|
|||
fprintf( outfile, "#endif\n" );
|
||||
|
||||
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, " \"" __ASM_NAME("__wine_delay_load_asm") ":\\n\"\n" );
|
||||
#if defined(__i386__)
|
||||
|
@ -928,6 +936,7 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
|
|||
#else
|
||||
#error You need to defined delayed import thunks for your architecture!
|
||||
#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++)
|
||||
{
|
||||
|
@ -956,11 +965,14 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
|
|||
#else
|
||||
#error You need to defined delayed import thunks for your architecture!
|
||||
#endif
|
||||
fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", name, name);
|
||||
}
|
||||
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, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_thunks);
|
||||
pos = nb_delayed * 32;
|
||||
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!
|
||||
#endif
|
||||
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, "#ifndef __GNUC__\n" );
|
||||
fprintf( outfile, "}\n" );
|
||||
|
|
|
@ -540,8 +540,8 @@ error:
|
|||
|
||||
static int name_compare( const void *name1, const void *name2 )
|
||||
{
|
||||
ORDDEF *odp1 = *(ORDDEF **)name1;
|
||||
ORDDEF *odp2 = *(ORDDEF **)name2;
|
||||
const ORDDEF *odp1 = *(const ORDDEF * const *)name1;
|
||||
const ORDDEF *odp2 = *(const ORDDEF * const *)name2;
|
||||
return strcmp( odp1->name, odp2->name );
|
||||
}
|
||||
|
||||
|
|
|
@ -32,25 +32,22 @@
|
|||
|
||||
#include "build.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(__svr4__)
|
||||
static const int use_stabs = 1;
|
||||
#else
|
||||
static const int use_stabs = 0;
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
static void function_header( FILE *outfile, const char *name )
|
||||
{
|
||||
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.globl " __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
|
||||
*
|
||||
|
@ -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 */
|
||||
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 */
|
||||
fprintf( outfile, "\t.byte 0x66\n" );
|
||||
fprintf( outfile, "\tlret\n" );
|
||||
|
||||
/* Function footer */
|
||||
function_footer( outfile, name );
|
||||
}
|
||||
|
||||
|
||||
|
@ -648,6 +652,9 @@ static void BuildRet16Func( FILE *outfile )
|
|||
|
||||
fprintf( outfile, "\tlret\n" );
|
||||
|
||||
/* Function footer */
|
||||
function_footer( outfile, "CallTo16_Ret" );
|
||||
|
||||
/* Declare the return address and data selector variables */
|
||||
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
|
@ -756,9 +763,6 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
|
|||
/* Function header */
|
||||
|
||||
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, __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 %%ebp\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 )
|
||||
|
@ -907,6 +912,8 @@ static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx )
|
|||
}
|
||||
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 */
|
||||
|
||||
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, "\tiret\n" );
|
||||
function_footer( outfile, "__wine_call_from_32_regs" );
|
||||
|
||||
function_header( outfile, "__wine_call_from_32_restore_regs" );
|
||||
fprintf( outfile, "\tleal 4(%%esp),%%ecx\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 exit from function, stack will be popped.
|
||||
*/
|
||||
void BuildPendingEventCheck( FILE *outfile )
|
||||
static void BuildPendingEventCheck( FILE *outfile )
|
||||
{
|
||||
/* Function header */
|
||||
|
||||
|
@ -1091,6 +1100,8 @@ void BuildPendingEventCheck( FILE *outfile )
|
|||
fprintf( outfile, ".globl " __ASM_NAME("DPMI_PendingEventCheck_Return") "\n" );
|
||||
fprintf( outfile, __ASM_NAME("DPMI_PendingEventCheck_Return") ":\n" );
|
||||
fprintf( outfile, "\tiret\n" );
|
||||
|
||||
function_footer( outfile, "DPMI_PendingEventCheck" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1101,26 +1112,12 @@ void BuildPendingEventCheck( FILE *outfile )
|
|||
*/
|
||||
void BuildRelays16( FILE *outfile )
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
/* File header */
|
||||
|
||||
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
|
||||
fprintf( outfile, "\t.text\n" );
|
||||
|
||||
if (output_file_name && use_stabs)
|
||||
{
|
||||
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("__wine_spec_thunk_text_16") ":\n\n" );
|
||||
|
||||
fprintf( outfile, __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, "\t.globl " __ASM_NAME("Call16_End") "\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" );
|
||||
}
|
||||
}
|
||||
fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_16") ",. - " __ASM_NAME("__wine_spec_thunk_text_16") "\n" );
|
||||
|
||||
/* The whole Call16_Ret segment must lie within the .data section */
|
||||
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, __ASM_NAME("Call16_Ret_Start") ":\n" );
|
||||
|
||||
|
@ -1188,6 +1172,7 @@ void BuildRelays16( FILE *outfile )
|
|||
/* End of Call16_Ret segment */
|
||||
fprintf( outfile, "\n\t.globl " __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, "\t.text\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" );
|
||||
}
|
||||
fprintf( outfile, __ASM_NAME("__wine_spec_thunk_text_32") ":\n\n" );
|
||||
|
||||
/* 32-bit register entry point */
|
||||
BuildCallFrom32Regs( outfile );
|
||||
|
||||
if (use_stabs)
|
||||
{
|
||||
fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
|
||||
fprintf( outfile, ".Letext:\n");
|
||||
}
|
||||
fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_32") ",. - " __ASM_NAME("__wine_spec_thunk_text_32") "\n" );
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
|
|
@ -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 */
|
||||
static WORD get_word(void)
|
||||
{
|
||||
WORD ret = *(WORD *)file_pos;
|
||||
WORD ret = *(const WORD *)file_pos;
|
||||
file_pos += sizeof(WORD);
|
||||
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
|
||||
return ret;
|
||||
|
@ -142,7 +142,7 @@ static WORD get_word(void)
|
|||
/* get the next dword from the current resource file */
|
||||
static DWORD get_dword(void)
|
||||
{
|
||||
DWORD ret = *(DWORD *)file_pos;
|
||||
DWORD ret = *(const DWORD *)file_pos;
|
||||
file_pos += sizeof(DWORD);
|
||||
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
|
||||
return ret;
|
||||
|
@ -151,7 +151,7 @@ static DWORD get_dword(void)
|
|||
/* get a string from the current resource file */
|
||||
static void get_string( struct string_id *str )
|
||||
{
|
||||
if (*(WCHAR *)file_pos == 0xffff)
|
||||
if (*(const WCHAR *)file_pos == 0xffff)
|
||||
{
|
||||
get_word(); /* skip the 0xffff */
|
||||
str->str = NULL;
|
||||
|
@ -159,7 +159,7 @@ static void get_string( struct string_id *str )
|
|||
}
|
||||
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->id = 0;
|
||||
while ((*p++ = get_word()));
|
||||
|
@ -202,7 +202,7 @@ static void load_next_resource( DLLSPEC *spec )
|
|||
get_dword(); /* skip version */
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -471,8 +471,8 @@ static const char *get_function_name( const ORDDEF *odp )
|
|||
*/
|
||||
static int Spec16TypeCompare( const void *e1, const void *e2 )
|
||||
{
|
||||
const ORDDEF *odp1 = *(const ORDDEF **)e1;
|
||||
const ORDDEF *odp2 = *(const ORDDEF **)e2;
|
||||
const ORDDEF *odp1 = *(const ORDDEF * const *)e1;
|
||||
const ORDDEF *odp2 = *(const ORDDEF * const *)e2;
|
||||
int retval;
|
||||
int type1 = odp1->type;
|
||||
int type2 = odp2->type;
|
||||
|
|
Loading…
Reference in New Issue