From patchwork Thu Aug 31 12:12:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 137285 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c792:0:b0:3f2:4152:657d with SMTP id b18csp197935vqu; Thu, 31 Aug 2023 05:13:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH9NYRtliDzBVmn9SDaudWy+ACi/6Pnnlm2SEUnm7YSzA0XxQMdtgvNSE+G0X8iV0axOdEc X-Received: by 2002:a17:906:1d4:b0:9a5:c7a6:1549 with SMTP id 20-20020a17090601d400b009a5c7a61549mr4557926ejj.39.1693483987657; Thu, 31 Aug 2023 05:13:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693483987; cv=none; d=google.com; s=arc-20160816; b=pyQxe6m4Lzqp4PV/csrk3xzJQoWGZtqiP1oexuRftJPd2Oh4ZNl3OXqw21NmJclFpR IkpnifBe94mmOB6YzKd8WZ3zQp2OroxkpJK9qPNd+XhuSpvDIKBn979+6dG7hmKf9WJd 4eGsy+BPtysJkzsgDobc8AWHzPxZA7uPqJVcks/zyE19HWIjN2Wm95fQRwKRWMmZblFi IpKYdorTsl3Z38scXbx5elOFsgMONwtfyYhLyhp956gxaJi1CPagTuKfLSjVbX1baOtC bQSdoKtDe8lb7qf1JHQvMK5f0/5ydnK0PPV63PC9RqfR47zUECF7En1xzipR/5fk+hfu /mog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:mime-version:message-id:subject:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=fkcukAqoi+t64i4CUW3ojV8bZDVefYh2vu2qSFlXTDY=; fh=NLxAvL/bDfPg4AGOtxqvQlND8vazkZrNzKLY8+LAbBY=; b=F9qp0CMpoaKv7FIOJoQbamU2xblG7LZkvgOCUse35CvgDpABz5ItkyaMPiGCT3Qccb 99DYQyAk4UPzrL4ZPAaq23FxzI1T+HH3lBOJmxNxZCS0ig3Vw3q8jC/Cfx30j6V1qyJE Yq+QmCTWOHm+C7Dr5xpTsjFNbTfKH1/Jk47M+pXjCGOc1e1gHmjclmmnwm8AsAqA4c8i tNPPjbLrkzLMiuAn0W15ARXkuSjv72Fe0jsjTeOqzxouiPY075ppMlx0Lx/9zYDlIqFF PzhgyUuq3EyAXfO2Knag7iTBr3YmvnzqvyPK//tqeHIkj3zFC16HY18HxEBzVMwlF3wS Z0nQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=GH93KQL5; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id o18-20020a17090608d200b009a197afe799si801283eje.368.2023.08.31.05.13.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 31 Aug 2023 05:13:07 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=GH93KQL5; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ABAF3385842A for ; Thu, 31 Aug 2023 12:13:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ABAF3385842A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1693483984; bh=fkcukAqoi+t64i4CUW3ojV8bZDVefYh2vu2qSFlXTDY=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=GH93KQL5Z3awzia1Ov/Nwb//Vs86MxooDWUhY+4OTCKOflq6TruO1JZUFe+YjJ3qk Qqn/EIvK0haF2G/viZkiYWB2opwsVNkhSjuf/0+pUUU5KCmzfjKCFV8rS5Y4O+dNUh NqB48dqx9JwCTTlK0/YxFJepf2AEB4KzFFV7epmE= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by sourceware.org (Postfix) with ESMTPS id D54C63858D28 for ; Thu, 31 Aug 2023 12:12:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D54C63858D28 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1c06f6f98c0so5537305ad.3 for ; Thu, 31 Aug 2023 05:12:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693483960; x=1694088760; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fkcukAqoi+t64i4CUW3ojV8bZDVefYh2vu2qSFlXTDY=; b=SDX3BRdU30aExBkguwwH/gQv9bAceWtuxfhJnIikuYZZ4nrXOnJKSRiC4JAb3RyJV2 8VYFT5XUgWMhGlBeSxVtzh1oIvdYqQJrkcwjvVJkELSJA/tXNhvxlSVYSfuhoujnIiOF 1MsdumSKRpQTDl4RU6Dd9ogQlhMji1heo290IvoF6ZmFwqL/XVfOuBMc/c6Unl5d7GDd /J1iww/e0mAJ21ajFYAV8rLDtVnL5g9H0gpCfn2jc2TzrhctnYldddbflOgFbtVAINvI pAjZXfNQWxG89X9V1RmsSo8Q9phQa7AE3PmjMal6CLtpfiX4KrKo7lTf0DMXLgGXYMHk GI+A== X-Gm-Message-State: AOJu0YzoOZpuH/A0Q4q1xG+45LQq3u4pzQA9pJ2DB9sG+jv+gkDilvZz Gdf/IryHRiF7D8Rsojs+ZKltXYV6Iac+vg== X-Received: by 2002:a17:902:f54f:b0:1c0:d0d1:8e70 with SMTP id h15-20020a170902f54f00b001c0d0d18e70mr6485757plf.51.1693483959943; Thu, 31 Aug 2023 05:12:39 -0700 (PDT) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:beed:e5d:7015:37c8]) by smtp.gmail.com with ESMTPSA id d10-20020a170902654a00b001b8b2b95068sm1157684pln.204.2023.08.31.05.12.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 31 Aug 2023 05:12:39 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 5786E114241C; Thu, 31 Aug 2023 21:42:36 +0930 (ACST) Date: Thu, 31 Aug 2023 21:42:36 +0930 To: binutils@sourceware.org Subject: gas init_stab_section and get_stab_string_offset Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-3032.9 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 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.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Alan Modra via Binutils From: Alan Modra Reply-To: Alan Modra Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1775746665917150769 X-GMAIL-MSGID: 1775746665917150769 get_stab_string_offset currently creates the stabstr section if not already present, in the process keeping a reference to the malloc'd section name string. Really, the name belongs in bfd_alloc'd memory or some obstack so that it doesn't show as a memory leak on exit. s_stab_generic at least does allocate the name for the stab section on an obstack, but doesn't tidy that as well as it could. Return paths after issuing a warning don't release the memory, nor the memory for the "string" copy. This patch fixes these problems. s_stab_generic is rearranged so that creation of the sections occurs earlier, before any potential uses of the note obstack during expression parsing. That makes it possible to always free the section name strings unless used to create new sections. I've also avoided get_absolute_expression_and_terminator as I see that function might skip over end-of-line, and lack of a --input_line_pointer might have caused the following source line to be ignored. (Other uses of this function in gas are OK.) * config/obj-coff.c (obj_coff_init_stab_section): Add stabstr param. Pass to get_stab_string_offset rather than name of section. * config/obj-som.c (obj_som_init_stab_section): Likewise. * config/obj-elf.c (obj_elf_init_stab_section): Likewise. (elf_init_stab_section): Adjust. * config/obj-coff.h (INIT_STAB_SECTION): Update. (obj_coff_init_stab_section): Update prototype. * config/obj-som.h: Similarly. * config/obj-elf.h: Similarly. * config/obj-multi.h (INIT_STAB_SECTION): Update. * obj.h (struct format_ops ): Update. * read.h (get_stab_string_offset): Update prototype. * stabs.c (cached_sec): Delete. (stabs_begin): Adjust to suit. (get_stab_string_offset): Add stabstr param, delete stabstr_name and free_stabstr_secname params. Don't make stabstr section here. (eat_comma): New function. (s_stab_generic): Replace stab_secname_obstack_end param with bool freenames. Move creation of stab and stabstr sections earlier, so the names can be freed earlier before possible use of notes obstack during expression parsing. Tidy error paths ensuring "string" is freed. Use get_absolute_expression in place of get_absolute_expression_and_terminator. (s_stab): Adjust. (s_xstab): Use notes_concat to make stabstr section name. diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 6216b1f63ee..b8e049aba46 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1804,11 +1804,10 @@ coff_frob_section (segT sec) } void -obj_coff_init_stab_section (segT seg) +obj_coff_init_stab_section (segT stab ATTRIBUTE_UNUSED, segT stabstr) { const char *file; char *p; - char *stabstr_name; unsigned int stroff; /* Make space for this first symbol. */ @@ -1816,8 +1815,7 @@ obj_coff_init_stab_section (segT seg) /* Zero it out. */ memset (p, 0, 12); file = as_where ((unsigned int *) NULL); - stabstr_name = concat (seg->name, "str", (char *) NULL); - stroff = get_stab_string_offset (file, stabstr_name, true); + stroff = get_stab_string_offset (file, stabstr); know (stroff == 1); md_number_to_chars (p, stroff, 4); } diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index 2a97c38474f..8c41ac0a5e8 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -299,7 +299,7 @@ extern const pseudo_typeS coff_pseudo_table[]; /* We need 12 bytes at the start of the section to hold some initial information. */ -#define INIT_STAB_SECTION(seg) obj_coff_init_stab_section (seg) +#define INIT_STAB_SECTION(stab, str) obj_coff_init_stab_section (stab, str) /* Store the number of relocations in the section aux entry. */ #ifdef OBJ_XCOFF @@ -342,7 +342,7 @@ extern segT s_get_segment (symbolS *); extern void tc_coff_symbol_emit_hook (symbolS *); #endif extern void obj_coff_pe_handle_link_once (void); -extern void obj_coff_init_stab_section (segT); +extern void obj_coff_init_stab_section (segT, segT); extern void c_section_header (struct internal_scnhdr *, char *, long, long, long, long, long, long, long, long); diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 1c1b60b0b48..681e75f9a48 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -2525,27 +2525,25 @@ obj_elf_ident (int ignore ATTRIBUTE_UNUSED) /* The first entry in a .stabs section is special. */ void -obj_elf_init_stab_section (segT seg) +obj_elf_init_stab_section (segT stab, segT stabstr) { char *file; char *p; - char *stabstr_name; unsigned int stroff; /* Force the section to align to a longword boundary. Without this, UnixWare ar crashes. */ - bfd_set_section_alignment (seg, 2); + bfd_set_section_alignment (stab, 2); /* Make space for this first symbol. */ p = frag_more (12); /* Zero it out. */ memset (p, 0, 12); file = remap_debug_filename (as_where (NULL)); - stabstr_name = concat (segment_name (seg), "str", (char *) NULL); - stroff = get_stab_string_offset (file, stabstr_name, true); + stroff = get_stab_string_offset (file, stabstr); know (stroff == 1 || (stroff == 0 && file[0] == '\0')); md_number_to_chars (p, stroff, 4); - seg_info (seg)->stabu.p = p; + seg_info (stab)->stabu.p = p; free (file); } @@ -3137,12 +3135,12 @@ elf_separate_stab_sections (void) } static void -elf_init_stab_section (segT seg) +elf_init_stab_section (segT stab, segT stabstr) { #ifdef NEED_ECOFF_DEBUG if (!ECOFF_DEBUGGING) #endif - obj_elf_init_stab_section (seg); + obj_elf_init_stab_section (stab, stabstr); } /* This is called when the assembler starts. */ diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index 5c8404ec49d..683d0851585 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -242,7 +242,7 @@ void elf_adjust_symtab (void); #ifndef SEPARATE_STAB_SECTIONS /* Avoid ifndef each separate macro setting by wrapping the whole of the stab group on the assumption that whoever sets SEPARATE_STAB_SECTIONS - caters to ECOFF_DEBUGGING and the right setting of INIT_STAB_SECTIONS + caters to ECOFF_DEBUGGING and the right setting of INIT_STAB_SECTION and OBJ_PROCESS_STAB too, without needing the tweaks below. */ /* Stabs go in a separate section. */ @@ -250,8 +250,8 @@ void elf_adjust_symtab (void); /* We need 12 bytes at the start of the section to hold some initial information. */ -extern void obj_elf_init_stab_section (segT); -#define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg) +extern void obj_elf_init_stab_section (segT, segT); +#define INIT_STAB_SECTION(stab, str) obj_elf_init_stab_section (stab, str) #ifdef ECOFF_DEBUGGING /* We smuggle stabs in ECOFF rather than using a separate section. @@ -261,8 +261,8 @@ extern void obj_elf_init_stab_section (segT); #define SEPARATE_STAB_SECTIONS (!ECOFF_DEBUGGING) #undef INIT_STAB_SECTION -#define INIT_STAB_SECTION(seg) \ - ((void) (ECOFF_DEBUGGING ? 0 : (obj_elf_init_stab_section (seg), 0))) +#define INIT_STAB_SECTION(stab, str) \ + ((void) (ECOFF_DEBUGGING ? 0 : (obj_elf_init_stab_section (stab, str), 0))) #undef OBJ_PROCESS_STAB #define OBJ_PROCESS_STAB(what, string, type, other, desc) \ diff --git a/gas/config/obj-multi.h b/gas/config/obj-multi.h index 894b9245845..4007d8adfb0 100644 --- a/gas/config/obj-multi.h +++ b/gas/config/obj-multi.h @@ -153,9 +153,9 @@ #define SEPARATE_STAB_SECTIONS \ ((*this_format->separate_stab_sections) ()) -#define INIT_STAB_SECTION(S) \ +#define INIT_STAB_SECTION(STAB, STR) \ (this_format->init_stab_section \ - ? (*this_format->init_stab_section) (S) \ + ? (*this_format->init_stab_section) (STAB, STR) \ : (void) 0) #define EMIT_SECTION_SYMBOLS (this_format->emit_section_symbols) diff --git a/gas/config/obj-som.c b/gas/config/obj-som.c index 9171db29185..6c0c64f94dd 100644 --- a/gas/config/obj-som.c +++ b/gas/config/obj-som.c @@ -205,7 +205,7 @@ obj_som_copyright (int unused ATTRIBUTE_UNUSED) which BFD does not understand. */ void -obj_som_init_stab_section (segT seg) +obj_som_init_stab_section (segT stab, segT stabstr) { segT saved_seg = now_seg; segT space; @@ -234,8 +234,8 @@ obj_som_init_stab_section (segT seg) (just created above). Also set some attributes which BFD does not understand. In particular, access bits, sort keys, and load quadrant. */ - obj_set_subsection_attributes (seg, space, 0x1f, 73, 0, 0, 0, 0); - bfd_set_section_alignment (seg, 2); + obj_set_subsection_attributes (stab, space, 0x1f, 73, 0, 0, 0, 0); + bfd_set_section_alignment (stab, 2); /* Make some space for the first special stab entry and zero the memory. It contains information about the length of this file's @@ -247,18 +247,17 @@ obj_som_init_stab_section (segT seg) p = frag_more (12); memset (p, 0, 12); file = as_where ((unsigned int *) NULL); - stroff = get_stab_string_offset (file, "$GDB_STRINGS$", false); + stroff = get_stab_string_offset (file, stabstr); know (stroff == 1); md_number_to_chars (p, stroff, 4); - seg_info (seg)->stabu.p = p; + seg_info (stab)->stabu.p = p; /* Set the containing space for both stab sections to be $GDB_DEBUG$ (just created above). Also set some attributes which BFD does not understand. In particular, access bits, sort keys, and load quadrant. */ - seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$"); - obj_set_subsection_attributes (seg, space, 0x1f, 72, 0, 0, 0, 0); - bfd_set_section_alignment (seg, 2); + obj_set_subsection_attributes (stabstr, space, 0x1f, 72, 0, 0, 0, 0); + bfd_set_section_alignment (stabstr, 2); subseg_set (saved_seg, saved_subseg); } diff --git a/gas/config/obj-som.h b/gas/config/obj-som.h index b04b577e3eb..2c2dd69da8b 100644 --- a/gas/config/obj-som.h +++ b/gas/config/obj-som.h @@ -36,7 +36,7 @@ extern void som_file_symbol (char *); extern void som_frob_file (void); extern void obj_som_version (int); -extern void obj_som_init_stab_section (segT); +extern void obj_som_init_stab_section (segT, segT); extern void obj_som_copyright (int); extern void obj_som_compiler (int); @@ -60,7 +60,7 @@ extern void obj_som_compiler (int); /* We use INIT_STAB_SECTION to record the space/subspace relationships for the various debugging sections. */ -#define INIT_STAB_SECTION(seg) obj_som_init_stab_section (seg) +#define INIT_STAB_SECTION(stab, str) obj_som_init_stab_section (stab, str) /* We'll be updating the magic 1st stab entry once the entire assembly fail has been processed. */ diff --git a/gas/obj.h b/gas/obj.h index 3851e67563b..0aebc6a087e 100644 --- a/gas/obj.h +++ b/gas/obj.h @@ -65,7 +65,7 @@ struct format_ops { void (*generate_asm_lineno) (void); void (*process_stab) (int, const char *, int, int, int); int (*separate_stab_sections) (void); - void (*init_stab_section) (segT); + void (*init_stab_section) (segT, segT); int (*sec_sym_ok_for_reloc) (asection *); void (*pop_insert) (void); /* For configurations using ECOFF_DEBUGGING, this callback is used. */ diff --git a/gas/read.h b/gas/read.h index 42efce9e79d..523a6e8af43 100644 --- a/gas/read.h +++ b/gas/read.h @@ -113,8 +113,7 @@ extern char original_case_string[]; #endif extern void pop_insert (const pseudo_typeS *); -extern unsigned int get_stab_string_offset - (const char *, const char *, bool); +extern unsigned int get_stab_string_offset (const char *, segT); extern void aout_process_stab (int, const char *, int, int, int); extern char *demand_copy_string (int *lenP); extern char *demand_copy_C_string (int *len_pointer); diff --git a/gas/stabs.c b/gas/stabs.c index 6a462c4eee7..1b25542900a 100644 --- a/gas/stabs.c +++ b/gas/stabs.c @@ -52,9 +52,6 @@ static void generate_asm_file (int, const char *); apply to assembler code assembled with -gstabs. */ static const char *current_function_label; -/* Current stab section when SEPARATE_STAB_SECTIONS. */ -static segT cached_sec; - /* State used by generate_asm_file. */ static char *last_asm_file; static int file_label_count; @@ -95,14 +92,12 @@ static int endfunc_label_count; #endif unsigned int -get_stab_string_offset (const char *string, const char *stabstr_secname, - bool free_stabstr_secname) +get_stab_string_offset (const char *string, segT stabstr) { unsigned int length; unsigned int retval; segT save_seg; subsegT save_subseg; - segT seg; char *p; if (! SEPARATE_STAB_SECTIONS) @@ -113,19 +108,16 @@ get_stab_string_offset (const char *string, const char *stabstr_secname, save_seg = now_seg; save_subseg = now_subseg; - /* Create the stab string section, if it doesn't already exist. */ - seg = subseg_new (stabstr_secname, 0); - if (free_stabstr_secname && seg->name != stabstr_secname) - free ((char *) stabstr_secname); + subseg_set (stabstr, 0); - retval = seg_info (seg)->stabu.stab_string_size; + retval = seg_info (stabstr)->stabu.stab_string_size; if (retval <= 0) { /* Make sure the first string is empty. */ p = frag_more (1); *p = 0; - retval = seg_info (seg)->stabu.stab_string_size = 1; - bfd_set_section_flags (seg, SEC_READONLY | SEC_DEBUGGING); + retval = seg_info (stabstr)->stabu.stab_string_size = 1; + bfd_set_section_flags (stabstr, SEC_READONLY | SEC_DEBUGGING); } if (length > 0) @@ -133,7 +125,7 @@ get_stab_string_offset (const char *string, const char *stabstr_secname, p = frag_more (length + 1); strcpy (p, string); - seg_info (seg)->stabu.stab_string_size += length + 1; + seg_info (stabstr)->stabu.stab_string_size += length + 1; } else retval = 0; @@ -184,23 +176,71 @@ aout_process_stab (int what, const char *string, int type, int other, int desc) } #endif +static bool +eat_comma (int what) +{ + if (*input_line_pointer == ',') + { + input_line_pointer++; + return true; + } + as_warn (_(".stab%c: missing comma"), what); + ignore_rest_of_line (); + return false; +} + /* This can handle different kinds of stabs (s,n,d) and different - kinds of stab sections. If STAB_SECNAME_OBSTACK_END is non-NULL, - then STAB_SECNAME and STABSTR_SECNAME will be freed if possible - before this function returns (the former by obstack_free). */ + kinds of stab sections. If FREENAMES is true, then STAB_SECNAME + and STABSTR_SECNAME are allocated in that order on the notes + obstack and will be freed if possible. */ static void s_stab_generic (int what, const char *stab_secname, const char *stabstr_secname, - const char *stab_secname_obstack_end) + bool freenames) { - long longint; const char *string; char *saved_string_obstack_end; int type; int other; int desc; + segT stab, stabstr = NULL; + segT saved_seg = now_seg; + subsegT saved_subseg = now_subseg; + fragS *saved_frag = frag_now; + valueT dot = 0; + + if (SEPARATE_STAB_SECTIONS) + /* Output the stab information in a separate section. This is used + at least for COFF and ELF. */ + { + dot = frag_now_fix (); + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + stab = subseg_new (stab_secname, 0); + stabstr = subseg_new (stabstr_secname, 0); + + if (freenames + && stab->name != stab_secname + && stabstr->name != stabstr_secname) + obstack_free (¬es, stab_secname); + + subseg_set (stab, 0); + if (!seg_info (stab)->hadone) + { + bfd_set_section_flags (stab, + SEC_READONLY | SEC_RELOC | SEC_DEBUGGING); +#ifdef INIT_STAB_SECTION + INIT_STAB_SECTION (stab, stabstr); +#endif + seg_info (stab)->hadone = 1; + } + } + else if (freenames) + obstack_free (¬es, stab_secname); /* The general format is: .stabs "STRING",TYPE,OTHER,DESC,VALUE @@ -210,11 +250,9 @@ s_stab_generic (int what, any trailing whitespace. The argument what is one of 's', 'n' or 'd' indicating which type of .stab this is. */ + saved_string_obstack_end = NULL; if (what != 's') - { - string = ""; - saved_string_obstack_end = 0; - } + string = ""; else { int length; @@ -224,38 +262,24 @@ s_stab_generic (int what, { as_warn (_(".stab%c: missing string"), what); ignore_rest_of_line (); - return; + goto out; } /* FIXME: We should probably find some other temporary storage for string, rather than leaking memory if someone else happens to use the notes obstack. */ saved_string_obstack_end = obstack_next_free (¬es); SKIP_WHITESPACE (); - if (*input_line_pointer == ',') - input_line_pointer++; - else - { - as_warn (_(".stab%c: missing comma"), what); - ignore_rest_of_line (); - return; - } + if (!eat_comma (what)) + goto out; } - if (get_absolute_expression_and_terminator (&longint) != ',') - { - as_warn (_(".stab%c: missing comma"), what); - ignore_rest_of_line (); - return; - } - type = longint; + type = get_absolute_expression (); + if (!eat_comma (what)) + goto out; - if (get_absolute_expression_and_terminator (&longint) != ',') - { - as_warn (_(".stab%c: missing comma"), what); - ignore_rest_of_line (); - return; - } - other = longint; + other = get_absolute_expression (); + if (!eat_comma (what)) + goto out; desc = get_absolute_expression (); @@ -268,13 +292,8 @@ s_stab_generic (int what, if (what == 's' || what == 'n') { - if (*input_line_pointer != ',') - { - as_warn (_(".stab%c: missing comma"), what); - ignore_rest_of_line (); - return; - } - input_line_pointer++; + if (!eat_comma (what)) + goto out; SKIP_WHITESPACE (); } @@ -322,54 +341,16 @@ s_stab_generic (int what, /* Output the stab information in a separate section. This is used at least for COFF and ELF. */ { - segT saved_seg = now_seg; - subsegT saved_subseg = now_subseg; - fragS *saved_frag = frag_now; - valueT dot; - segT seg; unsigned int stroff; char *p; - dot = frag_now_fix (); - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif + stroff = get_stab_string_offset (string, stabstr); - if (cached_sec && strcmp (cached_sec->name, stab_secname) == 0) - { - seg = cached_sec; - subseg_set (seg, 0); - } - else - { - seg = subseg_new (stab_secname, 0); - cached_sec = seg; - } - - if (! seg_info (seg)->hadone) - { - bfd_set_section_flags (seg, - SEC_READONLY | SEC_RELOC | SEC_DEBUGGING); -#ifdef INIT_STAB_SECTION - INIT_STAB_SECTION (seg); -#endif - seg_info (seg)->hadone = 1; - } - - stroff = get_stab_string_offset (string, stabstr_secname, - stab_secname_obstack_end != NULL); - - /* Release the string, if nobody else has used the obstack. */ - if (saved_string_obstack_end != NULL - && saved_string_obstack_end == obstack_next_free (¬es)) + /* Release the string, if nobody else has used the obstack. + This must be done before creating symbols below, which uses + the notes obstack. */ + if (saved_string_obstack_end == obstack_next_free (¬es)) obstack_free (¬es, string); - /* Similarly for the section name. This must be done before - creating symbols below, which uses the notes obstack. */ - if (seg->name != stab_secname - && stab_secname_obstack_end != NULL - && stab_secname_obstack_end == obstack_next_free (¬es)) - obstack_free (¬es, stab_secname); /* At least for now, stabs in a special stab section are always output as 12 byte blocks of information. */ @@ -403,17 +384,9 @@ s_stab_generic (int what, #ifdef OBJ_PROCESS_STAB OBJ_PROCESS_STAB (what, string, type, other, desc); #endif - - subseg_set (saved_seg, saved_subseg); } else { - if (stab_secname_obstack_end != NULL) - { - free ((char *) stabstr_secname); - if (stab_secname_obstack_end == obstack_next_free (¬es)) - obstack_free (¬es, stab_secname); - } #ifdef OBJ_PROCESS_STAB OBJ_PROCESS_STAB (what, string, type, other, desc); #else @@ -422,6 +395,10 @@ s_stab_generic (int what, } demand_empty_rest_of_line (); + out: + if (saved_string_obstack_end == obstack_next_free (¬es)) + obstack_free (¬es, string); + subseg_set (saved_seg, saved_subseg); } /* Regular stab directive. */ @@ -429,7 +406,7 @@ s_stab_generic (int what, void s_stab (int what) { - s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME, NULL); + s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME, false); } /* "Extended stabs", used in Solaris only now. */ @@ -438,25 +415,23 @@ void s_xstab (int what) { int length; - char *stab_secname, *stabstr_secname, *stab_secname_obstack_end; + char *stab_secname, *stabstr_secname; stab_secname = demand_copy_C_string (&length); - stab_secname_obstack_end = obstack_next_free (¬es); SKIP_WHITESPACE (); if (*input_line_pointer == ',') - input_line_pointer++; + { + input_line_pointer++; + /* To get the name of the stab string section, simply add + "str" to the stab section name. */ + stabstr_secname = notes_concat (stab_secname, "str", (char *) NULL); + s_stab_generic (what, stab_secname, stabstr_secname, true); + } else { as_bad (_("comma missing in .xstabs")); ignore_rest_of_line (); - return; } - - /* To get the name of the stab string section, simply add "str" to - the stab section name. */ - stabstr_secname = concat (stab_secname, "str", (char *) NULL); - s_stab_generic (what, stab_secname, stabstr_secname, - stab_secname_obstack_end); } #ifdef S_SET_DESC @@ -707,7 +682,6 @@ void stabs_begin (void) { current_function_label = NULL; - cached_sec = NULL; last_asm_file = NULL; file_label_count = 0; line_label_count = 0;