public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add the .seh_ifrepeat and .seh_ifnrepeat directives
@ 2023-06-30  7:53 Julian Waters
  0 siblings, 0 replies; 2+ messages in thread
From: Julian Waters @ 2023-06-30  7:53 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 7814 bytes --]

In SEH assembly blocks, certain blocks should only be emitted once or a
certain number of times, but there is no good way to do so currently. This
patch adds the .seh_ifrepeat and .seh_ifnrepeat directives, which are
conditional directives that track the number of times they appear in an
.seh_proc block and activate/deactivate their respective code branches if
they appear more or less than the specified number of times in the same
block, respectively, and can be used with the .else and .endif directives
seamlessly

From c963b6ff835548516866c1c2d73ab9ff66f24030 Mon Sep 17 00:00:00 2001
From: TheShermanTanker <tanksherman27@gmail.com>
Date: Fri, 30 Jun 2023 13:53:19 +0800
Subject: [PATCH] Add the .seh_ifrepeat and .seh_ifnrepeat directives

---
 gas/cond.c                | 37 ++++---------------------
 gas/cond.h                | 52 +++++++++++++++++++++++++++++++++++
 gas/config/obj-coff-seh.c | 57 +++++++++++++++++++++++++++++++++++++++
 gas/config/obj-coff-seh.h |  3 +++
 4 files changed, 117 insertions(+), 32 deletions(-)
 create mode 100644 gas/cond.h

diff --git a/gas/cond.c b/gas/cond.c
index 5523e92..925f232 100644
--- a/gas/cond.c
+++ b/gas/cond.c
@@ -24,43 +24,16 @@

 #include "obstack.h"

+#include "cond.h"
+
 /* This is allocated to grow and shrink as .ifdef/.endif pairs are
    scanned.  */
 struct obstack cond_obstack;

-struct file_line
-{
-  const char *file;
-  unsigned int line;
-};
-
-/* We push one of these structures for each .if, and pop it at the
-   .endif.  */
-
-struct conditional_frame
-{
-  /* The source file & line number of the "if".  */
-  struct file_line if_file_line;
-  /* The source file & line of the "else".  */
-  struct file_line else_file_line;
-  /* The previous conditional.  */
-  struct conditional_frame *previous_cframe;
-  /* Have we seen an else yet?  */
-  int else_seen;
-  /* Whether we are currently ignoring input.  */
-  int ignoring;
-  /* Whether a conditional at a higher level is ignoring input.
-     Set also when a branch of an "if .. elseif .." tree has matched
-     to prevent further matches.  */
-  int dead_tree;
-  /* Macro nesting level at which this conditional was created.  */
-  int macro_nest;
-};
-
-static void initialize_cframe (struct conditional_frame *cframe);
+void initialize_cframe (struct conditional_frame *cframe);
 static char *get_mri_string (int, int *);

-static struct conditional_frame *current_cframe = NULL;
+struct conditional_frame *current_cframe = NULL;

 /* Performs the .ifdef (test_defined == 1) and
    the .ifndef (test_defined == 0) pseudo op.  */
@@ -534,7 +507,7 @@ ignore_input (void)
   return (current_cframe != NULL) && (current_cframe->ignoring);
 }

-static void
+void
 initialize_cframe (struct conditional_frame *cframe)
 {
   memset (cframe, 0, sizeof (*cframe));
diff --git a/gas/cond.h b/gas/cond.h
new file mode 100644
index 0000000..d5c135f
--- /dev/null
+++ b/gas/cond.h
@@ -0,0 +1,53 @@
+/* cond.h - conditional assembly pseudo-ops, and .include
+   Copyright (C) 1990-2023 Free Software Foundation, Inc.
+
+   This file is part of GAS, the GNU Assembler.
+
+   GAS is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GAS is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+struct file_line
+{
+  const char *file;
+  unsigned int line;
+};
+
+/* We push one of these structures for each .if, and pop it at the
+   .endif.  */
+
+struct conditional_frame
+{
+  /* The source file & line number of the "if".  */
+  struct file_line if_file_line;
+  /* The source file & line of the "else".  */
+  struct file_line else_file_line;
+  /* The previous conditional.  */
+  struct conditional_frame *previous_cframe;
+  /* Have we seen an else yet?  */
+  int else_seen;
+  /* Whether we are currently ignoring input.  */
+  int ignoring;
+  /* Whether a conditional at a higher level is ignoring input.
+     Set also when a branch of an "if .. elseif .." tree has matched
+     to prevent further matches.  */
+  int dead_tree;
+  /* Macro nesting level at which this conditional was created.  */
+  int macro_nest;
+};
+
+extern struct conditional_frame *current_cframe;
+
+void initialize_cframe (struct conditional_frame *cframe);
+
diff --git a/gas/config/obj-coff-seh.c b/gas/config/obj-coff-seh.c
index 7b4486a..5c13ad8 100644
--- a/gas/config/obj-coff-seh.c
+++ b/gas/config/obj-coff-seh.c
@@ -20,6 +20,10 @@

 #include "obj-coff-seh.h"

+#include "as.h"
+#include "cond.h"
+#include "obstack.h"
+

 /* Private segment collection list.  */
 struct seh_seg_list {
@@ -40,6 +44,9 @@ static void write_function_xdata (seh_context *);
 static void write_function_pdata (seh_context *);


+static unsigned int ifcount = 0;
+
+
 /* Build based on segment the derived .pdata/.xdata
    segment name containing origin segment's postfix name part.  */
 static char *
@@ -273,6 +280,54 @@ skip_whitespace_and_comma (int required)
   return 0;
 }

+static void
+obj_coff_seh_ifrepeat (int what)
+{
+
+  if (!verify_context (".seh_ifrepeat"))
+    return;
+
+  unsigned int specified;
+  struct conditional_frame cframe;
+
+  /* Leading whitespace is part of operand.  */
+  SKIP_WHITESPACE ();
+
+  if (*input_line_pointer == 0 || *input_line_pointer == '\n') {
+    as_bad (_(".seh_ifrepeat requires the count parameter"));
+    demand_empty_rest_of_line ();
+    return;
+  } else if (*input_line_pointer == '-') {
+    as_bad (_("Negative count passed to .seh_ifrepeat"));
+    return;
+  } else {
+    specified = atoi(input_line_pointer);
+    ignore_rest_of_line();
+  }
+
+  initialize_cframe (&cframe);
+
+  if (cframe.dead_tree) {
+    cframe.ignoring = 1;
+  } else {
+    if (what == 0) {
+      cframe.ignoring = specified > ifcount++;
+    } else if (what == 1) {
+      cframe.ignoring = specified <= ifcount++;
+    }
+  }
+
+  current_cframe =
+    (struct conditional_frame *) obstack_alloc (&cond_obstack, sizeof
cframe);
+  memcpy (current_cframe, &cframe, sizeof cframe);
+
+  if (LISTING_SKIP_COND ()
+      && cframe.ignoring
+      && (cframe.previous_cframe == NULL
+   || ! cframe.previous_cframe->ignoring))
+    listing_list (2);
+}
+
 /* Mark current context to use 32-bit instruction (arm).  */

 static void
@@ -434,6 +489,8 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED)
       return;
     }

+  ifcount = 0;
+
   seh_ctx_cur = XCNEW (seh_context);

   seh_ctx_cur->code_seg = now_seg;
diff --git a/gas/config/obj-coff-seh.h b/gas/config/obj-coff-seh.h
index 8d77bac..ee3c809 100644
--- a/gas/config/obj-coff-seh.h
+++ b/gas/config/obj-coff-seh.h
@@ -70,6 +70,8 @@
         {"seh_endprologue", obj_coff_seh_endprologue, 0}, \
         {"seh_setframe", obj_coff_seh_setframe, 0}, \
         {"seh_stackalloc", obj_coff_seh_stackalloc, 0}, \
+        {"seh_ifrepeat", obj_coff_seh_ifrepeat, 0}, \
+        {"seh_ifnrepeat", obj_coff_seh_ifrepeat, 1}, \
  {"seh_eh", obj_coff_seh_eh, 0}, \
  {"seh_32", obj_coff_seh_32, 1}, \
  {"seh_no32", obj_coff_seh_32, 0}, \
@@ -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_ifrepeat (int);

 #define UNDSEC bfd_und_section_ptr

-- 
2.35.1.windows.2

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Add the .seh_ifrepeat and .seh_ifnrepeat directives
@ 2023-06-30 18:00 Julian Waters
  0 siblings, 0 replies; 2+ messages in thread
From: Julian Waters @ 2023-06-30 18:00 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 90 bytes --]

Hi all,

Please ignore my proposed patch. It is slightly premature.

best regards,
Julian

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-06-30 18:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-30  7:53 [PATCH] Add the .seh_ifrepeat and .seh_ifnrepeat directives Julian Waters
2023-06-30 18:00 Julian Waters

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).