winebuild: Add .seh annotations on ARM.

This commit is contained in:
Alexandre Julliard 2024-02-05 21:08:28 +01:00
parent e25b1ab7e9
commit 7c7544aba1
2 changed files with 32 additions and 18 deletions

View file

@ -1256,6 +1256,8 @@ void output_stubs( DLLSPEC *spec )
output_seh( ".seh_endproc" );
break;
case CPU_ARM:
output( "\t.seh_proc %s\n", asm_name(name) );
output( "\t.seh_endprologue\n" );
output( "\tmovw r0,:lower16:.L__wine_spec_file_name\n");
output( "\tmovt r0,:upper16:.L__wine_spec_file_name\n");
if (exp_name)
@ -1264,12 +1266,13 @@ void output_stubs( DLLSPEC *spec )
output( "\tmovt r1,:upper16:.L%s_string\n", name );
}
else output( "\tmov r1,#%u\n", odp->ordinal );
output( "\tbl %s\n", asm_name("__wine_spec_unimplemented_stub") );
output( "\tb %s\n", asm_name("__wine_spec_unimplemented_stub") );
output( "\t.seh_endproc\n" );
break;
case CPU_ARM64:
case CPU_ARM64EC:
output_seh( ".seh_proc %s", arm64_name(name) );
output_seh( ".seh_endprologue" );
output( "\t.seh_proc %s\n", arm64_name(name) );
output( "\t.seh_endprologue\n" );
output( "\tadrp x0, %s\n", arm64_page(".L__wine_spec_file_name") );
output( "\tadd x0, x0, #%s\n", arm64_pageoff(".L__wine_spec_file_name") );
if (exp_name)
@ -1282,7 +1285,7 @@ void output_stubs( DLLSPEC *spec )
else
output( "\tmov x1, %u\n", odp->ordinal );
output( "\tb %s\n", arm64_name("__wine_spec_unimplemented_stub") );
output_seh( ".seh_endproc" );
output( "\t.seh_endproc\n" );
break;
}
output_function_size( name );
@ -1501,7 +1504,10 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
output_seh( ".seh_endproc" );
break;
case CPU_ARM:
output( "\t.seh_proc %s\n", asm_name( delay_load ) );
output( "\tpush {r0-r3, FP, LR}\n" );
output( "\t.seh_save_regs {r0-r3,fp,lr}\n" );
output( "\t.seh_endprologue\n" );
output( "\tmov r1, IP\n" );
output( "\tldr r0, 1f\n" );
output( "\tldr r0, [r0]\n" );
@ -1510,14 +1516,15 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
output( "\tpop {r0-r3, FP, LR}\n" );
output( "\tbx IP\n" );
output( "1:\t.long %s\n", asm_name( import_desc ) );
output( "\t.seh_endproc\n" );
break;
case CPU_ARM64:
output_seh( ".seh_proc %s", asm_name( delay_load ) );
output( "\t.seh_proc %s\n", asm_name( delay_load ) );
output( "\tstp x29, x30, [sp, #-80]!\n" );
output_seh( ".seh_save_fplr_x 80" );
output( "\t.seh_save_fplr_x 80\n" );
output( "\tmov x29, sp\n" );
output_seh( ".seh_set_fp" );
output_seh( ".seh_endprologue" );
output( "\t.seh_set_fp\n" );
output( "\t.seh_endprologue\n" );
output( "\tstp x0, x1, [sp, #16]\n" );
output( "\tstp x2, x3, [sp, #32]\n" );
output( "\tstp x4, x5, [sp, #48]\n" );
@ -1533,7 +1540,7 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
output( "\tldp x6, x7, [sp, #64]\n" );
output( "\tldp x29, x30, [sp], #80\n" );
output( "\tbr x16\n" );
output_seh( ".seh_endproc" );
output( "\t.seh_endproc\n" );
break;
case CPU_ARM64EC:
assert( 0 );

View file

@ -300,11 +300,17 @@ static void output_relay_debug( DLLSPEC *spec )
output( "\t.balign 4\n" );
output( "__wine_spec_relay_entry_point_%d:\n", i );
output( "\t.seh_proc __wine_spec_relay_entry_point_%d\n", i );
output( "\tpush {r0-r3}\n" );
output( "\tmov r2, SP\n");
if (has_float) output( "\tvpush {s0-s15}\n" );
output( "\tpush {LR}\n" );
output( "\tsub SP, #4\n");
output( "\t.seh_save_regs {r0-r3}\n" );
if (has_float)
{
output( "\tvpush {d0-d7}\n" );
output( "\t.seh_save_fregs {d0-d7}\n" );
}
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( "\tmovt r1,#%u\n", odp->u.func.args_str_offset );
output( "\tmovw r0, :lower16:.L__wine_spec_relay_descr\n" );
@ -314,6 +320,7 @@ static void output_relay_debug( DLLSPEC *spec )
output( "\tldr IP, [SP, #4]\n" );
output( "\tadd SP, #%u\n", 24 + (has_float ? 64 : 0) );
output( "\tbx IP\n");
output( "\t.seh_endproc\n" );
break;
}
@ -323,12 +330,12 @@ static void output_relay_debug( DLLSPEC *spec )
output( "\t.balign 4\n" );
output( "__wine_spec_relay_entry_point_%d:\n", i );
output_seh( ".seh_proc __wine_spec_relay_entry_point_%d", i );
output( "\t.seh_proc __wine_spec_relay_entry_point_%d\n", i );
output( "\tstp x29, x30, [sp, #-%u]!\n", stack_size + 16 );
output_seh( ".seh_save_fplr_x %u", stack_size + 16 );
output( "\t.seh_save_fplr_x %u\n", stack_size + 16 );
output( "\tmov x29, sp\n" );
output_seh( ".seh_set_fp" );
output_seh( ".seh_endprologue" );
output( "\t.seh_set_fp\n" );
output( "\t.seh_endprologue\n" );
switch (stack_size)
{
case 64: output( "\tstp x6, x7, [sp, #64]\n" );
@ -352,7 +359,7 @@ static void output_relay_debug( DLLSPEC *spec )
output( "\tmov sp, x29\n" );
output( "\tldp x29, x30, [sp], #%u\n", stack_size + 16 );
output( "\tret\n");
output_seh( ".seh_endproc" );
output( "\t.seh_endproc\n" );
break;
}