Reimplement the .seh_scope directive

Message ID CAP2b4GN6AvihQ9W0ebCMgH1ozEvYKjb41Te9HfQg4k=e9ejhSw@mail.gmail.com
State Corrupt patch
Headers
Series Reimplement the .seh_scope directive |

Checks

Context Check Description
snail/binutils-gdb-check warning Git am fail log

Commit Message

Julian Waters July 2, 2023, 10:18 a.m. UTC
  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(-)

--
2.35.1.windows.2
  

Patch

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