[PATCH] Reimplement the .seh_scope directive

Julian Waters tanksherman27@gmail.com
Sun Jul 2 10:18:31 GMT 2023


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 <tanksherman27@gmail.com>
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


More information about the Binutils mailing list