From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qt1-x82f.google.com (mail-qt1-x82f.google.com [IPv6:2607:f8b0:4864:20::82f]) by sourceware.org (Postfix) with ESMTPS id 53AE3385559C for ; Fri, 30 Jun 2023 07:53:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 53AE3385559C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-qt1-x82f.google.com with SMTP id d75a77b69052e-3f9cf20da51so13010471cf.2 for ; Fri, 30 Jun 2023 00:53:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1688111630; x=1690703630; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=IcxBThgXZU3KR3ew9QemDLj4JRUgPCh2bRFK/hFeUxc=; b=i9xEke/kQcLZjoG3JaGYFoifotfQqyd7Y9Iams22Wa1qSgnkxJDrA3fKr/H0sNYyAK HCCcKpmE5DvIqyixF6HqKILnkGc6ipLGRCFAqU2bYKDOmZVPYXf34Fvj4u61yXB7CIjt KEaa3bFEbMR231l4rOZ3teL/hQYiWgXOFKhN40o/EItwlUkebYThXewk5LGvJD+3GBnR vQsyiopyJetD3U2Nfp+Mxm/MLDDcboeHyJAadRq8dm5ZoWF6h3i/V5KWcWGGd6WMU6Jz wxOI6Pk92bypaiHzyzDuNG37OrjwGGHWVCbWcffT1QlmMiv7mdzB79Beeq6ZF6Zblahx frnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688111630; x=1690703630; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=IcxBThgXZU3KR3ew9QemDLj4JRUgPCh2bRFK/hFeUxc=; b=keAh2KfaJoyBwUvP4qy56L3M3mfQKhmdsI0lBHNIkN0JT0Nc+8RefQqH6JuNJf0RQh gv1EKajMabiDrwQAlqImxh2FLLuL2RpnIwpTdxL4JoNa4zoev4QgdaMFZ9SbrHvsRbZR 6BSscYzOW6d6zFA/HdJa90rdvMcCMA7liJhI6TVKhBulGqW9Cdlg0bWWWxWfgqjeYc96 v2TjE9kq3eJi2kbeq5iEowtlQDUjgaPiK41OwvpwILgtxSb8+SgvcwC2DPsTaZtLcDMS lW7Zx7lJo5LpsOtAvR116Nj1nFyNfTd/fmtluvQ5UHX7SDR/7uqTljPEf8vx6BzprvgR XaTg== X-Gm-Message-State: AC+VfDyRt1D/G83ZYSkV1lP339FavJA4K3C1svu/jKhgsJOr6N+3CiPP h6DZTPj6wEJnZWaR38RuUddBHmKXnFFvSbMzF2CdVklavHg= X-Google-Smtp-Source: ACHHUZ6D4JFBm4CpMSEEl1/0ZolZapBH4HRvMLriDDDoYazqHoGMRtvh6BWrNFWdcCh+rmsm3a/COXZgFVokaL3JtKs= X-Received: by 2002:ac8:5fce:0:b0:3f5:31c9:2578 with SMTP id k14-20020ac85fce000000b003f531c92578mr1711783qta.67.1688111630005; Fri, 30 Jun 2023 00:53:50 -0700 (PDT) MIME-Version: 1.0 From: Julian Waters Date: Fri, 30 Jun 2023 15:53:13 +0800 Message-ID: Subject: [PATCH] Add the .seh_ifrepeat and .seh_ifnrepeat directives To: binutils@sourceware.org Content-Type: multipart/alternative; boundary="0000000000000c3a6905ff541e9f" X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,GIT_PATCH_0,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --0000000000000c3a6905ff541e9f Content-Type: text/plain; charset="UTF-8" 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 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 --0000000000000c3a6905ff541e9f--