From patchwork Fri Jun 9 06:09:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 105286 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp739638vqr; Thu, 8 Jun 2023 23:09:49 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4xbHfFKg3DC85yTkMM7jDGrQt3ClK+pKxXWnfL92qUeemoA/0R7VDPwupEX5uGjmQCVHd3 X-Received: by 2002:aa7:c71a:0:b0:50d:975f:3729 with SMTP id i26-20020aa7c71a000000b0050d975f3729mr688346edq.11.1686290989749; Thu, 08 Jun 2023 23:09:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686290989; cv=none; d=google.com; s=arc-20160816; b=MAd28JnATtV0Z2DsoO5WcrrZMRoS3MZdGoqNcJaCkta9DxvAuiKbOUr/COShmgAifV oB8x6ab6yGhutfc5doZ5TBPpDxJQOcPlhgxIL26I+3Hi3MtTniIvF2l4OfJcWhF0opPL qiMeIuEFefYSTYomKSyW5BkIiHKG9Gt78SY1vaifRH/rZ+Z6208afaEdrANZlUdpsalF mhpsqNIZ7U03qr9tSm6WmJaohkAMiD4xkmuSTGwDBdt6KVwVXnGkSwwXZyBOAKPTWiiS wJyXCS8kl8X3GdWRd1tFODvcr0HjfZH8r9H8luCTI2hWtmXvknLth0JOrRM3ZTW4ITXY fn8Q== 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=KPRRsoJHiIZqWkurvDtZsYNblaOXkiB0v3egDMYXdn0=; b=munZdHMB4G0QRCKkxwQFrNuMt0dac311hCpU4ZdGsakx0nwvVLLCT+gTE6n7L27Tfw lM1klfQJ//xYZQXReofMik1IWK//eLJzBaRVywEDcIZviLizr3nfBFh3PEJnl1Vfc22J YjUg2dS0qoYAGceGkq8GMeXOffvVO2ItFH/u5FBPWiKt+0KdpCxTaD3hICdATQwhcOIL 6X2nw0IIJyc8SSmYBkCWGSBblNrDJuz3/GJ8aLufljNAKu8vcUiENWr6rBF9pVATYgFD 6+Gcmb2hLYvrRKwxoJa5mdQLdZxMDaPoJ/BK5bmpuGVecJcbXF9f15rXvwgnJX7zMwC1 qqzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=foY1Z6dz; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 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 sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id bo24-20020a0564020b3800b0051492c2a57dsi1738253edb.107.2023.06.08.23.09.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Jun 2023 23:09:49 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=foY1Z6dz; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 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 B706D3856DCD for ; Fri, 9 Jun 2023 06:09:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B706D3856DCD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1686290984; bh=KPRRsoJHiIZqWkurvDtZsYNblaOXkiB0v3egDMYXdn0=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=foY1Z6dzVH/mnMakcmmZ1yuWmsJhbXlV1oO4FhysIYXIVimSoCdFGom90gGPidI1V V3c/m1ucvj3uBAkomiGbsxBVmNV35chmKnBtCiVDg8DCxNShUTtCW3qAA2Dzs6c1v2 XejIZQDOzeuunl7deXPY6bo5OgxosnUjFY3Rm3g0= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) by sourceware.org (Postfix) with ESMTPS id 21B083858C20 for ; Fri, 9 Jun 2023 06:09:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 21B083858C20 Received: by mail-pg1-x534.google.com with SMTP id 41be03b00d2f7-543cc9541feso372280a12.2 for ; Thu, 08 Jun 2023 23:09:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686290973; x=1688882973; 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=KPRRsoJHiIZqWkurvDtZsYNblaOXkiB0v3egDMYXdn0=; b=Gr3K/N7XBgUCoNiGsaC0ipdxEA+6bfqECKTZbbwwsbGLcTMBuEWdVkJjJ9esDN/fFH BCjXtI2nX5DF5kKLFdQTxte8OATmqhy4HBvXp+Td19pXqI/a2Vjwx0N2806u2r1AIxkO 9kQzv2xo0OTTcOuxTsjM1gEC+72ps/Pnj8IV8SuPQOgFV+sUqs8y44TF+MrCjnlwTLvX XqCYHVOJLSpSA8q5SyCPnrIeME+JTdH1+E0CvONBJayqPHlK2AUZDoxqmMlTHIsb8VRy kFZGFTxkeQdUUFiUnVI3GpOfm5pJO8fjOvEm/OEzQvO9VEdmv+VASxKdMn4jXqHp5esv CLsA== X-Gm-Message-State: AC+VfDwHA825SOcxAkUveC/6dYV67hIuZGPDzZsM7haxQEhxiUbnoy+O YggIQIE9pYcIkA83A8x2Oba/IYzSvBs= X-Received: by 2002:a17:903:258c:b0:1b2:499f:674f with SMTP id jb12-20020a170903258c00b001b2499f674fmr264661plb.25.1686290972855; Thu, 08 Jun 2023 23:09:32 -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 x1-20020a170902b40100b001a804b16e38sm2390528plr.150.2023.06.08.23.09.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Jun 2023 23:09:31 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id E71BF11403A4; Fri, 9 Jun 2023 15:39:27 +0930 (ACST) Date: Fri, 9 Jun 2023 15:39:27 +0930 To: binutils@sourceware.org Subject: ecoff find_nearest_line and final link leaks Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-3034.6 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-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: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1768204261197093460?= X-GMAIL-MSGID: =?utf-8?q?1768204261197093460?= Freeing ecoff_debug_info "pointers to the unswapped symbolic info" isn't a simple matter, due to differing allocation strategies. In _bfd_ecoff_slurp_symbolic_info the pointers are to objalloc memory. In the ecoff linker they are to separately malloc'd memory. In gas we have most (obj-elf) or all (obj-ecoff) into a single malloc'd buffer. This patch fixes the leaks for binutils and ld, leaving the gas leaks for another day. The mips elf backend already had this covered, and the ecoff backend had a pointer, raw_syments used as a flag, so most of the patch is moving these around a little so they are accessible for both ecoff and elf. include/ * coff/ecoff.h (struct ecoff_debug_info): Add alloc_syments. bfd/ * libecoff.h (struct ecoff_tdata): Delete raw_syments. * elfxx-mips.c (free_ecoff_debug): Delete. Replace uses with _bfd_ecoff_free_ecoff_debug_info. (_bfd_mips_elf_final_link): Init debug.alloc_syments. * ecofflink.c (_bfd_ecoff_free_ecoff_debug_info): New function. * ecoff.c (_bfd_ecoff_bfd_free_cached_info): Call _bfd_ecoff_free_ecoff_debug_info. (_bfd_ecoff_slurp_symbolic_info): Replace uses of raw_syments with alloc_syments. (ecoff_final_link_debug_accumulate): Likewise. Use _bfd_ecoff_free_ecoff_debug_info. (_bfd_ecoff_bfd_copy_private_bfd_data): Set alloc_syments for copied output. * elf64-alpha.c (elf64_alpha_read_ecoff_info): Use _bfd_ecoff_free_ecoff_debug_info. * libbfd-in.h (_bfd_ecoff_free_ecoff_debug_info): Declare. * libbfd.h: Regenerate. gas/ * config/obj-ecoff.c (ecoff_frob_file): Set alloc_syments. * config/obj-elf.c (elf_frob_file_after_relocs): Likewise. diff --git a/bfd/ecoff.c b/bfd/ecoff.c index f2626c541e2..522a4425e61 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -117,12 +117,15 @@ _bfd_ecoff_bfd_free_cached_info (bfd *abfd) if ((bfd_get_format (abfd) == bfd_object || bfd_get_format (abfd) == bfd_core) && (tdata = ecoff_data (abfd)) != NULL) - while (tdata->mips_refhi_list != NULL) - { - struct mips_hi *ref = tdata->mips_refhi_list; - tdata->mips_refhi_list = ref->next; - free (ref); - } + { + while (tdata->mips_refhi_list != NULL) + { + struct mips_hi *ref = tdata->mips_refhi_list; + tdata->mips_refhi_list = ref->next; + free (ref); + } + _bfd_ecoff_free_ecoff_debug_info (&tdata->debug_info); + } return _bfd_generic_bfd_free_cached_info (abfd); } @@ -524,7 +527,7 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd, /* Check whether we've already gotten it, and whether there's any to get. */ - if (ecoff_data (abfd)->raw_syments != NULL) + if (debug->alloc_syments) return true; if (ecoff_data (abfd)->sym_filepos == 0) { @@ -595,7 +598,7 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd, if (raw == NULL) return false; - ecoff_data (abfd)->raw_syments = raw; + debug->alloc_syments = true; /* Get pointers for the numeric offsets in the HDRR structure. */ #define FIX(start, count, ptr, type) \ @@ -1918,6 +1921,9 @@ _bfd_ecoff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd; oinfo->external_rfd = iinfo->external_rfd; + + /* Flag that oinfo entries should not be freed. */ + oinfo->alloc_syments = true; } else { @@ -3809,9 +3815,9 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd, ((char *) debug->ptr)[amt] = 0; \ } while (0) - /* If raw_syments is not NULL, then the data was already by read by + /* If alloc_syments is true, then the data was already by read by _bfd_ecoff_slurp_symbolic_info. */ - if (ecoff_data (input_bfd)->raw_syments == NULL) + if (!debug->alloc_syments) { READ (line, cbLineOffset, cbLine, sizeof (unsigned char)); READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size); @@ -3833,31 +3839,7 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd, input_bfd, debug, swap, info)); return_something: - if (ecoff_data (input_bfd)->raw_syments == NULL) - { - free (debug->line); - free (debug->external_dnr); - free (debug->external_pdr); - free (debug->external_sym); - free (debug->external_opt); - free (debug->external_aux); - free (debug->ss); - free (debug->external_fdr); - free (debug->external_rfd); - - /* Make sure we don't accidentally follow one of these pointers - into freed memory. */ - debug->line = NULL; - debug->external_dnr = NULL; - debug->external_pdr = NULL; - debug->external_sym = NULL; - debug->external_opt = NULL; - debug->external_aux = NULL; - debug->ss = NULL; - debug->external_fdr = NULL; - debug->external_rfd = NULL; - } - + _bfd_ecoff_free_ecoff_debug_info (debug); return ret; } diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c index bba25929f2c..5b7acd57a1a 100644 --- a/bfd/ecofflink.c +++ b/bfd/ecofflink.c @@ -1696,6 +1696,38 @@ bfd_ecoff_write_accumulated_debug (void * handle, /* Handle the find_nearest_line function for both ECOFF and MIPS ELF files. */ +/* Free ECOFF debugging info used by find_nearest_line. */ + +void +_bfd_ecoff_free_ecoff_debug_info (struct ecoff_debug_info *debug) +{ + if (!debug->alloc_syments) + { + free (debug->line); + free (debug->external_dnr); + free (debug->external_pdr); + free (debug->external_sym); + free (debug->external_opt); + free (debug->external_aux); + free (debug->ss); + free (debug->ssext); + free (debug->external_fdr); + free (debug->external_rfd); + free (debug->external_ext); + } + debug->line= NULL; + debug->external_dnr= NULL; + debug->external_pdr= NULL; + debug->external_sym= NULL; + debug->external_opt= NULL; + debug->external_aux= NULL; + debug->ss= NULL; + debug->ssext= NULL; + debug->external_fdr= NULL; + debug->external_rfd= NULL; + debug->external_ext= NULL; +} + /* Compare FDR entries. This is called via qsort. */ static int diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 5cf9a665ae5..125379b4f88 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -1425,17 +1425,7 @@ elf64_alpha_read_ecoff_info (bfd *abfd, asection *section, error_return: free (ext_hdr); - free (debug->line); - free (debug->external_dnr); - free (debug->external_pdr); - free (debug->external_sym); - free (debug->external_opt); - free (debug->external_aux); - free (debug->ss); - free (debug->ssext); - free (debug->external_fdr); - free (debug->external_rfd); - free (debug->external_ext); + _bfd_ecoff_free_ecoff_debug_info (debug); return false; } diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 7d29ec2d105..a618f6f1249 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -1389,35 +1389,6 @@ struct mips_elf_find_line struct ecoff_find_line i; }; -/* Free ECOFF debugging info used by find_nearest_line. */ - -static void -free_ecoff_debug (struct ecoff_debug_info *debug) -{ - free (debug->line); - free (debug->external_dnr); - free (debug->external_pdr); - free (debug->external_sym); - free (debug->external_opt); - free (debug->external_aux); - free (debug->ss); - free (debug->ssext); - free (debug->external_fdr); - free (debug->external_rfd); - free (debug->external_ext); - debug->line = NULL; - debug->external_dnr = NULL; - debug->external_pdr = NULL; - debug->external_sym = NULL; - debug->external_opt = NULL; - debug->external_aux = NULL; - debug->ss = NULL; - debug->ssext = NULL; - debug->external_fdr = NULL; - debug->external_rfd = NULL; - debug->external_ext = NULL; -} - bool _bfd_mips_elf_free_cached_info (bfd *abfd) { @@ -1435,7 +1406,7 @@ _bfd_mips_elf_free_cached_info (bfd *abfd) free (hi); } if (tdata->find_line_info != NULL) - free_ecoff_debug (&tdata->find_line_info->d); + _bfd_ecoff_free_ecoff_debug_info (&tdata->find_line_info->d); } return _bfd_elf_free_cached_info (abfd); } @@ -1523,7 +1494,7 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section, error_return: free (ext_hdr); - free_ecoff_debug (debug); + _bfd_ecoff_free_ecoff_debug_info (debug); return false; } @@ -13225,7 +13196,7 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols, fi->d.fdr = bfd_alloc (abfd, amt); if (fi->d.fdr == NULL) { - free_ecoff_debug (&fi->d); + _bfd_ecoff_free_ecoff_debug_info (&fi->d); msec->flags = origflags; return false; } @@ -15043,6 +15014,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* We accumulate the debugging information itself in the debug_info structure. */ + debug.alloc_syments = false; debug.line = NULL; debug.external_dnr = NULL; debug.external_pdr = NULL; @@ -15128,7 +15100,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) (mdebug_handle, abfd, &debug, swap, input_bfd, &input_debug, input_swap, info))) { - free_ecoff_debug (&input_debug); + _bfd_ecoff_free_ecoff_debug_info (&input_debug); return false; } @@ -15171,7 +15143,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) } /* Free up the information we just read. */ - free_ecoff_debug (&input_debug); + _bfd_ecoff_free_ecoff_debug_info (&input_debug); /* Hack: reset the SEC_HAS_CONTENTS flag so that elf_link_input_bfd ignores this section. */ diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index ae1b61aa4e3..03ae099c2ea 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -787,6 +787,8 @@ struct ecoff_debug_swap; struct ecoff_extr; struct ecoff_find_line; +extern void _bfd_ecoff_free_ecoff_debug_info + (struct ecoff_debug_info *debug); extern bool _bfd_ecoff_locate_line (bfd *, asection *, bfd_vma, struct ecoff_debug_info * const, const struct ecoff_debug_swap * const, struct ecoff_find_line *, diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 92fbf0195ee..a9fa1111a3d 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -793,6 +793,8 @@ struct ecoff_debug_swap; struct ecoff_extr; struct ecoff_find_line; +extern void _bfd_ecoff_free_ecoff_debug_info + (struct ecoff_debug_info *debug); extern bool _bfd_ecoff_locate_line (bfd *, asection *, bfd_vma, struct ecoff_debug_info * const, const struct ecoff_debug_swap * const, struct ecoff_find_line *, diff --git a/bfd/libecoff.h b/bfd/libecoff.h index 0c4bb43c39a..2267c7bc53b 100644 --- a/bfd/libecoff.h +++ b/bfd/libecoff.h @@ -124,9 +124,6 @@ typedef struct ecoff_tdata /* The ECOFF symbolic debugging information. */ struct ecoff_debug_info debug_info; - /* The unswapped ECOFF symbolic information. */ - void * raw_syments; - /* The canonical BFD symbols. */ struct ecoff_symbol_struct *canonical_symbols; diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c index 092f6f2c927..26da2af01b3 100644 --- a/gas/config/obj-ecoff.c +++ b/gas/config/obj-ecoff.c @@ -151,6 +151,7 @@ ecoff_frob_file (void) ecoff_build_debug (hdr, &buf, debug_swap); /* Finish up the ecoff_tdata structure. */ + ecoff_data (stdoutput)->debug_info.alloc_syments = true; set = buf; #define SET(ptr, count, type, size) \ if (hdr->count == 0) \ diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index bf3ef541ab7..753a929fb14 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -3008,6 +3008,7 @@ elf_frob_file_after_relocs (void) ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap); /* Set up the pointers in debug. */ + debug.alloc_syments = true; #define SET(ptr, offset, type) \ debug.ptr = (type) (buf + debug.symbolic_header.offset) diff --git a/include/coff/ecoff.h b/include/coff/ecoff.h index 169d8f6918d..991d92f92dd 100644 --- a/include/coff/ecoff.h +++ b/include/coff/ecoff.h @@ -299,7 +299,10 @@ struct ecoff_debug_info all pointers to arrays, not single structures. They will be NULL if there are no instances of the relevant structure. These fields are also used by the assembler to output ECOFF debugging - information. */ + information. If alloc_syments is true then the pointers are to + objalloc memory, or into a single malloc'd buffer, or otherwise + should not be freed. */ + bool alloc_syments; unsigned char *line; void *external_dnr; /* struct dnr_ext */ void *external_pdr; /* struct pdr_ext */