Right now we filter entry points for the target architecture when parsing .spec file. On ARM64X, we're interested in entry points for two different targets. On MSVC (and experimental LLVM), creating importlibs that support both ARM64EC and ARM64 requires passing two .def files. With .spec files, we may generate them both from the same .spec file.
This separates per-target exports into a separate struct, while parser stores all entry points specified in the .spec file.
From: Jacek Caban jacek@codeweavers.com
--- tools/winebuild/build.h | 14 +++++++++++++- tools/winebuild/parser.c | 32 ++++++++++++++++++++++++++------ tools/winebuild/utils.c | 12 ++++++++++-- 3 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index e4ad4e6556f..ec463792eef 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -129,6 +129,17 @@ struct apiset
static const unsigned int apiset_hash_factor = 31;
+struct exports +{ + int nb_entry_points; /* number of used entry points */ + ORDDEF **entry_points; /* dll entry points */ + int nb_names; /* number of entry points with names */ + ORDDEF **names; /* array of entry point names (points into entry_points) */ + int base; /* ordinal base */ + int limit; /* ordinal limit */ + ORDDEF **ordinals; /* array of dll ordinals (points into entry_points) */ +}; + typedef struct { char *src_name; /* file name of the source spec file */ @@ -152,9 +163,10 @@ typedef struct int subsystem_major; /* subsystem version major number */ int subsystem_minor; /* subsystem version minor number */ int unicode_app; /* default to unicode entry point */ - ORDDEF *entry_points; /* dll entry points */ + ORDDEF *entry_points; /* spec entry points */ ORDDEF **names; /* array of entry point names (points into entry_points) */ ORDDEF **ordinals; /* array of dll ordinals (points into entry_points) */ + struct exports exports; /* dll exports */ struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */ struct apiset apiset; /* list of defined api sets */ } DLLSPEC; diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 959170e39b8..01c230a0a2c 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -952,6 +952,29 @@ static void assign_ordinals( DLLSPEC *spec ) }
+static void assign_exports( DLLSPEC *spec ) +{ + struct exports *exports = &spec->exports; + unsigned int i; + + exports->entry_points = xmalloc( spec->nb_entry_points * sizeof(*exports->entry_points) ); + for (i = 0; i < spec->nb_entry_points; i++) + { + ORDDEF *entry = &spec->entry_points[i]; + exports->entry_points[exports->nb_entry_points++] = entry; + } + + assign_names( spec ); + assign_ordinals( spec ); + + exports->nb_names = spec->nb_names; + exports->names = spec->names; + exports->base = spec->base; + exports->limit = spec->limit; + exports->ordinals = spec->ordinals; +} + + /******************************************************************* * add_16bit_exports * @@ -1008,8 +1031,7 @@ void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 ) odp->u.func.nb_args * sizeof(odp->u.func.args[0]) ); }
- assign_names( spec32 ); - assign_ordinals( spec32 ); + assign_exports( spec32 ); }
@@ -1052,8 +1074,7 @@ int parse_spec_file( FILE *file, DLLSPEC *spec ) }
current_line = 0; /* no longer parsing the input file */ - assign_names( spec ); - assign_ordinals( spec ); + assign_exports( spec ); return !nb_errors; }
@@ -1295,7 +1316,6 @@ int parse_def_file( FILE *file, DLLSPEC *spec ) }
current_line = 0; /* no longer parsing the input file */ - assign_names( spec ); - assign_ordinals( spec ); + assign_exports( spec ); return !nb_errors; } diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 2334611fa0d..337db77bcaf 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -615,10 +615,19 @@ DLLSPEC *alloc_dll_spec(void) spec->subsystem_major = 4; spec->subsystem_minor = 0; spec->dll_characteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; + spec->exports.base = MAX_ORDINALS; return spec; }
+static void free_exports( struct exports *entries ) +{ + free( entries->entry_points ); + free( entries->names ); + free( entries->ordinals ); +} + + /******************************************************************* * free_dll_spec * @@ -635,13 +644,12 @@ void free_dll_spec( DLLSPEC *spec ) free( odp->export_name ); free( odp->link_name ); } + free_exports( &spec->exports ); free( spec->file_name ); free( spec->dll_name ); free( spec->c_name ); free( spec->init_func ); free( spec->entry_points ); - free( spec->names ); - free( spec->ordinals ); free( spec->resources ); free( spec ); }
From: Jacek Caban jacek@codeweavers.com
--- tools/winebuild/import.c | 55 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 27 deletions(-)
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index bc43c24ac13..a2473efc5ba 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -353,11 +353,11 @@ static DLLSPEC *read_import_lib( struct import *imp ) return NULL; /* the same file was already loaded, ignore this one */ }
- if (spec->nb_entry_points) + if (spec->exports.nb_entry_points) { - imp->exports = xmalloc( spec->nb_entry_points * sizeof(*imp->exports) ); - for (i = 0; i < spec->nb_entry_points; i++) - imp->exports[imp->nb_exports++] = &spec->entry_points[i]; + imp->exports = xmalloc( spec->exports.nb_entry_points * sizeof(*imp->exports) ); + for (i = 0; i < spec->exports.nb_entry_points; i++) + imp->exports[imp->nb_exports++] = spec->exports.entry_points[i]; qsort( imp->exports, imp->nb_exports, sizeof(*imp->exports), func_cmp ); } return spec; @@ -493,13 +493,13 @@ static void add_undef_import( const char *name, int is_ordinal ) }
/* check if the spec file exports any stubs */ -static int has_stubs( const DLLSPEC *spec ) +static int has_stubs( const struct exports *exports ) { int i;
- for (i = 0; i < spec->nb_entry_points; i++) + for (i = 0; i < exports->nb_entry_points; i++) { - ORDDEF *odp = &spec->entry_points[i]; + ORDDEF *odp = exports->entry_points[i]; if (odp->type == TYPE_STUB) return 1; } return 0; @@ -510,12 +510,12 @@ static void add_extra_undef_symbols( DLLSPEC *spec ) { add_extra_ld_symbol( spec->init_func ); if (spec->type == SPEC_WIN16) add_extra_ld_symbol( "DllMain" ); - if (has_stubs( spec )) add_extra_ld_symbol( "__wine_spec_unimplemented_stub" ); + if (has_stubs( &spec->exports )) add_extra_ld_symbol( "__wine_spec_unimplemented_stub" ); if (delayed_imports.count) add_extra_ld_symbol( "__delayLoadHelper2" ); }
/* check if a given imported dll is not needed, taking forwards into account */ -static int check_unused( const struct import* imp, const DLLSPEC *spec ) +static int check_unused( const struct import* imp, const struct exports *exports ) { int i; const char *file_name = imp->dll_name; @@ -523,9 +523,9 @@ static int check_unused( const struct import* imp, const DLLSPEC *spec ) const char *p = strchr( file_name, '.' ); if (p && !strcasecmp( p, ".dll" )) len = p - file_name;
- for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (!odp || !(odp->flags & FLAG_FORWARD)) continue; if (!strncasecmp( odp->link_name, file_name, len ) && odp->link_name[len] == '.') @@ -541,9 +541,9 @@ static void check_undefined_forwards( DLLSPEC *spec ) char *link_name, *api_name, *dll_name, *p; int i;
- for (i = 0; i < spec->nb_entry_points; i++) + for (i = 0; i < spec->exports.nb_entry_points; i++) { - ORDDEF *odp = &spec->entry_points[i]; + ORDDEF *odp = spec->exports.entry_points[i];
if (!(odp->flags & FLAG_FORWARD)) continue;
@@ -571,9 +571,9 @@ static void check_undefined_exports( DLLSPEC *spec ) { int i;
- for (i = 0; i < spec->nb_entry_points; i++) + for (i = 0; i < spec->exports.nb_entry_points; i++) { - ORDDEF *odp = &spec->entry_points[i]; + ORDDEF *odp = spec->exports.entry_points[i]; if (odp->type == TYPE_STUB || odp->type == TYPE_ABS || odp->type == TYPE_VARIABLE) continue; if (odp->flags & FLAG_FORWARD) continue; if (find_name( odp->link_name, undef_symbols )) @@ -611,9 +611,9 @@ static char *create_undef_symbols_file( DLLSPEC *spec ) as_file = open_temp_output_file( ".s" ); output( "\t.data\n" );
- for (i = 0; i < spec->nb_entry_points; i++) + for (i = 0; i < spec->exports.nb_entry_points; i++) { - ORDDEF *odp = &spec->entry_points[i]; + ORDDEF *odp = spec->exports.entry_points[i]; if (odp->type == TYPE_STUB || odp->type == TYPE_ABS || odp->type == TYPE_VARIABLE) continue; if (odp->flags & FLAG_FORWARD) continue; output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name( get_link_name( odp ))); @@ -721,7 +721,7 @@ void resolve_dll_imports( DLLSPEC *spec, struct list *list ) if (!imp->nb_imports) { /* the dll is not used, get rid of it */ - if (check_unused( imp, spec )) + if (check_unused( imp, &spec->exports )) warning( "winebuild: %s imported but no symbols used\n", imp->dll_name ); list_remove( &imp->entry ); free_imports( imp ); @@ -1180,16 +1180,17 @@ static void output_external_link_imports( DLLSPEC *spec ) */ void output_stubs( DLLSPEC *spec ) { + struct exports *exports = &spec->exports; const char *name, *exp_name; int i;
- if (!has_stubs( spec )) return; + if (!has_stubs( exports )) return;
output( "\n/* stub functions */\n\n" );
- for (i = 0; i < spec->nb_entry_points; i++) + for (i = 0; i < exports->nb_entry_points; i++) { - ORDDEF *odp = &spec->entry_points[i]; + ORDDEF *odp = exports->entry_points[i]; if (odp->type != TYPE_STUB) continue;
name = get_stub_name( odp, spec ); @@ -1294,9 +1295,9 @@ void output_stubs( DLLSPEC *spec ) output( "\t%s\n", get_asm_string_section() ); output( ".L__wine_spec_file_name:\n" ); output( "\t%s "%s"\n", get_asm_string_keyword(), spec->file_name ); - for (i = 0; i < spec->nb_entry_points; i++) + for (i = 0; i < exports->nb_entry_points; i++) { - ORDDEF *odp = &spec->entry_points[i]; + ORDDEF *odp = exports->entry_points[i]; if (odp->type != TYPE_STUB) continue; exp_name = odp->name ? odp->name : odp->export_name; if (exp_name) @@ -1611,9 +1612,9 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc strarray_addall( &objs, as_files ); as_files = empty_strarray;
- for (i = total = 0; i < spec->nb_entry_points; i++) + for (i = total = 0; i < spec->exports.nb_entry_points; i++) { - const ORDDEF *odp = &spec->entry_points[i]; + const ORDDEF *odp = spec->exports.entry_points[i]; const char *abi_name; char *imp_name;
@@ -1745,9 +1746,9 @@ static void build_unix_import_lib( DLLSPEC *spec, struct strarray files )
/* entry points */
- for (i = total = 0; i < spec->nb_entry_points; i++) + for (i = total = 0; i < spec->exports.nb_entry_points; i++) { - const ORDDEF *odp = &spec->entry_points[i]; + const ORDDEF *odp = spec->exports.entry_points[i];
if (odp->name) name = odp->name; else if (odp->export_name) name = odp->export_name;
From: Jacek Caban jacek@codeweavers.com
--- tools/winebuild/spec16.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 4fcc74978f9..630dc16b69d 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -103,7 +103,7 @@ static void output_entries( DLLSPEC *spec, int first, int count )
for (i = 0; i < count; i++) { - ORDDEF *odp = spec->ordinals[first + i]; + ORDDEF *odp = spec->exports.ordinals[first + i]; output( "\t.byte 0x03\n" ); /* flags: exported & public data */ switch (odp->type) { @@ -134,10 +134,10 @@ static void output_entry_table( DLLSPEC *spec ) { int i, prev = 0, prev_sel = -1, bundle_count = 0;
- for (i = 1; i <= spec->limit; i++) + for (i = 1; i <= spec->exports.limit; i++) { int selector = 0; - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = spec->exports.ordinals[i]; if (!odp) continue; if (odp->flags & FLAG_EXPORT32) continue;
@@ -499,17 +499,18 @@ static int relay_type_compare( const void *e1, const void *e2 ) */ static void output_module16( DLLSPEC *spec ) { + struct exports *exports = &spec->exports; ORDDEF **typelist; ORDDEF *entry_point = NULL; int i, j, nb_funcs;
/* store the main entry point as ordinal 0 */
- if (!spec->ordinals) + if (!exports->ordinals) { - assert(spec->limit == 0); - spec->ordinals = xmalloc( sizeof(spec->ordinals[0]) ); - spec->ordinals[0] = NULL; + assert(exports->limit == 0); + exports->ordinals = xmalloc( sizeof(exports->ordinals[0]) ); + exports->ordinals[0] = NULL; } if (spec->init_func && !(spec->characteristics & IMAGE_FILE_DLL)) { @@ -522,17 +523,17 @@ static void output_module16( DLLSPEC *spec ) entry_point->link_name = xstrdup( spec->init_func ); entry_point->export_name = NULL; entry_point->u.func.nb_args = 0; - assert( !spec->ordinals[0] ); - spec->ordinals[0] = entry_point; + assert( !exports->ordinals[0] ); + exports->ordinals[0] = entry_point; }
/* Build sorted list of all argument types, without duplicates */
- typelist = xmalloc( (spec->limit + 1) * sizeof(*typelist) ); + typelist = xmalloc( (exports->limit + 1) * sizeof(*typelist) );
- for (i = nb_funcs = 0; i <= spec->limit; i++) + for (i = nb_funcs = 0; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (!odp) continue; if (is_function( odp )) typelist[nb_funcs++] = odp; } @@ -629,9 +630,9 @@ static void output_module16( DLLSPEC *spec ) output( "\n\t.balign 2\n" ); output( ".L__wine_spec_ne_restab:\n" ); output_resident_name( spec->dll_name, 0 ); - for (i = 1; i <= spec->limit; i++) + for (i = 1; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (!odp || !odp->name[0]) continue; if (odp->flags & FLAG_EXPORT32) continue; output_resident_name( odp->name, i ); @@ -729,9 +730,9 @@ static void output_module16( DLLSPEC *spec ) output( "\t.long 0x%08x,0x%08x\n", arg_types[0], arg_types[1] ); }
- for (i = 0; i <= spec->limit; i++) + for (i = 0; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (!odp || !is_function( odp )) continue; output( ".L__wine_%s_%u:\n", spec->c_name, i ); output( "\tpushw %%bp\n" ); @@ -745,9 +746,9 @@ static void output_module16( DLLSPEC *spec )
output( "\n.L__wine_spec_data_segment:\n" ); output( "\t.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n" ); /* instance data */ - for (i = 0; i <= spec->limit; i++) + for (i = 0; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (!odp || odp->type != TYPE_VARIABLE) continue; output( ".L__wine_%s_%u:\n", spec->c_name, i ); output( "\t.long " );
From: Jacek Caban jacek@codeweavers.com
--- tools/winebuild/spec32.c | 126 ++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 61 deletions(-)
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index f60afc82ec8..e7d195d3081 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -94,24 +94,24 @@ static int is_float_arg( const ORDDEF *odp, int arg ) }
/* check if dll will output relay thunks */ -static int has_relays( DLLSPEC *spec ) +static int has_relays( struct exports *exports ) { int i;
if (target.cpu == CPU_ARM64EC) return 0;
- for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (needs_relay( odp )) return 1; } return 0; }
-static int get_exports_count( DLLSPEC *spec ) +static int get_exports_count( struct exports *exports ) { - if (spec->base > spec->limit) return 0; - return spec->limit - spec->base + 1; + if (exports->base > exports->limit) return 0; + return exports->limit - exports->base + 1; }
static int cmp_func_args( const void *p1, const void *p2 ) @@ -177,17 +177,17 @@ static void output_data_directories( const char *names[16] ) /******************************************************************* * build_args_string */ -static char *build_args_string( DLLSPEC *spec ) +static char *build_args_string( struct exports *exports ) { int i, count = 0, len = 1; char *p, *buffer; char str[MAX_ARGUMENTS + 2]; ORDDEF **funcs;
- funcs = xmalloc( (spec->limit + 1 - spec->base) * sizeof(*funcs) ); - for (i = spec->base; i <= spec->limit; i++) + funcs = xmalloc( (exports->limit + 1 - exports->base) * sizeof(*funcs) ); + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i];
if (!needs_relay( odp )) continue; funcs[count++] = odp; @@ -217,7 +217,7 @@ static char *build_args_string( DLLSPEC *spec ) * * Output entry points for relay debugging */ -static void output_relay_debug( DLLSPEC *spec ) +static void output_relay_debug( struct exports *exports ) { int i;
@@ -227,9 +227,9 @@ static void output_relay_debug( DLLSPEC *spec ) output( "\t.balign 4\n" ); output( ".L__wine_spec_relay_entry_point_offsets:\n" );
- for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i];
if (needs_relay( odp )) output( "\t.long __wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i ); @@ -240,7 +240,7 @@ static void output_relay_debug( DLLSPEC *spec ) /* then the strings of argument types */
output( ".L__wine_spec_relay_args_string:\n" ); - output( "\t%s "%s"\n", get_asm_string_keyword(), build_args_string( spec )); + output( "\t%s "%s"\n", get_asm_string_keyword(), build_args_string( exports ));
/* then the relay thunks */
@@ -248,9 +248,9 @@ static void output_relay_debug( DLLSPEC *spec ) output( "__wine_spec_relay_entry_points:\n" ); output( "\tnop\n" ); /* to avoid 0 offset */
- for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i];
if (!needs_relay( odp )) continue;
@@ -269,7 +269,7 @@ static void output_relay_debug( DLLSPEC *spec ) output( "\tpushl %%ecx\n" ); output( "\tpushl %%eax\n" ); } - output( "\tpushl $%u\n", (odp->u.func.args_str_offset << 16) | (i - spec->base) ); + output( "\tpushl $%u\n", (odp->u.func.args_str_offset << 16) | (i - exports->base) ); output_cfi( ".cfi_adjust_cfa_offset 4" );
if (UsePIC) @@ -311,7 +311,7 @@ static void output_relay_debug( DLLSPEC *spec ) output( "\tpush {r4,lr}\n" ); output( "\t.seh_save_regs {r4,lr}\n" ); output( "\t.seh_endprologue\n" ); - output( "\tmovw r1,#%u\n", i - spec->base ); + output( "\tmovw r1,#%u\n", i - exports->base ); output( "\tmovt r1,#%u\n", odp->u.func.args_str_offset ); output( "\tmovw r0, :lower16:.L__wine_spec_relay_descr\n" ); output( "\tmovt r0, :upper16:.L__wine_spec_relay_descr\n" ); @@ -351,7 +351,7 @@ static void output_relay_debug( DLLSPEC *spec ) output( "\tadd x2, sp, #16\n"); output( "\tstp x8, x9, [SP,#-16]!\n" ); output( "\tmov w1, #%u\n", odp->u.func.args_str_offset << 16 ); - if (i - spec->base) output( "\tadd w1, w1, #%u\n", i - spec->base ); + if (i - exports->base) output( "\tadd w1, w1, #%u\n", i - exports->base ); output( "\tadrp x0, %s\n", arm64_page(".L__wine_spec_relay_descr") ); output( "\tadd x0, x0, #%s\n", arm64_pageoff(".L__wine_spec_relay_descr") ); output( "\tldr x3, [x0, #8]\n"); @@ -381,7 +381,7 @@ static void output_relay_debug( DLLSPEC *spec ) /* fall through */ case 0: break; } - output( "\tmovl $%u,%%edx\n", (odp->u.func.args_str_offset << 16) | (i - spec->base) ); + output( "\tmovl $%u,%%edx\n", (odp->u.func.args_str_offset << 16) | (i - exports->base) ); output( "\tleaq .L__wine_spec_relay_descr(%%rip),%%rcx\n" ); output( "\tcallq *8(%%rcx)\n" ); output( "\tret\n" ); @@ -401,10 +401,11 @@ static void output_relay_debug( DLLSPEC *spec ) */ void output_exports( DLLSPEC *spec ) { + struct exports *exports = &spec->exports; int i, fwd_size = 0; int needs_imports = 0; - int needs_relay = has_relays( spec ); - int nr_exports = get_exports_count( spec ); + int needs_relay = has_relays( exports ); + int nr_exports = get_exports_count( exports ); const char *func_ptr = is_pe() ? ".rva" : get_asm_ptr_keyword(); const char *name;
@@ -421,11 +422,11 @@ void output_exports( DLLSPEC *spec ) output( "\t.long %u\n", hash_filename(spec->file_name) ); /* TimeDateStamp */ output( "\t.long 0\n" ); /* MajorVersion/MinorVersion */ output_rva( ".L__wine_spec_exp_names" ); /* Name */ - output( "\t.long %u\n", spec->base ); /* Base */ + output( "\t.long %u\n", exports->base ); /* Base */ output( "\t.long %u\n", nr_exports ); /* NumberOfFunctions */ - output( "\t.long %u\n", spec->nb_names ); /* NumberOfNames */ + output( "\t.long %u\n", exports->nb_names ); /* NumberOfNames */ output_rva( ".L__wine_spec_exports_funcs " ); /* AddressOfFunctions */ - if (spec->nb_names) + if (exports->nb_names) { output_rva( ".L__wine_spec_exp_name_ptrs" ); /* AddressOfNames */ output_rva( ".L__wine_spec_exp_ordinals" ); /* AddressOfNameOrdinals */ @@ -439,9 +440,9 @@ void output_exports( DLLSPEC *spec ) /* output the function pointers */
output( "\n.L__wine_spec_exports_funcs:\n" ); - for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (!odp) output( "\t%s 0\n", is_pe() ? ".long" : get_asm_ptr_keyword() ); else switch(odp->type) { @@ -478,27 +479,27 @@ void output_exports( DLLSPEC *spec ) } }
- if (spec->nb_names) + if (exports->nb_names) { /* output the function name pointers */
int namepos = strlen(spec->file_name) + 1;
output( "\n.L__wine_spec_exp_name_ptrs:\n" ); - for (i = 0; i < spec->nb_names; i++) + for (i = 0; i < exports->nb_names; i++) { output_rva( ".L__wine_spec_exp_names + %u", namepos ); - namepos += strlen(spec->names[i]->name) + 1; + namepos += strlen(exports->names[i]->name) + 1; }
/* output the function ordinals */
output( "\n.L__wine_spec_exp_ordinals:\n" ); - for (i = 0; i < spec->nb_names; i++) + for (i = 0; i < exports->nb_names; i++) { - output( "\t.short %d\n", spec->names[i]->ordinal - spec->base ); + output( "\t.short %d\n", exports->names[i]->ordinal - exports->base ); } - if (spec->nb_names % 2) + if (exports->nb_names % 2) { output( "\t.short 0\n" ); } @@ -515,18 +516,18 @@ void output_exports( DLLSPEC *spec )
output( "\n.L__wine_spec_exp_names:\n" ); output( "\t%s "%s"\n", get_asm_string_keyword(), spec->file_name ); - for (i = 0; i < spec->nb_names; i++) + for (i = 0; i < exports->nb_names; i++) output( "\t%s "%s"\n", - get_asm_string_keyword(), spec->names[i]->name ); + get_asm_string_keyword(), exports->names[i]->name );
/* output forward strings */
if (fwd_size) { output( "\n.L__wine_spec_forwards:\n" ); - for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (odp && (odp->flags & FLAG_FORWARD)) output( "\t%s "%s"\n", get_asm_string_keyword(), odp->link_name ); } @@ -555,7 +556,7 @@ void output_exports( DLLSPEC *spec ) output( "\t%s .L__wine_spec_relay_entry_point_offsets\n", get_asm_ptr_keyword() ); output( "\t%s .L__wine_spec_relay_args_string\n", get_asm_ptr_keyword() );
- output_relay_debug( spec ); + output_relay_debug( exports ); } else if (!is_pe()) { @@ -568,9 +569,9 @@ void output_exports( DLLSPEC *spec )
if (!needs_imports) return; output( "\t.text\n" ); - for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (!odp) continue; if (!(odp->flags & FLAG_IMPORT)) continue;
@@ -729,7 +730,7 @@ void output_module( DLLSPEC *spec ) output( "\t.long 0\n" ); /* LoaderFlags */ output( "\t.long 16\n" ); /* NumberOfRvaAndSizes */
- if (get_exports_count( spec )) + if (get_exports_count( &spec->exports )) data_dirs[0] = ".L__wine_spec_exports"; /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ if (has_imports()) data_dirs[1] = ".L__wine_spec_imports"; /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ @@ -848,11 +849,12 @@ static unsigned int flush_output_to_section( const char *name, int dir_idx, unsi
static void output_pe_exports( DLLSPEC *spec ) { - unsigned int i, exp_count = get_exports_count( spec ); + struct exports *exports = &spec->exports; + unsigned int i, exp_count = get_exports_count( exports ); unsigned int exp_rva = current_rva() + 40; /* sizeof(IMAGE_EXPORT_DIRECTORY) */ - unsigned int pos, str_rva = exp_rva + 4 * exp_count + 6 * spec->nb_names; + unsigned int pos, str_rva = exp_rva + 4 * exp_count + 6 * exports->nb_names;
- if (!spec->nb_entry_points) return; + if (!exports->nb_entry_points) return;
init_output_buffer(); put_dword( 0 ); /* Characteristics */ @@ -860,14 +862,14 @@ static void output_pe_exports( DLLSPEC *spec ) put_word( 0 ); /* MajorVersion */ put_word( 0 ); /* MinorVersion */ put_dword( str_rva ); /* Name */ - put_dword( spec->base ); /* Base */ + put_dword( exports->base ); /* Base */ put_dword( exp_count ); /* NumberOfFunctions */ - put_dword( spec->nb_names ); /* NumberOfNames */ + put_dword( exports->nb_names ); /* NumberOfNames */ put_dword( exp_rva ); /* AddressOfFunctions */ - if (spec->nb_names) + if (exports->nb_names) { put_dword( exp_rva + 4 * exp_count ); /* AddressOfNames */ - put_dword( exp_rva + 4 * exp_count + 4 * spec->nb_names ); /* AddressOfNameOrdinals */ + put_dword( exp_rva + 4 * exp_count + 4 * exports->nb_names ); /* AddressOfNameOrdinals */ } else { @@ -876,11 +878,11 @@ static void output_pe_exports( DLLSPEC *spec ) }
/* functions */ - for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < spec->nb_names; i++) - pos += strlen( spec->names[i]->name ) + 1; - for (i = spec->base; i <= spec->limit; i++) + for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < exports->nb_names; i++) + pos += strlen( exports->names[i]->name ) + 1; + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (odp && (odp->flags & FLAG_FORWARD)) { put_dword( pos ); @@ -890,23 +892,23 @@ static void output_pe_exports( DLLSPEC *spec ) }
/* names */ - for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < spec->nb_names; i++) + for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < exports->nb_names; i++) { put_dword( pos ); - pos += strlen(spec->names[i]->name) + 1; + pos += strlen(exports->names[i]->name) + 1; }
/* ordinals */ - for (i = 0; i < spec->nb_names; i++) put_word( spec->names[i]->ordinal - spec->base ); + for (i = 0; i < exports->nb_names; i++) put_word( exports->names[i]->ordinal - exports->base );
/* strings */ put_data( spec->file_name, strlen(spec->file_name) + 1 ); - for (i = 0; i < spec->nb_names; i++) - put_data( spec->names[i]->name, strlen(spec->names[i]->name) + 1 ); + for (i = 0; i < exports->nb_names; i++) + put_data( exports->names[i]->name, strlen(exports->names[i]->name) + 1 );
- for (i = spec->base; i <= spec->limit; i++) + for (i = exports->base; i <= exports->limit; i++) { - ORDDEF *odp = spec->ordinals[i]; + ORDDEF *odp = exports->ordinals[i]; if (odp && (odp->flags & FLAG_FORWARD)) put_data( odp->link_name, strlen(odp->link_name) + 1 ); }
@@ -1276,6 +1278,7 @@ void output_data_module( DLLSPEC *spec ) */ void output_def_file( DLLSPEC *spec, int import_only ) { + struct exports *exports; DLLSPEC *spec32 = NULL; const char *name; int i, total; @@ -1286,6 +1289,7 @@ void output_def_file( DLLSPEC *spec, int import_only ) add_16bit_exports( spec32, spec ); spec = spec32; } + exports = &spec->exports;
if (spec_file_name) output( "; File generated automatically from %s; do not edit!\n\n", @@ -1298,9 +1302,9 @@ void output_def_file( DLLSPEC *spec, int import_only )
/* Output the exports and relay entry points */
- for (i = total = 0; i < spec->nb_entry_points; i++) + for (i = total = 0; i < exports->nb_entry_points; i++) { - const ORDDEF *odp = &spec->entry_points[i]; + const ORDDEF *odp = exports->entry_points[i]; int is_data = 0, is_private = odp->flags & FLAG_PRIVATE;
if (odp->name) name = odp->name;
From: Jacek Caban jacek@codeweavers.com
--- tools/winebuild/build.h | 3 -- tools/winebuild/parser.c | 61 ++++++++++++++++++---------------------- tools/winebuild/utils.c | 1 - 3 files changed, 28 insertions(+), 37 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index ec463792eef..281c450ea9a 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -149,8 +149,6 @@ typedef struct char *init_func; /* initialization routine */ char *main_module; /* main Win32 module for Win16 specs */ SPEC_TYPE type; /* type of dll (Win16/Win32) */ - int base; /* ordinal base */ - int limit; /* ordinal limit */ int stack_size; /* exe stack size */ int heap_size; /* exe heap size */ int nb_entry_points; /* number of used entry points */ @@ -165,7 +163,6 @@ typedef struct int unicode_app; /* default to unicode entry point */ ORDDEF *entry_points; /* spec entry points */ ORDDEF **names; /* array of entry point names (points into entry_points) */ - ORDDEF **ordinals; /* array of dll ordinals (points into entry_points) */ struct exports exports; /* dll exports */ struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */ struct apiset apiset; /* list of defined api sets */ diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 01c230a0a2c..c8b970ea59f 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -648,8 +648,6 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) error( "Ordinal number %d too large\n", ordinal ); goto error; } - if (ordinal > spec->limit) spec->limit = ordinal; - if (ordinal < spec->base) spec->base = ordinal; odp->ordinal = ordinal; }
@@ -898,57 +896,57 @@ static void assign_names( DLLSPEC *spec ) * * Build the ordinal array. */ -static void assign_ordinals( DLLSPEC *spec ) +static void assign_ordinals( struct exports *exports ) { int i, count, ordinal;
/* start assigning from base, or from 1 if no ordinal defined yet */
- spec->base = MAX_ORDINALS; - spec->limit = 0; - for (i = 0; i < spec->nb_entry_points; i++) + exports->base = MAX_ORDINALS; + exports->limit = 0; + for (i = 0; i < exports->nb_entry_points; i++) { - ordinal = spec->entry_points[i].ordinal; + ordinal = exports->entry_points[i]->ordinal; if (ordinal == -1) continue; - if (ordinal > spec->limit) spec->limit = ordinal; - if (ordinal < spec->base) spec->base = ordinal; + if (ordinal > exports->limit) exports->limit = ordinal; + if (ordinal < exports->base) exports->base = ordinal; } - if (spec->base == MAX_ORDINALS) spec->base = 1; - if (spec->limit < spec->base) spec->limit = spec->base; + if (exports->base == MAX_ORDINALS) exports->base = 1; + if (exports->limit < exports->base) exports->limit = exports->base;
- count = max( spec->limit + 1, spec->base + spec->nb_entry_points ); - spec->ordinals = xmalloc( count * sizeof(spec->ordinals[0]) ); - memset( spec->ordinals, 0, count * sizeof(spec->ordinals[0]) ); + count = max( exports->limit + 1, exports->base + exports->nb_entry_points ); + exports->ordinals = xmalloc( count * sizeof(exports->ordinals[0]) ); + memset( exports->ordinals, 0, count * sizeof(exports->ordinals[0]) );
/* fill in all explicitly specified ordinals */ - for (i = 0; i < spec->nb_entry_points; i++) + for (i = 0; i < exports->nb_entry_points; i++) { - ordinal = spec->entry_points[i].ordinal; + ordinal = exports->entry_points[i]->ordinal; if (ordinal == -1) continue; - if (spec->ordinals[ordinal]) + if (exports->ordinals[ordinal]) { - current_line = max( spec->entry_points[i].lineno, spec->ordinals[ordinal]->lineno ); + current_line = max( exports->entry_points[i]->lineno, exports->ordinals[ordinal]->lineno ); error( "ordinal %d redefined\n%s:%d: First defined here\n", ordinal, input_file_name, - min( spec->entry_points[i].lineno, spec->ordinals[ordinal]->lineno ) ); + min( exports->entry_points[i]->lineno, exports->ordinals[ordinal]->lineno ) ); } - else spec->ordinals[ordinal] = &spec->entry_points[i]; + else exports->ordinals[ordinal] = exports->entry_points[i]; }
/* now assign ordinals to the rest */ - for (i = 0, ordinal = spec->base; i < spec->nb_entry_points; i++) + for (i = 0, ordinal = exports->base; i < exports->nb_entry_points; i++) { - if (spec->entry_points[i].ordinal != -1) continue; - while (spec->ordinals[ordinal]) ordinal++; + if (exports->entry_points[i]->ordinal != -1) continue; + while (exports->ordinals[ordinal]) ordinal++; if (ordinal >= MAX_ORDINALS) { - current_line = spec->entry_points[i].lineno; + current_line = exports->entry_points[i]->lineno; fatal_error( "Too many functions defined (max %d)\n", MAX_ORDINALS ); } - spec->entry_points[i].ordinal = ordinal; - spec->ordinals[ordinal] = &spec->entry_points[i]; + exports->entry_points[i]->ordinal = ordinal; + exports->ordinals[ordinal] = exports->entry_points[i]; } - if (ordinal > spec->limit) spec->limit = ordinal; + if (ordinal > exports->limit) exports->limit = ordinal; }
@@ -965,13 +963,10 @@ static void assign_exports( DLLSPEC *spec ) }
assign_names( spec ); - assign_ordinals( spec ); + assign_ordinals( exports );
exports->nb_names = spec->nb_names; exports->names = spec->names; - exports->base = spec->base; - exports->limit = spec->limit; - exports->ordinals = spec->ordinals; }
@@ -1012,9 +1007,9 @@ void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 )
/* add the explicit win32 exports */
- for (i = 1; i <= spec16->limit; i++) + for (i = 1; i <= spec16->exports.limit; i++) { - ORDDEF *odp16 = spec16->ordinals[i]; + ORDDEF *odp16 = spec16->exports.ordinals[i];
if (!odp16 || !odp16->name) continue; if (!(odp16->flags & FLAG_EXPORT32)) continue; diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 337db77bcaf..258a644b494 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -609,7 +609,6 @@ DLLSPEC *alloc_dll_spec(void) spec = xmalloc( sizeof(*spec) ); memset( spec, 0, sizeof(*spec) ); spec->type = SPEC_WIN32; - spec->base = MAX_ORDINALS; spec->characteristics = IMAGE_FILE_EXECUTABLE_IMAGE; spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; spec->subsystem_major = 4;
From: Jacek Caban jacek@codeweavers.com
--- tools/winebuild/build.h | 2 -- tools/winebuild/parser.c | 37 +++++++++++++++++-------------------- 2 files changed, 17 insertions(+), 22 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 281c450ea9a..50559e7c98c 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -153,7 +153,6 @@ typedef struct int heap_size; /* exe heap size */ int nb_entry_points; /* number of used entry points */ int alloc_entry_points; /* number of allocated entry points */ - int nb_names; /* number of entry points with names */ unsigned int nb_resources; /* number of resources */ int characteristics; /* characteristics for the PE header */ int dll_characteristics;/* DLL characteristics for the PE header */ @@ -162,7 +161,6 @@ typedef struct int subsystem_minor; /* subsystem version minor number */ int unicode_app; /* default to unicode entry point */ ORDDEF *entry_points; /* spec entry points */ - ORDDEF **names; /* array of entry point names (points into entry_points) */ struct exports exports; /* dll exports */ struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */ struct apiset apiset; /* list of defined api sets */ diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index c8b970ea59f..a8e5eb1d09b 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -843,24 +843,24 @@ static int name_compare( const void *ptr1, const void *ptr2 ) * * Build the name array and catch duplicates. */ -static void assign_names( DLLSPEC *spec ) +static void assign_names( struct exports *exports ) { int i, j, nb_exp_names = 0; ORDDEF **all_names;
- spec->nb_names = 0; - for (i = 0; i < spec->nb_entry_points; i++) - if (spec->entry_points[i].name) spec->nb_names++; - else if (spec->entry_points[i].export_name) nb_exp_names++; + exports->nb_names = 0; + for (i = 0; i < exports->nb_entry_points; i++) + if (exports->entry_points[i]->name) exports->nb_names++; + else if (exports->entry_points[i]->export_name) nb_exp_names++;
- if (!spec->nb_names && !nb_exp_names) return; + if (!exports->nb_names && !nb_exp_names) return;
/* check for duplicates */
- all_names = xmalloc( (spec->nb_names + nb_exp_names) * sizeof(all_names[0]) ); - for (i = j = 0; i < spec->nb_entry_points; i++) - if (spec->entry_points[i].name || spec->entry_points[i].export_name) - all_names[j++] = &spec->entry_points[i]; + all_names = xmalloc( (exports->nb_names + nb_exp_names) * sizeof(all_names[0]) ); + for (i = j = 0; i < exports->nb_entry_points; i++) + if (exports->entry_points[i]->name || exports->entry_points[i]->export_name) + all_names[j++] = exports->entry_points[i];
qsort( all_names, j, sizeof(all_names[0]), name_compare );
@@ -879,15 +879,15 @@ static void assign_names( DLLSPEC *spec ) } free( all_names );
- if (spec->nb_names) + if (exports->nb_names) { - spec->names = xmalloc( spec->nb_names * sizeof(spec->names[0]) ); - for (i = j = 0; i < spec->nb_entry_points; i++) - if (spec->entry_points[i].name) spec->names[j++] = &spec->entry_points[i]; + exports->names = xmalloc( exports->nb_names * sizeof(exports->names[0]) ); + for (i = j = 0; i < exports->nb_entry_points; i++) + if (exports->entry_points[i]->name) exports->names[j++] = exports->entry_points[i];
/* sort the list of names */ - qsort( spec->names, spec->nb_names, sizeof(spec->names[0]), name_compare ); - for (i = 0; i < spec->nb_names; i++) spec->names[i]->hint = i; + qsort( exports->names, exports->nb_names, sizeof(exports->names[0]), name_compare ); + for (i = 0; i < exports->nb_names; i++) exports->names[i]->hint = i; } }
@@ -962,11 +962,8 @@ static void assign_exports( DLLSPEC *spec ) exports->entry_points[exports->nb_entry_points++] = entry; }
- assign_names( spec ); + assign_names( exports ); assign_ordinals( exports ); - - exports->nb_names = spec->nb_names; - exports->names = spec->names; }
From: Jacek Caban jacek@codeweavers.com
--- tools/winebuild/parser.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index a8e5eb1d09b..5bd05e97ca9 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -623,13 +623,6 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) assert( 0 ); }
- if ((odp->flags & FLAG_CPU_MASK) && !(odp->flags & FLAG_CPU(target.cpu))) - { - /* ignore this entry point */ - spec->nb_entry_points--; - return 1; - } - if (data_only && !(odp->flags & FLAG_FORWARD)) { error( "Only forwarded entry points are allowed in data-only mode\n" ); @@ -959,6 +952,8 @@ static void assign_exports( DLLSPEC *spec ) for (i = 0; i < spec->nb_entry_points; i++) { ORDDEF *entry = &spec->entry_points[i]; + if ((entry->flags & FLAG_CPU_MASK) && !(entry->flags & FLAG_CPU(target.cpu))) + continue; exports->entry_points[exports->nb_entry_points++] = entry; }