Output the import directory using assembly instead of C structures.
This commit is contained in:
parent
d1c5f68dca
commit
932ecb24eb
|
@ -192,7 +192,8 @@ extern void add_ignore_symbol( const char *name );
|
|||
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 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 int load_res32_file( const char *name, 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
|
|||
output_function_size( outfile, name );
|
||||
}
|
||||
|
||||
/* output the import table of a Win32 module */
|
||||
static int output_immediate_imports( FILE *outfile )
|
||||
/* compute the size of the import table */
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
|
||||
fprintf( outfile, "\nstatic struct {\n" );
|
||||
fprintf( outfile, " struct {\n" );
|
||||
fprintf( outfile, " void *OriginalFirstThunk;\n" );
|
||||
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" );
|
||||
fprintf( outfile, "/* import table */\n" );
|
||||
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(4) );
|
||||
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_imports"));
|
||||
|
||||
/* list of dlls */
|
||||
|
||||
for (i = j = 0; i < nb_imports; i++)
|
||||
{
|
||||
if (dll_imports[i]->delay) continue;
|
||||
fprintf( outfile, " { 0, 0, 0, \"%s\", &imports.data[%d] },\n",
|
||||
dll_imports[i]->spec->file_name, j );
|
||||
dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
|
||||
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;
|
||||
}
|
||||
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, " },\n {\n" );
|
||||
|
||||
/* list of imported functions */
|
||||
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_import_data_ptrs") );
|
||||
for (i = 0; i < nb_imports; i++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
ORDDEF *odp = dll_imports[i]->imports[j];
|
||||
if (!(odp->flags & FLAG_NONAME))
|
||||
{
|
||||
unsigned short ord = odp->ordinal;
|
||||
fprintf( outfile, " \"\\%03o\\%03o%s\",\n",
|
||||
*(unsigned char *)&ord, *((unsigned char *)&ord + 1), odp->name );
|
||||
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(2) );
|
||||
fprintf( outfile, " \"__wine_spec_import_data_%s_%s:\\n\"\n", dll_name, 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 */
|
||||
|
@ -810,20 +849,18 @@ static void output_immediate_import_thunks( FILE *outfile )
|
|||
|
||||
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, "asm(\".text\\n\\t.align %d\\n\"\n", get_alignment(8) );
|
||||
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;
|
||||
for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += sizeof(const char *))
|
||||
{
|
||||
ORDDEF *odp = dll_imports[i]->imports[j];
|
||||
output_import_thunk( outfile, odp->name ? odp->name : odp->export_name,
|
||||
"imports", pos );
|
||||
"__wine_spec_import_data_ptrs", pos );
|
||||
}
|
||||
pos += 4;
|
||||
}
|
||||
|
@ -832,11 +869,11 @@ static void output_immediate_import_thunks( FILE *outfile )
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
if (!nb_delayed) return 0;
|
||||
if (!nb_delayed) return;
|
||||
|
||||
fprintf( outfile, "static void *__wine_delay_imp_hmod[%d];\n", nb_delayed );
|
||||
for (i = 0; i < nb_imports; i++)
|
||||
|
@ -899,8 +936,6 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
|
|||
}
|
||||
}
|
||||
fprintf( outfile, " }\n};\n\n" );
|
||||
|
||||
return nb_delayed;
|
||||
}
|
||||
|
||||
/* output the delayed import thunks of a Win32 module */
|
||||
|
@ -1042,7 +1077,7 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
|
|||
}
|
||||
break;
|
||||
}
|
||||
output_function_size( outfile, name );
|
||||
output_function_size( outfile, buffer );
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
@ -1065,18 +1100,16 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
|
|||
fprintf( outfile, ");\n" );
|
||||
}
|
||||
|
||||
/* output the import and delayed import tables of a Win32 module
|
||||
* returns number of DLLs exported in 'immediate' mode
|
||||
*/
|
||||
int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed )
|
||||
/* output the import and delayed import tables of a Win32 module */
|
||||
void output_imports( FILE *outfile, DLLSPEC *spec )
|
||||
{
|
||||
*nb_delayed = output_delayed_imports( outfile, spec );
|
||||
return output_immediate_imports( outfile );
|
||||
output_delayed_imports( outfile, spec );
|
||||
}
|
||||
|
||||
/* output the import and delayed import thunks of a Win32 module */
|
||||
void output_import_thunks( FILE *outfile, DLLSPEC *spec )
|
||||
{
|
||||
output_delayed_import_thunks( outfile, spec );
|
||||
output_immediate_imports( 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
|
|||
*/
|
||||
void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
||||
{
|
||||
int exports_size = 0;
|
||||
int nr_exports, nr_imports, nr_delayed;
|
||||
int exports_size, imports_size;
|
||||
unsigned int page_size = get_page_size();
|
||||
|
||||
nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
|
||||
resolve_imports( spec );
|
||||
exports_size = get_exports_size( spec );
|
||||
imports_size = get_imports_size();
|
||||
output_standard_file_header( outfile );
|
||||
|
||||
/* Reserve some space for the PE header */
|
||||
|
@ -475,13 +474,13 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, "extern char _end[];\n" );
|
||||
|
||||
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 the DLL imports */
|
||||
|
||||
nr_imports = output_imports( outfile, spec, &nr_delayed );
|
||||
output_imports( outfile, spec );
|
||||
|
||||
/* Output the resources */
|
||||
|
||||
|
@ -584,10 +583,10 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, " 0,\n" ); /* LoaderFlags */
|
||||
fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */
|
||||
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 );
|
||||
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */
|
||||
nr_imports ? "&imports" : "0", nr_imports ? "sizeof(imports)" : "0" );
|
||||
fprintf( outfile, " { %s, %u },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */
|
||||
imports_size ? "__wine_spec_imports" : "0", imports_size );
|
||||
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */
|
||||
spec->nb_resources ? "&__wine_spec_resources" : "0",
|
||||
spec->nb_resources ? "sizeof(__wine_spec_resources)" : "0" );
|
||||
|
|
Loading…
Reference in New Issue