winebuild: Use exports struct for exports handling.

This commit is contained in:
Jacek Caban 2024-02-14 01:26:03 +01:00 committed by Alexandre Julliard
parent 6ee0583546
commit f5ed0de392

View file

@ -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;