From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by sourceware.org (Postfix) with ESMTPS id 4270B3851A95 for ; Mon, 4 Jul 2022 13:24:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4270B3851A95 Received: by mail-pl1-x62b.google.com with SMTP id y18so568488plb.2 for ; Mon, 04 Jul 2022 06:24:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=vFPr7zPKICWO6w5SRNNw6u9DGKzilfzBAn33ureY7og=; b=VEiy80rcmo9rjWHHtgD+WcJP5GZXWPmpZfLUbhjBzlDX26Bk2jlpGH6Cqo1XIPoobZ PauaLO8mwqbHx6W8KrJGY2m6v/Fzw1guXNj98sy5/KzyKtogxF30P6oGUHGiUF8S1kNe T/iygb/mGkpNzyFMPO8fyRjk1B+hYnQGVtqFzTAE2C17jefPJ858UmqHhwnyOYXrYI04 sEhdJnzXaiIRllOjYWaDlC74R5f1rS97NNoDgjTmOrVsqYjTdz9jcBEnp6nPejdKafjy uBElSv8g6xIG5k5cdEY8798o855kb/qq4X2bcVy0raE7Kmr2syBwkaXdwkLbNpHIDYpS pUag== X-Gm-Message-State: AJIora8FHK9a7PHYBmgNK8NXgS7zfV1d5f/wx3A2oegid9exT8agS6/Z tDENQOBQrToXsnzL17nxGNS6IiEk6zg= X-Google-Smtp-Source: AGRyM1tE/8AzwFWx+YDEaUb+RjJzelXhXn54beYMypgkqxia3f/Vwmr0G2g5r18echo5jYzc3UmV1g== X-Received: by 2002:a17:902:dad1:b0:16a:75cb:5d97 with SMTP id q17-20020a170902dad100b0016a75cb5d97mr35852444plx.64.1656941069945; Mon, 04 Jul 2022 06:24:29 -0700 (PDT) Received: from squeak.grove.modra.org (158.106.96.58.static.exetel.com.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id p12-20020a17090adf8c00b001ef8de342b8sm1583524pjv.15.2022.07.04.06.24.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Jul 2022 06:24:29 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id B85101143095; Mon, 4 Jul 2022 22:54:26 +0930 (ACST) Date: Mon, 4 Jul 2022 22:54:26 +0930 From: Alan Modra To: binutils@sourceware.org Subject: alloc gas seginfo on notes obstack Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3037.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, 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 X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Jul 2022 13:24:33 -0000 Lots of memory used in gas should go on this obstack. The patch also frees all the gas obstacks on exit, which isn't a completely trivial task. * subsegs.c (alloc_seginfo): New function. (subseg_change, subseg_get): Use it. (subsegs_end): New function. * as.h (subsegs_end): Declare. * output-file.c: Include subsegs.h (stash_frchain_obs): New function. (output_file_close): Save obstacks attached to output bfd before closing. Call subsegs_end with the array of obstacks. diff --git a/gas/as.h b/gas/as.h index 470a2e52891..ec0c12afe23 100644 --- a/gas/as.h +++ b/gas/as.h @@ -476,6 +476,7 @@ void input_scrub_end (void); void new_logical_line (const char *, int); void new_logical_line_flags (const char *, int, int); void subsegs_begin (void); +void subsegs_end (struct obstack **); void subseg_change (segT, int); segT subseg_new (const char *, subsegT); segT subseg_force_new (const char *, subsegT); diff --git a/gas/output-file.c b/gas/output-file.c index 9852a2ed456..95e21d23dc1 100644 --- a/gas/output-file.c +++ b/gas/output-file.c @@ -19,6 +19,7 @@ 02110-1301, USA. */ #include "as.h" +#include "subsegs.h" #include "output-file.h" #ifndef TARGET_MACH @@ -49,23 +50,54 @@ output_file_create (const char *name) stdoutput->flags |= BFD_TRADITIONAL_FORMAT; } +static void +stash_frchain_obs (asection *sec) +{ + segment_info_type *info = seg_info (sec); + if (info) + { + struct frchain *frchp; + for (frchp = info->frchainP; frchp; frchp = frchp->frch_next) + obstack_ptr_grow (¬es, &frchp->frch_obstack); + info->frchainP = NULL; + } +} + void output_file_close (const char *filename) { bool res; + bfd *obfd = stdoutput; + struct obstack **obs; + asection *sec; - if (stdoutput == NULL) + if (obfd == NULL) return; + /* Prevent an infinite loop - if the close failed we will call as_fatal + which will call xexit() which may call this function again... */ + stdoutput = NULL; + + /* We can't free obstacks attached to the output bfd sections before + closing the output bfd since data in those obstacks may need to + be accessed, but we can't access anything in the output bfd after + it is closed.. */ + for (sec = obfd->sections; sec; sec = sec->next) + stash_frchain_obs (sec); + stash_frchain_obs (reg_section); + stash_frchain_obs (expr_section); + stash_frchain_obs (bfd_abs_section_ptr); + stash_frchain_obs (bfd_und_section_ptr); + obstack_ptr_grow (¬es, NULL); + obs = obstack_finish (¬es); + /* Close the bfd. */ if (!flag_always_generate_output && had_errors ()) res = bfd_cache_close_all (); else - res = bfd_close (stdoutput); + res = bfd_close (obfd); - /* Prevent an infinite loop - if the close failed we will call as_fatal - which will call xexit() which may call this function again... */ - stdoutput = NULL; + subsegs_end (obs); if (! res) as_fatal ("%s: %s", filename, bfd_errmsg (bfd_get_error ())); diff --git a/gas/subsegs.c b/gas/subsegs.c index cb598e84bef..1776511a9b8 100644 --- a/gas/subsegs.c +++ b/gas/subsegs.c @@ -43,7 +43,27 @@ subsegs_begin (void) frchain_now = NULL; /* Warn new_subseg() that we are booting. */ frag_now = &dummy_frag; } + +void +subsegs_end (struct obstack **obs) +{ + for (; *obs; obs++) + _obstack_free (*obs, NULL); + _obstack_free (&frchains, NULL); + _obstack_free (&cond_obstack, NULL); + _obstack_free (¬es, NULL); +} +static void +alloc_seginfo (segT seg) +{ + segment_info_type *seginfo; + + seginfo = obstack_alloc (¬es, sizeof (*seginfo)); + memset (seginfo, 0, sizeof (*seginfo)); + seginfo->bfd_section = seg; + bfd_set_section_userdata (seg, seginfo); +} /* * subseg_change() * @@ -57,16 +77,11 @@ subsegs_begin (void) void subseg_change (segT seg, int subseg) { - segment_info_type *seginfo = seg_info (seg); now_seg = seg; now_subseg = subseg; - if (! seginfo) - { - seginfo = XCNEW (segment_info_type); - seginfo->bfd_section = seg; - bfd_set_section_userdata (seg, seginfo); - } + if (!seg_info (seg)) + alloc_seginfo (seg); } static void @@ -149,7 +164,6 @@ segT subseg_get (const char *segname, int force_new) { segT secptr; - segment_info_type *seginfo; const char *now_seg_name = now_seg ? bfd_section_name (now_seg) : 0; if (!force_new @@ -163,13 +177,10 @@ subseg_get (const char *segname, int force_new) else secptr = bfd_make_section_anyway (stdoutput, segname); - seginfo = seg_info (secptr); - if (! seginfo) + if (!seg_info (secptr)) { secptr->output_section = secptr; - seginfo = XCNEW (segment_info_type); - seginfo->bfd_section = secptr; - bfd_set_section_userdata (secptr, seginfo); + alloc_seginfo (secptr); } return secptr; } -- Alan Modra Australia Development Lab, IBM