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, combined with the handler count field that the xdata section requires. 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