Commit 94588343 authored by Alexandre Julliard's avatar Alexandre Julliard

winebuild: Add a helper to output an asm function header.

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