Commit 932ecb24 authored by Alexandre Julliard's avatar Alexandre Julliard

Output the import directory using assembly instead of C structures.

parent d1c5f68d
...@@ -192,7 +192,8 @@ extern void add_ignore_symbol( const char *name ); ...@@ -192,7 +192,8 @@ extern void add_ignore_symbol( const char *name );
extern void add_extra_ld_symbol( const char *name ); extern void add_extra_ld_symbol( const char *name );
extern void read_undef_symbols( DLLSPEC *spec, char **argv ); extern void read_undef_symbols( DLLSPEC *spec, char **argv );
extern int resolve_imports( DLLSPEC *spec ); extern int resolve_imports( DLLSPEC *spec );
extern int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed ); extern int get_imports_size(void);
extern void output_imports( FILE *outfile, DLLSPEC *spec );
extern void output_import_thunks( FILE *outfile, DLLSPEC *spec ); extern void output_import_thunks( FILE *outfile, DLLSPEC *spec );
extern int load_res32_file( const char *name, DLLSPEC *spec ); extern int load_res32_file( const char *name, DLLSPEC *spec );
extern void output_resources( FILE *outfile, DLLSPEC *spec ); extern void output_resources( FILE *outfile, DLLSPEC *spec );
......
...@@ -742,63 +742,102 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta ...@@ -742,63 +742,102 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta
output_function_size( outfile, name ); output_function_size( outfile, name );
} }
/* output the import table of a Win32 module */ /* compute the size of the import table */
static int output_immediate_imports( FILE *outfile ) int get_imports_size(void)
{ {
int i, j, nb_imm = nb_imports - nb_delayed; int i, total_size, nb_imm = nb_imports - nb_delayed;
if (!nb_imm) return 0; if (!nb_imm) return 0;
/* list of dlls */
total_size = 5 * 4 * (nb_imm + 1);
for (i = 0; i < nb_imports; i++)
{
if (dll_imports[i]->delay) continue;
total_size += (dll_imports[i]->nb_imports + 1) * 4;
}
/* Note: the strings are not counted as being part of the import directory */
return total_size;
}
/* output the import table of a Win32 module */
static void output_immediate_imports( FILE *outfile )
{
int i, j;
const char *dll_name;
if (nb_imports == nb_delayed) return; /* no immediate imports */
/* main import header */ /* main import header */
fprintf( outfile, "\nstatic struct {\n" ); fprintf( outfile, "/* import table */\n" );
fprintf( outfile, " struct {\n" ); fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(4) );
fprintf( outfile, " void *OriginalFirstThunk;\n" ); fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_imports"));
fprintf( outfile, " unsigned int TimeDateStamp;\n" );
fprintf( outfile, " unsigned int ForwarderChain;\n" );
fprintf( outfile, " const char *Name;\n" );
fprintf( outfile, " void *FirstThunk;\n" );
fprintf( outfile, " } imp[%d];\n", nb_imm+1 );
fprintf( outfile, " const char *data[%d];\n",
total_imports - total_delayed + nb_imm );
fprintf( outfile, "} imports = {\n {\n" );
/* list of dlls */ /* list of dlls */
for (i = j = 0; i < nb_imports; i++) for (i = j = 0; i < nb_imports; i++)
{ {
if (dll_imports[i]->delay) continue; if (dll_imports[i]->delay) continue;
fprintf( outfile, " { 0, 0, 0, \"%s\", &imports.data[%d] },\n", dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
dll_imports[i]->spec->file_name, j ); fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* OriginalFirstThunk */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* ForwarderChain */
fprintf( outfile, " \"\\t.long __wine_spec_import_name_%s\\n\"\n", dll_name ); /* Name */
fprintf( outfile, " \"\\t.long %s+%d\\n\"\n", /* FirstThunk */
asm_name("__wine_spec_import_data_ptrs"), j * 4 );
j += dll_imports[i]->nb_imports + 1; j += dll_imports[i]->nb_imports + 1;
} }
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* OriginalFirstThunk */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* ForwarderChain */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Name */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* FirstThunk */
fprintf( outfile, " { 0, 0, 0, 0, 0 },\n" ); fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_import_data_ptrs") );
fprintf( outfile, " },\n {\n" ); for (i = 0; i < nb_imports; i++)
{
/* list of imported functions */ if (dll_imports[i]->delay) continue;
dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
for (j = 0; j < dll_imports[i]->nb_imports; j++)
{
ORDDEF *odp = dll_imports[i]->imports[j];
if (!(odp->flags & FLAG_NONAME))
fprintf( outfile, " \"\\t.long __wine_spec_import_data_%s_%s\\n\"\n",
dll_name, odp->name );
else
fprintf( outfile, " \"\\t.long %d\\n\"\n", odp->ordinal );
}
fprintf( outfile, " \"\\t.long 0\\n\"\n" );
}
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;
fprintf( outfile, " /* %s */\n", dll_imports[i]->spec->file_name ); dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
for (j = 0; j < dll_imports[i]->nb_imports; j++) for (j = 0; j < dll_imports[i]->nb_imports; j++)
{ {
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
if (!(odp->flags & FLAG_NONAME)) if (!(odp->flags & FLAG_NONAME))
{ {
unsigned short ord = odp->ordinal; fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(2) );
fprintf( outfile, " \"\\%03o\\%03o%s\",\n", fprintf( outfile, " \"__wine_spec_import_data_%s_%s:\\n\"\n", dll_name, odp->name );
*(unsigned char *)&ord, *((unsigned char *)&ord + 1), odp->name ); fprintf( outfile, " \"\\t%s %d\\n\"\n", get_asm_short_keyword(), odp->ordinal );
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), odp->name );
} }
else
fprintf( outfile, " (char *)%d,\n", odp->ordinal );
} }
fprintf( outfile, " 0,\n" );
} }
fprintf( outfile, " }\n};\n\n" );
return nb_imm; for (i = 0; i < nb_imports; i++)
{
if (dll_imports[i]->delay) continue;
dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
fprintf( outfile, " \"__wine_spec_import_name_%s:\\t%s \\\"%s\\\"\\n\"\n",
dll_name, get_asm_string_keyword(), dll_imports[i]->spec->file_name );
}
fprintf( outfile, ");\n" );
} }
/* output the import thunks of a Win32 module */ /* output the import thunks of a Win32 module */
...@@ -810,20 +849,18 @@ static void output_immediate_import_thunks( FILE *outfile ) ...@@ -810,20 +849,18 @@ static void output_immediate_import_thunks( FILE *outfile )
if (!nb_imm) return; if (!nb_imm) return;
pos = (sizeof(void *) + 2*sizeof(unsigned int) + sizeof(const char *) + sizeof(void *)) *
(nb_imm + 1); /* offset of imports.data from start of imports */
fprintf( outfile, "/* immediate import thunks */\n" ); fprintf( outfile, "/* immediate import thunks */\n" );
fprintf( outfile, "asm(\".text\\n\\t.align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, "asm(\".text\\n\\t.align %d\\n\"\n", get_alignment(8) );
fprintf( outfile, " \"%s:\\n\"\n", asm_name(import_thunks)); fprintf( outfile, " \"%s:\\n\"\n", asm_name(import_thunks));
for (i = 0; i < nb_imports; i++) for (i = pos = 0; i < nb_imports; i++)
{ {
if (dll_imports[i]->delay) continue; if (dll_imports[i]->delay) continue;
for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += sizeof(const char *)) for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += sizeof(const char *))
{ {
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, output_import_thunk( outfile, odp->name ? odp->name : odp->export_name,
"imports", pos ); "__wine_spec_import_data_ptrs", pos );
} }
pos += 4; pos += 4;
} }
...@@ -832,11 +869,11 @@ static void output_immediate_import_thunks( FILE *outfile ) ...@@ -832,11 +869,11 @@ static void output_immediate_import_thunks( FILE *outfile )
} }
/* output the delayed import table of a Win32 module */ /* output the delayed import table of a Win32 module */
static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{ {
int i, j; int i, j;
if (!nb_delayed) return 0; if (!nb_delayed) return;
fprintf( outfile, "static void *__wine_delay_imp_hmod[%d];\n", nb_delayed ); fprintf( outfile, "static void *__wine_delay_imp_hmod[%d];\n", nb_delayed );
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
...@@ -899,8 +936,6 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) ...@@ -899,8 +936,6 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
} }
} }
fprintf( outfile, " }\n};\n\n" ); fprintf( outfile, " }\n};\n\n" );
return nb_delayed;
} }
/* output the delayed import thunks of a Win32 module */ /* output the delayed import thunks of a Win32 module */
...@@ -1042,7 +1077,7 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ...@@ -1042,7 +1077,7 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
} }
break; break;
} }
output_function_size( outfile, name ); output_function_size( outfile, buffer );
} }
idx++; idx++;
} }
...@@ -1065,18 +1100,16 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ...@@ -1065,18 +1100,16 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
fprintf( outfile, ");\n" ); fprintf( outfile, ");\n" );
} }
/* output the import and delayed import tables of a Win32 module /* output the import and delayed import tables of a Win32 module */
* returns number of DLLs exported in 'immediate' mode void output_imports( FILE *outfile, DLLSPEC *spec )
*/
int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed )
{ {
*nb_delayed = output_delayed_imports( outfile, spec ); output_delayed_imports( outfile, spec );
return output_immediate_imports( outfile );
} }
/* output the import and delayed import thunks of a Win32 module */ /* output the import and delayed import thunks of a Win32 module */
void output_import_thunks( FILE *outfile, DLLSPEC *spec ) void output_import_thunks( FILE *outfile, DLLSPEC *spec )
{ {
output_delayed_import_thunks( outfile, spec ); output_immediate_imports( outfile );
output_immediate_import_thunks( outfile ); output_immediate_import_thunks( outfile );
output_delayed_import_thunks( outfile, spec );
} }
...@@ -440,13 +440,12 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru ...@@ -440,13 +440,12 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru
*/ */
void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
{ {
int exports_size = 0; int exports_size, imports_size;
int nr_exports, nr_imports, nr_delayed;
unsigned int page_size = get_page_size(); unsigned int page_size = get_page_size();
nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
resolve_imports( spec ); resolve_imports( spec );
exports_size = get_exports_size( spec ); exports_size = get_exports_size( spec );
imports_size = get_imports_size();
output_standard_file_header( outfile ); output_standard_file_header( outfile );
/* Reserve some space for the PE header */ /* Reserve some space for the PE header */
...@@ -475,13 +474,13 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) ...@@ -475,13 +474,13 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
fprintf( outfile, "extern char _end[];\n" ); fprintf( outfile, "extern char _end[];\n" );
fprintf( outfile, "const char __wine_spec_file_name[] = \"%s\";\n", spec->file_name ); fprintf( outfile, "const char __wine_spec_file_name[] = \"%s\";\n", spec->file_name );
fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[];\n\n" ); fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[], __wine_spec_imports[];\n\n" );
output_stub_funcs( outfile, spec ); output_stub_funcs( outfile, spec );
/* Output the DLL imports */ /* Output the DLL imports */
nr_imports = output_imports( outfile, spec, &nr_delayed ); output_imports( outfile, spec );
/* Output the resources */ /* Output the resources */
...@@ -584,10 +583,10 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) ...@@ -584,10 +583,10 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
fprintf( outfile, " 0,\n" ); /* LoaderFlags */ fprintf( outfile, " 0,\n" ); /* LoaderFlags */
fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */ fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */
fprintf( outfile, " {\n" ); fprintf( outfile, " {\n" );
fprintf( outfile, " { %s, %d },\n", /* IMAGE_DIRECTORY_ENTRY_EXPORT */ fprintf( outfile, " { %s, %u },\n", /* IMAGE_DIRECTORY_ENTRY_EXPORT */
exports_size ? "__wine_spec_exports" : "0", exports_size ); exports_size ? "__wine_spec_exports" : "0", exports_size );
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */ fprintf( outfile, " { %s, %u },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */
nr_imports ? "&imports" : "0", nr_imports ? "sizeof(imports)" : "0" ); imports_size ? "__wine_spec_imports" : "0", imports_size );
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */ fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */
spec->nb_resources ? "&__wine_spec_resources" : "0", spec->nb_resources ? "&__wine_spec_resources" : "0",
spec->nb_resources ? "sizeof(__wine_spec_resources)" : "0" ); spec->nb_resources ? "sizeof(__wine_spec_resources)" : "0" );
......
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