From patchwork Mon Aug 28 13:43:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 137036 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a7d1:0:b0:3f2:4152:657d with SMTP id p17csp3338431vqm; Mon, 28 Aug 2023 06:43:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHxzEfAZL6V9PAivLOUmy82FwHB22mmlnCYPHYy/sckLnT37AgJnKH98VHZgKHLIf/Up0XZ X-Received: by 2002:ac2:533c:0:b0:500:78ee:4d03 with SMTP id f28-20020ac2533c000000b0050078ee4d03mr16419102lfh.69.1693230201945; Mon, 28 Aug 2023 06:43:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693230201; cv=none; d=google.com; s=arc-20160816; b=l15oosNxnv3OXvoqJWUsvoC9AOO+I+nx7Hp6xfF6sJ2hEjuCoynptt+eibYt7aPKHt 8K3W7SIbZ/F9aPcTGOk6OLH4voB4J3lewFGq9jVm/ADqGJWqTR6hm8mGAL2BGXmy9cRB BQ0gQw1qKWfd+AybsBWoL5RGg3HAbtFzb66cVfsfI79M2zR0mNYVCswwj+grjRJ0nyDo qEmJj3fxicYBQ2EHc41RZrVIRtSAs0P4SNPfZV1DMXcAcMxLrryELl5mUh1+3zUxoblE Z0roKvY6rgvK+aY9arCeGtvUZ2aveGF2oBXbjqPCXITPQ46tgY4ttdheODeJgMdwHdQD z1KA== 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=4+kkRzO5TyGrwH5/5V/cZWKTgzdNTe0Jp/xRaR5/Jps=; fh=NLxAvL/bDfPg4AGOtxqvQlND8vazkZrNzKLY8+LAbBY=; b=bU4r46jMHpa6FDhH8PDaznbeBkOnUkobqzSHM5Pc4b5HgaX/S2mgXUjNDfMiXha3KL /52kNhUuBTbs7KJOSIAnAU5ToblEIKTeY6fB7DGxE3y7HYqDtDWBJoEOL1cdpoGVzfcl yL1qCrbwvyxtsdjPFa1JfPGEfPscYsRv8HmycdujprrGz9EIcw/ign8l3TIz2Qd38hDB jyUdQYMoXFJZwiWhIcmZO1rMwP62jeNmYzGWmzgez+lQef/XdcHeMw5HmuLIR5faIpBo Lq0Tu6XZU0p+KhAWUa9lPuY9riZswXUJeHcdb29dQ+1s9RusSpeHy5ZEvrtH825rIyOp BFBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=IdqaqjeH; 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 (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id x8-20020a170906148800b0099bd655b725si4251497ejc.781.2023.08.28.06.43.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Aug 2023 06:43:21 -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=IdqaqjeH; 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 B28293858402 for ; Mon, 28 Aug 2023 13:43:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B28293858402 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1693230200; bh=4+kkRzO5TyGrwH5/5V/cZWKTgzdNTe0Jp/xRaR5/Jps=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=IdqaqjeHRcgL6S8TTuIwTr/A3pz0L5Jj/H6mmrzJt2BW88Nrtxvqu01ikOAf0FFRM vShyCXSlUmz8MuQl0xSAW4xrr5CBEUO2mGP7UqaKAhfgnCqgEK96lV5CF92yKKqZj/ C2VKueOrhJpYzvxuGuvTxRGGYB/0xYhoNoBzyFig= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-oi1-x22d.google.com (mail-oi1-x22d.google.com [IPv6:2607:f8b0:4864:20::22d]) by sourceware.org (Postfix) with ESMTPS id 803D23858D33 for ; Mon, 28 Aug 2023 13:43:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 803D23858D33 Received: by mail-oi1-x22d.google.com with SMTP id 5614622812f47-3a88ef9444bso2347779b6e.1 for ; Mon, 28 Aug 2023 06:43:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693230189; x=1693834989; 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=4+kkRzO5TyGrwH5/5V/cZWKTgzdNTe0Jp/xRaR5/Jps=; b=GOUo2vhyVDobUP9I8mWN/Hnr9AA7D2v6//MB3M/51IFzVcLUJJ7l+5sK6iAeU49nuR FvoivBPCX3Mthzc6o2dCvAwm1nvY8y+rJvwMihmdGTwPEkSuOLH+aKR8vTh2cqOBqn3e lg5c7DNIv0a2v8ibVpYLnd/oL8v7z35B+9GC2XbRahJUZTPaXn/m4ylONtQbdl/MBuQ5 4gYp72h29ONcLvInhIUivRaZn1uHY2RtzEDdMNhyjqD4PB90VCLwsN4hfy5qwf5K2W1/ I2phipRy4+oN4dcZuRw2DvgxM0Fk1aT//C8X49Zf58lSe+ZEE6s8Db4ULdJpLAMDl4jh hwbA== X-Gm-Message-State: AOJu0YzIvYvg+9jLGzlrUBFisFdp4o70e1IYFPiplPpxfBtM7QkAeiNc ST/ZMm7ZezFvAmcJkrlo1c2Cf8xjfWoomw== X-Received: by 2002:a05:6358:9924:b0:135:4003:7851 with SMTP id w36-20020a056358992400b0013540037851mr30934857rwa.19.1693230189085; Mon, 28 Aug 2023 06:43:09 -0700 (PDT) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:81e6:71c9:6d9f:1b5]) by smtp.gmail.com with ESMTPSA id f26-20020a63755a000000b0056c3a4a3ca5sm7193386pgn.36.2023.08.28.06.43.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Aug 2023 06:43:08 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 4A09111423B8; Mon, 28 Aug 2023 23:13:06 +0930 (ACST) Date: Mon, 28 Aug 2023 23:13:06 +0930 To: binutils@sourceware.org Subject: COFF swap_aux_in Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-3033.7 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: 1775480552350012072 X-GMAIL-MSGID: 1775480552350012072 A low level function like coff_swap_aux_in really has no business concatenating multiple auxents for the old PE multi-aux scheme of handling long file names. In doing so, it assumes multiple internal auxent buffers are available, which they are not in most calls to bfd_coff_swap_aux_in, both inside BFD and outside, eg. GDB. Buffer overflow fun. Concatenating multiple auxents belongs at a higher level. This required some changes to coff_get_normalized_symtab, which now uses the external auxents to access the concatenated file name. (Internal auxents are larger than the x_fname array, so the pieces of the file name are not adjacent as they are in the external auxents.) * coffswap.h (coff_swap_aux_in): Do not write more than one internal auxent. * coffcode.h (coff_bigobj_swap_aux_in): Likewise. * coffgen.c (coff_get_normalized_symtab): Normalize strings after swapping in each symbol so that external auxents are available. Use external auxents for multi-aux long file names. Formatting. Wrap long lines. Remove excess parens and unnecessary casts. Don't zalloc when only the string terminator needs zeroing, and memcpy rather than strncpy. Delete unnecessary sanity check with unsigned _n_offset. Return with failure if debug section can't be read, to avoid trying to read it multiple times. Correct sanity check against debug section size. diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 908dc93c64a..0487555dda1 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -5813,8 +5813,8 @@ coff_bigobj_swap_aux_in (bfd *abfd, void * ext1, int type, int in_class, - int indx, - int numaux, + int indx ATTRIBUTE_UNUSED, + int numaux ATTRIBUTE_UNUSED, void * in1) { AUXENT_BIGOBJ *ext = (AUXENT_BIGOBJ *) ext1; @@ -5826,14 +5826,7 @@ coff_bigobj_swap_aux_in (bfd *abfd, switch (in_class) { case C_FILE: - if (numaux > 1) - { - if (indx == 0) - memcpy (in->x_file.x_n.x_fname, ext->File.Name, - numaux * sizeof (AUXENT_BIGOBJ)); - } - else - memcpy (in->x_file.x_n.x_fname, ext->File.Name, sizeof (ext->File.Name)); + memcpy (in->x_file.x_n.x_fname, ext->File.Name, sizeof (ext->File.Name)); break; case C_STAT: diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 91667267cbc..c1aacc707b5 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1843,8 +1843,6 @@ coff_get_normalized_symtab (bfd *abfd) { combined_entry_type *internal; combined_entry_type *internal_ptr; - combined_entry_type *symbol_ptr; - combined_entry_type *internal_end; size_t symesz; char *raw_src; char *raw_end; @@ -1867,7 +1865,6 @@ coff_get_normalized_symtab (bfd *abfd) internal = (combined_entry_type *) bfd_zalloc (abfd, size); if (internal == NULL && size != 0) return NULL; - internal_end = internal + obj_raw_syment_count (abfd); raw_src = (char *) obj_coff_external_syms (abfd); @@ -1887,48 +1884,32 @@ coff_get_normalized_symtab (bfd *abfd) bfd_coff_swap_sym_in (abfd, (void *) raw_src, (void *) & internal_ptr->u.syment); - symbol_ptr = internal_ptr; internal_ptr->is_sym = true; + combined_entry_type *sym = internal_ptr; /* PR 17512: Prevent buffer overrun. */ - if (symbol_ptr->u.syment.n_numaux > ((raw_end - 1) - raw_src) / symesz) + if (sym->u.syment.n_numaux > ((raw_end - 1) - raw_src) / symesz) return NULL; - for (i = 0; - i < symbol_ptr->u.syment.n_numaux; - i++) + for (i = 0; i < sym->u.syment.n_numaux; i++) { internal_ptr++; raw_src += symesz; bfd_coff_swap_aux_in (abfd, (void *) raw_src, - symbol_ptr->u.syment.n_type, - symbol_ptr->u.syment.n_sclass, - (int) i, symbol_ptr->u.syment.n_numaux, + sym->u.syment.n_type, + sym->u.syment.n_sclass, + (int) i, sym->u.syment.n_numaux, &(internal_ptr->u.auxent)); internal_ptr->is_sym = false; - coff_pointerize_aux (abfd, internal, symbol_ptr, i, internal_ptr); + coff_pointerize_aux (abfd, internal, sym, i, internal_ptr); } - } - /* Free the raw symbols. */ - if (obj_coff_external_syms (abfd) != NULL - && ! obj_coff_keep_syms (abfd)) - { - free (obj_coff_external_syms (abfd)); - obj_coff_external_syms (abfd) = NULL; - } - - for (internal_ptr = internal; internal_ptr < internal_end; - internal_ptr++) - { - BFD_ASSERT (internal_ptr->is_sym); - - if (internal_ptr->u.syment.n_sclass == C_FILE - && internal_ptr->u.syment.n_numaux > 0) + if (sym->u.syment.n_sclass == C_FILE + && sym->u.syment.n_numaux > 0) { - combined_entry_type * aux = internal_ptr + 1; + combined_entry_type * aux = sym + 1; /* Make a file symbol point to the name in the auxent, since the text ".file" is redundant. */ @@ -1944,12 +1925,12 @@ coff_get_normalized_symtab (bfd *abfd) return NULL; } - if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset) + if ((bfd_size_type) aux->u.auxent.x_file.x_n.x_n.x_offset >= obj_coff_strings_len (abfd)) - internal_ptr->u.syment._n._n_n._n_offset = + sym->u.syment._n._n_n._n_offset = (uintptr_t) _(""); else - internal_ptr->u.syment._n._n_n._n_offset = + sym->u.syment._n._n_n._n_offset = (uintptr_t) (string_table + aux->u.auxent.x_file.x_n.x_n.x_offset); } @@ -1958,30 +1939,35 @@ coff_get_normalized_symtab (bfd *abfd) /* Ordinary short filename, put into memory anyway. The Microsoft PE tools sometimes store a filename in multiple AUX entries. */ - if (internal_ptr->u.syment.n_numaux > 1 && obj_pe (abfd)) - internal_ptr->u.syment._n._n_n._n_offset = - ((uintptr_t) - copy_name (abfd, - aux->u.auxent.x_file.x_n.x_fname, - internal_ptr->u.syment.n_numaux * symesz)); + size_t len; + char *src; + if (sym->u.syment.n_numaux > 1 && obj_pe (abfd)) + { + len = sym->u.syment.n_numaux * symesz; + src = raw_src - (len - symesz); + } else - internal_ptr->u.syment._n._n_n._n_offset = - ((uintptr_t) - copy_name (abfd, - aux->u.auxent.x_file.x_n.x_fname, - (size_t) bfd_coff_filnmlen (abfd))); + { + len = bfd_coff_filnmlen (abfd); + src = aux->u.auxent.x_file.x_n.x_fname; + } + sym->u.syment._n._n_n._n_offset = + (uintptr_t) copy_name (abfd, src, len); } /* Normalize other strings available in C_FILE aux entries. */ if (!obj_pe (abfd)) - for (int numaux = 1; numaux < internal_ptr->u.syment.n_numaux; numaux++) + for (int numaux = 1; + numaux < sym->u.syment.n_numaux; + numaux++) { - aux = internal_ptr + numaux + 1; + aux = sym + numaux + 1; BFD_ASSERT (! aux->is_sym); if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0) { - /* The string information is a long one, point into the string table. */ + /* The string information is a long one, point + into the string table. */ if (string_table == NULL) { string_table = _bfd_coff_read_string_table (abfd); @@ -1989,48 +1975,48 @@ coff_get_normalized_symtab (bfd *abfd) return NULL; } - if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset) + if ((bfd_size_type) aux->u.auxent.x_file.x_n.x_n.x_offset >= obj_coff_strings_len (abfd)) aux->u.auxent.x_file.x_n.x_n.x_offset = (uintptr_t) _(""); else aux->u.auxent.x_file.x_n.x_n.x_offset = (uintptr_t) (string_table - + (aux->u.auxent.x_file.x_n.x_n.x_offset)); + + aux->u.auxent.x_file.x_n.x_n.x_offset); } else aux->u.auxent.x_file.x_n.x_n.x_offset = ((uintptr_t) copy_name (abfd, aux->u.auxent.x_file.x_n.x_fname, - (size_t) bfd_coff_filnmlen (abfd))); + bfd_coff_filnmlen (abfd))); } } else { - if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) + if (sym->u.syment._n._n_n._n_zeroes != 0) { /* This is a "short" name. Make it long. */ - size_t i; char *newstring; /* Find the length of this string without walking into memory that isn't ours. */ - for (i = 0; i < 8; ++i) - if (internal_ptr->u.syment._n._n_name[i] == '\0') + for (i = 0; i < SYMNMLEN; ++i) + if (sym->u.syment._n._n_name[i] == '\0') break; - newstring = (char *) bfd_zalloc (abfd, (bfd_size_type) (i + 1)); + newstring = bfd_alloc (abfd, i + 1); if (newstring == NULL) return NULL; - strncpy (newstring, internal_ptr->u.syment._n._n_name, i); - internal_ptr->u.syment._n._n_n._n_offset = (uintptr_t) newstring; - internal_ptr->u.syment._n._n_n._n_zeroes = 0; + memcpy (newstring, sym->u.syment._n._n_name, i); + newstring[i] = 0; + sym->u.syment._n._n_n._n_offset = (uintptr_t) newstring; + sym->u.syment._n._n_n._n_zeroes = 0; } - else if (internal_ptr->u.syment._n._n_n._n_offset == 0) - internal_ptr->u.syment._n._n_n._n_offset = (uintptr_t) ""; - else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment)) + else if (sym->u.syment._n._n_n._n_offset == 0) + sym->u.syment._n._n_n._n_offset = (uintptr_t) ""; + else if (!bfd_coff_symname_in_debug (abfd, &sym->u.syment)) { /* Long name already. Point symbol at the string in the table. */ @@ -2040,43 +2026,47 @@ coff_get_normalized_symtab (bfd *abfd) if (string_table == NULL) return NULL; } - if (internal_ptr->u.syment._n._n_n._n_offset >= obj_coff_strings_len (abfd) - || string_table + internal_ptr->u.syment._n._n_n._n_offset < string_table) - internal_ptr->u.syment._n._n_n._n_offset = + if (sym->u.syment._n._n_n._n_offset >= obj_coff_strings_len (abfd)) + sym->u.syment._n._n_n._n_offset = (uintptr_t) _(""); else - internal_ptr->u.syment._n._n_n._n_offset = - ((uintptr_t) (string_table - + internal_ptr->u.syment._n._n_n._n_offset)); + sym->u.syment._n._n_n._n_offset = + (uintptr_t) (string_table + + sym->u.syment._n._n_n._n_offset); } else { /* Long name in debug section. Very similar. */ if (debug_sec_data == NULL) - debug_sec_data = build_debug_section (abfd, & debug_sec); - if (debug_sec_data != NULL) { - BFD_ASSERT (debug_sec != NULL); - /* PR binutils/17512: Catch out of range offsets into the debug data. */ - if (internal_ptr->u.syment._n._n_n._n_offset > debug_sec->size - || debug_sec_data + internal_ptr->u.syment._n._n_n._n_offset < debug_sec_data) - internal_ptr->u.syment._n._n_n._n_offset = - (uintptr_t) _(""); - else - internal_ptr->u.syment._n._n_n._n_offset = - (uintptr_t) (debug_sec_data - + internal_ptr->u.syment._n._n_n._n_offset); + debug_sec_data = build_debug_section (abfd, &debug_sec); + if (debug_sec_data == NULL) + return NULL; } + /* PR binutils/17512: Catch out of range offsets into + the debug data. */ + if (sym->u.syment._n._n_n._n_offset >= debug_sec->size) + sym->u.syment._n._n_n._n_offset = + (uintptr_t) _(""); else - internal_ptr->u.syment._n._n_n._n_offset = (uintptr_t) ""; + sym->u.syment._n._n_n._n_offset = + (uintptr_t) (debug_sec_data + + sym->u.syment._n._n_n._n_offset); } } - internal_ptr += internal_ptr->u.syment.n_numaux; + } + + /* Free the raw symbols. */ + if (obj_coff_external_syms (abfd) != NULL + && ! obj_coff_keep_syms (abfd)) + { + free (obj_coff_external_syms (abfd)); + obj_coff_external_syms (abfd) = NULL; } obj_raw_syments (abfd) = internal; BFD_ASSERT (obj_raw_syment_count (abfd) - == (unsigned int) (internal_ptr - internal)); + == (size_t) (internal_ptr - internal)); return internal; } diff --git a/bfd/coffswap.h b/bfd/coffswap.h index 190b8f02a0b..f0677ff8857 100644 --- a/bfd/coffswap.h +++ b/bfd/coffswap.h @@ -402,8 +402,8 @@ coff_swap_aux_in (bfd *abfd, void * ext1, int type, int in_class, - int indx, - int numaux, + int indx ATTRIBUTE_UNUSED, + int numaux ATTRIBUTE_UNUSED, void * in1) { AUXENT *ext = (AUXENT *) ext1; @@ -426,14 +426,7 @@ coff_swap_aux_in (bfd *abfd, #if FILNMLEN != E_FILNMLEN #error we need to cope with truncating or extending FILNMLEN #else - if (numaux > 1 && obj_pe (abfd)) - { - if (indx == 0) - memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, - numaux * sizeof (AUXENT)); - } - else - memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN); + memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN); #endif } goto end;