diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 718ce4666ef..f06c40ca9b1 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -411,6 +411,48 @@ void output_exports( DLLSPEC *spec ) if (!nr_exports) return; + /* ARM64EC exports are more tricky than other targets. For functions implemented in ARM64EC, + * linker generates x86_64 thunk and relevant metadata. Use .drectve section to pass export + * directives to the linker. */ + if (target.cpu == CPU_ARM64EC) + { + output( "\t.section .drectve\n" ); + for (i = exports->base; i <= exports->limit; i++) + { + ORDDEF *odp = exports->ordinals[i]; + const char *symbol; + + if (!odp) continue; + + switch (odp->type) + { + case TYPE_EXTERN: + case TYPE_STDCALL: + case TYPE_VARARGS: + case TYPE_CDECL: + if (odp->flags & FLAG_FORWARD) + symbol = odp->link_name; + else if (odp->flags & FLAG_EXT_LINK) + symbol = strmake( "%s_%s", asm_name("__wine_spec_ext_link"), odp->link_name ); + else + symbol = asm_name( get_link_name( odp )); + break; + case TYPE_STUB: + symbol = asm_name( get_stub_name( odp, spec )); + break; + default: + assert( 0 ); + } + + output( "\t.ascii \" -export:%s=%s,@%u%s%s\"\n", + odp->name ? odp->name : strmake( "_noname%u", i ), + symbol, i, + odp->name ? "" : ",NONAME", + odp->type == TYPE_EXTERN ? ",DATA" : "" ); + } + return; + } + output( "\n/* export table */\n\n" ); output( "\t%s\n", get_asm_export_section() ); output( "\t.balign 4\n" );