Moved stub function generation to import.c. Added a get_stub_name
function to ensure naming consistency.
This commit is contained in:
parent
d34b1c23a2
commit
3cd7379d26
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -44,28 +44,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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -272,78 +250,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
|
||||
*
|
||||
|
@ -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") );
|
||||
|
|
|
@ -361,23 +361,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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue