The .seh_scope directive was removed a little over a decade ago due to being too Microsoft specific. This has proven to be a mistake as there is now no easy way for reusable inline assembly to express Structured Exception Handling scopes for Microsoft Windows targets. This patch reimplements a simpler version of .seh_scope, with the proper semantics in place \ From cc9e143f8feb933ca8fc4b12deaab2985893b714 Mon Sep 17 00:00:00 2001 From: TheShermanTanker Date: Sun, 2 Jul 2023 16:22:18 +0800 Subject: [PATCH] Reimplement .seh_scope --- gas/config/obj-coff-seh.c | 26 ++++++++++++++++++++++++-- gas/config/obj-coff-seh.h | 5 ++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/gas/config/obj-coff-seh.c b/gas/config/obj-coff-seh.c index 7b4486a..b01a207 100644 --- a/gas/config/obj-coff-seh.c +++ b/gas/config/obj-coff-seh.c @@ -30,6 +32,7 @@ struct seh_seg_list { /* Local data. */ static seh_context *seh_ctx_cur = NULL; +static unsigned int scope = 0; static htab_t seh_hash; @@ -385,7 +388,21 @@ obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED) return; demand_empty_rest_of_line (); - switch_xdata (seh_ctx_cur->subsection + 1, seh_ctx_cur->code_seg); + switch_xdata (seh_ctx_cur->subsection + (scope == 0) ? 1 : 2, seh_ctx_cur->code_seg); +} + +static void obj_coff_seh_scope (int what) +{ + if (!verify_context_and_target (".seh_scope", seh_kind_x64)) + return; + + segT seg = now_seg; + int subseg = now_subseg; + + scope++; + switch_xdata (seh_ctx_cur->subsection + 2, seh_ctx_cur->code_seg); + s_rva (4); + subseg_set(seg, subseg); } /* Mark end of current context. */ @@ -442,7 +459,7 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED) { x_segcur = seh_hash_find_or_make (seh_ctx_cur->code_seg, ".xdata"); seh_ctx_cur->subsection = x_segcur->subseg; - x_segcur->subseg += 2; + x_segcur->subseg += 3; } SKIP_WHITESPACE (); @@ -918,6 +935,11 @@ write_function_xdata (seh_context *c) seh_x64_write_function_xdata (c); + if (scope > 0) { + switch_xdata (c->subsection + 1, c->code_seg); + out_four (scope); + } + subseg_set (save_seg, save_subseg); } diff --git a/gas/config/obj-coff-seh.h b/gas/config/obj-coff-seh.h index 8d77bac..feef17f 100644 --- a/gas/config/obj-coff-seh.h +++ b/gas/config/obj-coff-seh.h @@ -57,6 +57,7 @@ .seh_savexmm .seh_pushframe .seh_code + .seh_scope */ /* architecture specific pdata/xdata handling. */ @@ -75,7 +76,8 @@ {"seh_no32", obj_coff_seh_32, 0}, \ {"seh_handler", obj_coff_seh_handler, 0}, \ {"seh_code", obj_coff_seh_code, 0}, \ - {"seh_handlerdata", obj_coff_seh_handlerdata, 0}, + {"seh_handlerdata", obj_coff_seh_handlerdata, 0}, \ + {"seh_scope", obj_coff_seh_scope, 0}, /* Type definitions. */ @@ -151,6 +153,7 @@ static void obj_coff_seh_proc (int); static void obj_coff_seh_handler (int); static void obj_coff_seh_handlerdata (int); static void obj_coff_seh_code (int); +static void obj_coff_seh_scope (int); #define UNDSEC bfd_und_section_ptr -- 2.35.1.windows.2