winebuild: Add a helper to output an asm function header.
This commit is contained in:
parent
3bb752736c
commit
945883438a
5 changed files with 33 additions and 66 deletions
|
@ -288,7 +288,6 @@ extern unsigned int get_alignment(unsigned int align);
|
|||
extern unsigned int get_page_size(void);
|
||||
extern unsigned int get_args_size( const ORDDEF *odp );
|
||||
extern const char *asm_name( const char *func );
|
||||
extern const char *func_declaration( const char *func );
|
||||
extern const char *asm_globl( const char *func );
|
||||
extern const char *get_asm_ptr_keyword(void);
|
||||
extern const char *get_asm_string_keyword(void);
|
||||
|
@ -298,6 +297,7 @@ extern const char *get_asm_rsrc_section(void);
|
|||
extern const char *get_asm_string_section(void);
|
||||
extern const char *arm64_page( const char *sym );
|
||||
extern const char *arm64_pageoff( const char *sym );
|
||||
extern void output_function_header( const char *func, int global );
|
||||
extern void output_function_size( const char *name );
|
||||
extern void output_gnu_stack_note(void);
|
||||
|
||||
|
|
|
@ -752,10 +752,7 @@ int is_undefined( const char *name )
|
|||
void output_get_pc_thunk(void)
|
||||
{
|
||||
assert( target.cpu == CPU_i386 );
|
||||
output( "\n\t.text\n" );
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( "\t%s\n", func_declaration("__wine_spec_get_pc_thunk_eax") );
|
||||
output( "%s:\n", asm_name("__wine_spec_get_pc_thunk_eax") );
|
||||
output_function_header( "__wine_spec_get_pc_thunk_eax", 0 );
|
||||
output( "\tmovl (%%esp),%%eax\n" );
|
||||
output( "\tret\n" );
|
||||
output_function_size( "__wine_spec_get_pc_thunk_eax" );
|
||||
|
@ -764,9 +761,7 @@ void output_get_pc_thunk(void)
|
|||
/* output a single import thunk */
|
||||
static void output_import_thunk( const char *name, const char *table, int pos )
|
||||
{
|
||||
output( "\n\t.align %d\n", get_alignment(4) );
|
||||
output( "\t%s\n", func_declaration(name) );
|
||||
output( "%s\n", asm_globl(name) );
|
||||
output_function_header( name, 1 );
|
||||
|
||||
switch (target.cpu)
|
||||
{
|
||||
|
@ -1030,9 +1025,7 @@ static void output_delayed_import_thunks( const DLLSPEC *spec )
|
|||
LIST_FOR_EACH_ENTRY( import, &dll_delayed, struct import, entry )
|
||||
{
|
||||
char *module_func = strmake( "__wine_delay_load_asm_%s", import->c_name );
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( "\t%s\n", func_declaration(module_func) );
|
||||
output( "%s:\n", asm_name(module_func) );
|
||||
output_function_header( module_func, 0 );
|
||||
output_cfi( ".cfi_startproc" );
|
||||
switch (target.cpu)
|
||||
{
|
||||
|
@ -1249,7 +1242,6 @@ void output_stubs( DLLSPEC *spec )
|
|||
if (!has_stubs( spec )) return;
|
||||
|
||||
output( "\n/* stub functions */\n\n" );
|
||||
output( "\t.text\n" );
|
||||
|
||||
for (i = 0; i < spec->nb_entry_points; i++)
|
||||
{
|
||||
|
@ -1258,9 +1250,7 @@ void output_stubs( DLLSPEC *spec )
|
|||
|
||||
name = get_stub_name( odp, spec );
|
||||
exp_name = odp->name ? odp->name : odp->export_name;
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( "\t%s\n", func_declaration(name) );
|
||||
output( "%s:\n", asm_name(name) );
|
||||
output_function_header( name, 0 );
|
||||
|
||||
switch (target.cpu)
|
||||
{
|
||||
|
@ -1413,7 +1403,6 @@ void output_syscalls( DLLSPEC *spec )
|
|||
count = sort_func_list( syscalls, count, cmp_link_name );
|
||||
|
||||
output( "\n/* system calls */\n\n" );
|
||||
output( "\t.text\n" );
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -1421,9 +1410,7 @@ void output_syscalls( DLLSPEC *spec )
|
|||
const char *name = get_link_name(odp);
|
||||
unsigned int id = (spec->syscall_table << 12) + i;
|
||||
|
||||
output( "\t.align %d\n", get_alignment(16) );
|
||||
output( "\t%s\n", func_declaration(name) );
|
||||
output( "%s\n", asm_globl(name) );
|
||||
output_function_header( name, 1 );
|
||||
switch (target.cpu)
|
||||
{
|
||||
case CPU_i386:
|
||||
|
@ -1501,16 +1488,12 @@ void output_syscalls( DLLSPEC *spec )
|
|||
{
|
||||
case CPU_i386:
|
||||
if (UsePIC) break;
|
||||
output( "\t.align %d\n", get_alignment(16) );
|
||||
output( "\t%s\n", func_declaration("__wine_syscall") );
|
||||
output( "%s:\n", asm_name("__wine_syscall") );
|
||||
output_function_header( "__wine_syscall", 0 );
|
||||
output( "\tjmp *(%s)\n", asm_name("__wine_syscall_dispatcher") );
|
||||
output_function_size( "__wine_syscall" );
|
||||
break;
|
||||
case CPU_ARM:
|
||||
output( "\t.align %d\n", get_alignment(16) );
|
||||
output( "\t%s\n", func_declaration("__wine_syscall") );
|
||||
output( "%s:\n", asm_name("__wine_syscall") );
|
||||
output_function_header( "__wine_syscall", 0 );
|
||||
if (UsePIC)
|
||||
{
|
||||
output( "\tldr r0, 2f\n");
|
||||
|
@ -1675,10 +1658,7 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
|
|||
|
||||
if (is_delay)
|
||||
{
|
||||
output( "\n\t.text\n" );
|
||||
output( "\t.align %d\n", get_alignment( get_ptr_size() ));
|
||||
output( "%s\n", asm_globl( delay_load ) );
|
||||
output( "\t%s\n", func_declaration( delay_load ) );
|
||||
output_function_header( delay_load, 1 );
|
||||
|
||||
switch (target.cpu)
|
||||
{
|
||||
|
@ -1848,11 +1828,7 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
|
|||
asm_name( abi_name ) );
|
||||
|
||||
new_output_as_file();
|
||||
|
||||
output( "\n\t.text\n" );
|
||||
output( "\t.align %d\n", get_alignment( get_ptr_size() ) );
|
||||
output( "%s\n", asm_globl( abi_name ) );
|
||||
output( "\t%s\n", func_declaration( abi_name ) );
|
||||
output_function_header( abi_name, 1 );
|
||||
|
||||
switch (target.cpu)
|
||||
{
|
||||
|
@ -1977,10 +1953,7 @@ static void build_unix_import_lib( DLLSPEC *spec, struct strarray files )
|
|||
case TYPE_STDCALL:
|
||||
prefix = (!odp->name || (odp->flags & FLAG_ORDINAL)) ? import_ord_prefix : import_func_prefix;
|
||||
new_output_as_file();
|
||||
output( "\t.text\n" );
|
||||
output( "\n\t.align %d\n", get_alignment( get_ptr_size() ));
|
||||
output( "\t%s\n", func_declaration( name ) );
|
||||
output( "%s\n", asm_globl( name ) );
|
||||
output_function_header( name, 1 );
|
||||
output( "\t%s %s%s$%u$%s\n", get_asm_ptr_keyword(),
|
||||
asm_name( prefix ), dll_name, odp->ordinal, name );
|
||||
output_function_size( name );
|
||||
|
|
|
@ -36,14 +36,6 @@
|
|||
#define GS_OFFSET 0x1d8 /* FIELD_OFFSET(TEB,SystemReserved2) + FIELD_OFFSET(struct x86_thread_data,gs) */
|
||||
|
||||
|
||||
static void function_header( const char *name )
|
||||
{
|
||||
output( "\n\t.align %d\n", get_alignment(4) );
|
||||
output( "\t%s\n", func_declaration(name) );
|
||||
output( "%s\n", asm_globl(name) );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* BuildCallFrom16Core
|
||||
*
|
||||
|
@ -114,9 +106,9 @@ static void function_header( const char *name )
|
|||
static void BuildCallFrom16Core( int reg_func, int thunk )
|
||||
{
|
||||
/* Function header */
|
||||
if (thunk) function_header( "__wine_call_from_16_thunk" );
|
||||
else if (reg_func) function_header( "__wine_call_from_16_regs" );
|
||||
else function_header( "__wine_call_from_16" );
|
||||
if (thunk) output_function_header( "__wine_call_from_16_thunk", 1 );
|
||||
else if (reg_func) output_function_header( "__wine_call_from_16_regs", 1 );
|
||||
else output_function_header( "__wine_call_from_16", 1 );
|
||||
|
||||
/* Create STACK16FRAME (except STACK32FRAME link) */
|
||||
output( "\tpushw %%gs\n" );
|
||||
|
@ -381,7 +373,7 @@ static void BuildCallTo16Core( int reg_func )
|
|||
const char *func_name = is_pe() ? strmake( "%s@12", name ) : name;
|
||||
|
||||
/* Function header */
|
||||
function_header( func_name );
|
||||
output_function_header( func_name, 1 );
|
||||
|
||||
/* Function entry sequence */
|
||||
output_cfi( ".cfi_startproc" );
|
||||
|
@ -533,7 +525,7 @@ static void BuildCallTo16Core( int reg_func )
|
|||
*/
|
||||
static void BuildRet16Func(void)
|
||||
{
|
||||
function_header( "__wine_call_to_16_ret" );
|
||||
output_function_header( "__wine_call_to_16_ret", 1 );
|
||||
|
||||
/* Save %esp into %esi */
|
||||
output( "\tmovl %%esp,%%esi\n" );
|
||||
|
|
|
@ -338,9 +338,7 @@ static void output_call16_function( ORDDEF *odp )
|
|||
|
||||
name = strmake( ".L__wine_spec_call16_%s", get_relay_name(odp) );
|
||||
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( "\t%s\n", func_declaration(name) );
|
||||
output( "%s:\n", name );
|
||||
output_function_header( name, 0 );
|
||||
output_cfi( ".cfi_startproc" );
|
||||
output( "\tpushl %%ebp\n" );
|
||||
output_cfi( ".cfi_adjust_cfa_offset 4" );
|
||||
|
|
|
@ -876,38 +876,42 @@ const char *asm_name( const char *sym )
|
|||
}
|
||||
|
||||
/* return an assembly function declaration for a C function name */
|
||||
const char *func_declaration( const char *func )
|
||||
void output_function_header( const char *func, int global )
|
||||
{
|
||||
static char *buffer;
|
||||
const char *name = asm_name( func );
|
||||
|
||||
output( "\t.text\n" );
|
||||
|
||||
switch (target.platform)
|
||||
{
|
||||
case PLATFORM_APPLE:
|
||||
return "";
|
||||
if (global) output( "\t.globl %s\n\t.private_extern %s\n", name, name );
|
||||
break;
|
||||
case PLATFORM_MINGW:
|
||||
case PLATFORM_WINDOWS:
|
||||
free( buffer );
|
||||
buffer = strmake( ".def %s\n\t.scl 2\n\t.type 32\n\t.endef%s", asm_name(func),
|
||||
thumb_mode ? "\n\t.thumb_func" : "" );
|
||||
output( "\t.def %s\n\t.scl 2\n\t.type 32\n\t.endef\n", name );
|
||||
if (global) output( "\t.globl %s\n", name );
|
||||
if (thumb_mode) output( "\t.thumb_func\n" );
|
||||
break;
|
||||
default:
|
||||
free( buffer );
|
||||
switch (target.cpu)
|
||||
{
|
||||
case CPU_ARM:
|
||||
buffer = strmake( ".type %s,%%function%s", func,
|
||||
thumb_mode ? "\n\t.thumb_func" : "" );
|
||||
output( "\t.type %s,%%function\n", name );
|
||||
if (thumb_mode) output( "\t.thumb_func\n" );
|
||||
break;
|
||||
case CPU_ARM64:
|
||||
buffer = strmake( ".type %s,%%function", func );
|
||||
output( "\t.type %s,%%function\n", name );
|
||||
break;
|
||||
default:
|
||||
buffer = strmake( ".type %s,@function", func );
|
||||
output( "\t.type %s,@function\n", name );
|
||||
break;
|
||||
}
|
||||
if (global) output( "\t.globl %s\n\t.hidden %s\n", name, name );
|
||||
break;
|
||||
}
|
||||
return buffer;
|
||||
output( "\t.align %u\n", get_alignment(4) );
|
||||
output( "%s:\n", name );
|
||||
}
|
||||
|
||||
/* output a size declaration for an assembly function */
|
||||
|
|
Loading…
Add table
Reference in a new issue