Commit 3cd7379d authored by Alexandre Julliard's avatar Alexandre Julliard

Moved stub function generation to import.c. Added a get_stub_name

function to ensure naming consistency.
parent d34b1c23
......@@ -180,8 +180,8 @@ extern int remove_stdcall_decoration( char *name );
extern void assemble_file( const char *src_file, const char *obj_file );
extern DLLSPEC *alloc_dll_spec(void);
extern void free_dll_spec( DLLSPEC *spec );
extern int has_stubs( const DLLSPEC *spec );
extern const char *make_c_identifier( const char *str );
extern const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec );
extern unsigned int get_alignment(unsigned int align);
extern unsigned int get_page_size(void);
extern unsigned int get_ptr_size(void);
......@@ -201,6 +201,8 @@ extern void add_extra_ld_symbol( const char *name );
extern void read_undef_symbols( DLLSPEC *spec, char **argv );
extern int resolve_imports( DLLSPEC *spec );
extern int has_imports(void);
extern void output_get_pc_thunk( FILE *outfile );
extern void output_stubs( FILE *outfile, DLLSPEC *spec );
extern void output_imports( FILE *outfile, DLLSPEC *spec );
extern int load_res32_file( const char *name, DLLSPEC *spec );
extern void output_resources( FILE *outfile, DLLSPEC *spec );
......
......@@ -455,6 +455,18 @@ static const char *get_default_entry_point( const DLLSPEC *spec )
return "__wine_spec_exe_entry";
}
/* check if the spec file exports any stubs */
static int has_stubs( const DLLSPEC *spec )
{
int i;
for (i = 0; i < spec->nb_entry_points; i++)
{
ORDDEF *odp = &spec->entry_points[i];
if (odp->type == TYPE_STUB) return 1;
}
return 0;
}
/* add the extra undefined symbols that will be contained in the generated spec file itself */
static void add_extra_undef_symbols( DLLSPEC *spec )
{
......@@ -632,7 +644,7 @@ int resolve_imports( DLLSPEC *spec )
}
/* output the get_pc thunk if needed */
static void output_get_pc_thunk( FILE *outfile )
void output_get_pc_thunk( FILE *outfile )
{
if (target_cpu != CPU_x86) return;
if (!UsePIC) return;
......@@ -1155,6 +1167,77 @@ static void output_external_link_imports( FILE *outfile, DLLSPEC *spec )
output_function_size( outfile, "__wine_spec_external_link_thunks" );
}
/*******************************************************************
* output_stubs
*
* Output the functions for stub entry points
*/
void output_stubs( FILE *outfile, DLLSPEC *spec )
{
const char *name, *exp_name;
int i, pos;
if (!has_stubs( spec )) return;
fprintf( outfile, "\n/* stub functions */\n\n" );
fprintf( outfile, "\t.text\n" );
for (i = pos = 0; i < spec->nb_entry_points; i++)
{
ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue;
name = get_stub_name( odp, spec );
exp_name = odp->name ? odp->name : odp->export_name;
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, "%s:\n", asm_name(name) );
if (UsePIC)
{
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
fprintf( outfile, "1:" );
if (exp_name)
{
fprintf( outfile, "\tleal .L__wine_stub_strings+%d-1b(%%eax),%%ecx\n", pos );
fprintf( outfile, "\tpushl %%ecx\n" );
pos += strlen(exp_name) + 1;
}
else
fprintf( outfile, "\tpushl $%d\n", odp->ordinal );
fprintf( outfile, "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" );
fprintf( outfile, "\tpushl %%ecx\n" );
}
else
{
if (exp_name)
{
fprintf( outfile, "\tpushl $.L__wine_stub_strings+%d\n", pos );
pos += strlen(exp_name) + 1;
}
else
fprintf( outfile, "\tpushl $%d\n", odp->ordinal );
fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" );
}
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") );
fprintf( outfile, "\t%s\n", func_size(name) );
}
if (pos)
{
fprintf( outfile, "\t%s\n", get_asm_string_section() );
fprintf( outfile, ".L__wine_stub_strings:\n" );
for (i = 0; i < spec->nb_entry_points; i++)
{
ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue;
exp_name = odp->name ? odp->name : odp->export_name;
if (exp_name)
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name );
}
}
}
/* output the import and delayed import tables of a Win32 module */
void output_imports( FILE *outfile, DLLSPEC *spec )
{
......
......@@ -45,28 +45,6 @@ static int string_compare( const void *ptr1, const void *ptr2 )
/*******************************************************************
* make_internal_name
*
* Generate an internal name for an entry point. Used for stubs etc.
*/
static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const char *prefix )
{
static char buffer[256];
if (odp->name || odp->export_name)
{
char *p;
sprintf( buffer, "__wine_%s_%s_%s", prefix, spec->file_name,
odp->name ? odp->name : odp->export_name );
/* make sure name is a legal C identifier */
for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break;
if (!*p) return buffer;
}
sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(spec->file_name), odp->ordinal );
return buffer;
}
/*******************************************************************
* output_debug
*
* Output the debug channels.
......@@ -163,7 +141,7 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
break;
case TYPE_STUB:
fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(),
asm_name( make_internal_name( odp, spec, "stub" )) );
asm_name( get_stub_name( odp, spec )) );
break;
default:
assert(0);
......@@ -273,78 +251,6 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
/*******************************************************************
* output_stubs
*
* Output the functions for stub entry points
*/
static void output_stubs( FILE *outfile, DLLSPEC *spec )
{
const char *name, *exp_name;
int i, pos;
if (!has_stubs( spec )) return;
fprintf( outfile, "\n/* stub functions */\n\n" );
fprintf( outfile, "\t.text\n" );
for (i = pos = 0; i < spec->nb_entry_points; i++)
{
ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue;
name = make_internal_name( odp, spec, "stub" );
exp_name = odp->name ? odp->name : odp->export_name;
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, "%s:\n", asm_name(name) );
if (UsePIC)
{
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
fprintf( outfile, "1:" );
if (exp_name)
{
fprintf( outfile, "\tleal .L__wine_stub_strings+%d-1b(%%eax),%%ecx\n", pos );
fprintf( outfile, "\tpushl %%ecx\n" );
pos += strlen(exp_name) + 1;
}
else
fprintf( outfile, "\tpushl $%d\n", odp->ordinal );
fprintf( outfile, "\tleal %s-1b(%%eax),%%ecx\n", asm_name("__wine_spec_file_name") );
fprintf( outfile, "\tpushl %%ecx\n" );
}
else
{
if (exp_name)
{
fprintf( outfile, "\tpushl $.L__wine_stub_strings+%d\n", pos );
pos += strlen(exp_name) + 1;
}
else
fprintf( outfile, "\tpushl $%d\n", odp->ordinal );
fprintf( outfile, "\tpushl $%s\n", asm_name("__wine_spec_file_name") );
}
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") );
fprintf( outfile, "\t%s\n", func_size(name) );
}
if (pos)
{
fprintf( outfile, "\t%s\n", get_asm_string_section() );
fprintf( outfile, ".L__wine_stub_strings:\n" );
for (i = 0; i < spec->nb_entry_points; i++)
{
ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue;
exp_name = odp->name ? odp->name : odp->export_name;
if (exp_name)
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name );
}
}
}
/*******************************************************************
* output_dll_init
*
* Output code for calling a dll constructor and destructor.
......@@ -599,6 +505,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
fprintf( outfile, "\n\t%s\n", get_asm_string_section() );
fprintf( outfile, "%s\n", asm_globl("__wine_spec_file_name") );
fprintf( outfile, ".L__wine_spec_file_name:\n" );
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
if (target_platform == PLATFORM_APPLE)
fprintf( outfile, "\t.lcomm %s,4\n", asm_name("_end") );
......
......@@ -362,23 +362,6 @@ void free_dll_spec( DLLSPEC *spec )
/*******************************************************************
* has_stubs
*
* Check if the spec file exports any stubs
*/
int has_stubs( const DLLSPEC *spec )
{
int i;
for (i = 0; i < spec->nb_entry_points; i++)
{
ORDDEF *odp = &spec->entry_points[i];
if (odp->type == TYPE_STUB) return 1;
}
return 0;
}
/*******************************************************************
* make_c_identifier
*
* Map a string to a valid C identifier.
......@@ -398,6 +381,27 @@ const char *make_c_identifier( const char *str )
}
/*******************************************************************
* get_stub_name
*
* Generate an internal name for a stub entry point.
*/
const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec )
{
static char buffer[256];
if (odp->name || odp->export_name)
{
char *p;
sprintf( buffer, "__wine_stub_%s", odp->name ? odp->name : odp->export_name );
/* make sure name is a legal C identifier */
for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break;
if (!*p) return buffer;
}
sprintf( buffer, "__wine_stub_%s_%d", make_c_identifier(spec->file_name), odp->ordinal );
return buffer;
}
/*****************************************************************
* Function: get_alignment
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment