winebuild: Use exports struct for exports handling.
This commit is contained in:
parent
6ee0583546
commit
f5ed0de392
1 changed files with 65 additions and 61 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue