From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by sourceware.org (Postfix) with ESMTPS id 41ACA3858D28 for ; Sat, 24 Sep 2022 02:08:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 41ACA3858D28 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-pl1-x630.google.com with SMTP id l10so1639080plb.10 for ; Fri, 23 Sep 2022 19:08:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date; bh=UgArMnJcI2G1CmCvy+Ne5CfnrN8rZ4J0OX0UMAtwxmE=; b=I10SrGi4mKk/TKN2i6emeuJ/FdtFR/A77RsQIYreypDZrdM99OilgG00l6ITLvWF99 12zpdEJX9XlLVa1TZq6Kd9Ultuqnpdly8u5IGnp9y7SA/RvaG23AwaBcZHaalNm+cQ8J 1gGn14w1JxXsgopMT7K1VryGKilvTVTxPdczAUpVliJcWYj0KyYZBp/M1pbpOtsgU9W2 Ql6u3NkFRIF3kdTe8wpLF4n4K2FGYIHQ/DT0hIgWoCWf2yjR+DXqNxGSLiM5u1/liuXp ifZMm8AWYwUlGE4ml5M22Vi8vpeMD7AtsjJqJsJ9jK+r2KSKWdAaEkW/qkOpkDhFcjPO Aqig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date; bh=UgArMnJcI2G1CmCvy+Ne5CfnrN8rZ4J0OX0UMAtwxmE=; b=NN9GpV+JRk/5MiyjS5k/fGB6hSnnCcH5OKxlEz0cdq6w+Ees5HL9aBYvxdzc9uNddz JS3MKl85nNn2osQ1oK1aj1qpM5QwN4RDQDNLjBOcQcM5sFSFIcdgXXIlOgda0UWVjyln Ds46Blmr+WKqSYYeefXbOk+IRWdSX+f6XEfyqJfICKG6rM08pVzSwAQkASgi0F9IfKuK TchmBZTXCfNmbMUqAZMXhXQtjTnqkm66Ovfc8Kk9DrI2PzPR2JZ/x5DUJ8t6Fg1UzhKa wLr7n07I6jW8V58VRBsdrzQT+cDoltBznnmjPJqIM8NAxuGBIGOW8q18zt49F4ERD6Nq Zsbg== X-Gm-Message-State: ACrzQf1qYC4OkSOwvEM221+yYl6v5vuufGjQ6TxUaY5KN/aH/A4E3U5M lMEcmBi0FbBxwwLm3rGMum2FrBKXIX4= X-Google-Smtp-Source: AMsMyM4kYTuC3adF5pPBEZaZrp7Q/NWZaCAx60TcsvbL07PNp9bUgAgKayhaz1wOu4nRIgCuxdakbQ== X-Received: by 2002:a17:90b:3e8c:b0:202:c7b1:b20b with SMTP id rj12-20020a17090b3e8c00b00202c7b1b20bmr12577156pjb.54.1663985289011; Fri, 23 Sep 2022 19:08:09 -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 p19-20020a170902a41300b0016bb24f5d19sm6562061plq.209.2022.09.23.19.08.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Sep 2022 19:08:08 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id ED3FD11404B4; Sat, 24 Sep 2022 11:38:05 +0930 (ACST) Date: Sat, 24 Sep 2022 11:38:05 +0930 From: Alan Modra To: binutils@sourceware.org Subject: The problem with warning in elf_object_p Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3036.4 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 List-Id: elfcode.h can emit three warnings in elf_object_p for various things, "section extending past end of file", "corrupt string table index", and "program header with invalid alignment". The problem with doing this is that the warning can be emitted for multiple possible targets as each one is tried. I was looking at a fuzzer testcase that had an object file with 6144 program headers, 5316 of which had invalid alignment. It would be bad enough to get 5316 messages all the same, but this object was contained in an archive and resulted in 4975776 repeats! Some trimming can be done by not warning if the bfd is already marked read_only, as is done for the "section extending past end of file" warning, but that still results in an unacceptable number of warnings for object files in archives. Besides that, it is just wrong to warn about a problem detected by a target elf_object_p other than the one that actually matches. At some point we might have more target specific warnings. So what to do? One obvious solution is to remove the warnings. Another is to poke any warning strings into the target xvec, emitting them if that xvec is the final one chosen. This also has the benefit of solving the archive problem. A warning when recursing into _bfd_check_format for the first element of the archive (to find the correct target for the archive) will still be on the xvec at the point that target is chosen for the archive. However, target xvecs are read-only. Thus the need for per_xvec_warn to logically extend bfd_target with a writable field. I've made per_xvec_warn one larger than bfd_target_vector to provide one place for user code that makes private copies of target xvecs. * elfcode.h (elf_swap_shdr_in, elf_object_p): Stash potential warnings in _bfd_per_xvec_warn location. * format.c (clear_warnmsg): New function. (bfd_check_format_matches): Call clear_warnmsg before trying a new xvec. Print warnings for the successful non-archive match. * targets.c: Include libiberty.h. (_bfd_target_vector_entries): Use ARRAY_SIZE. (per_xvec_warn): New. (_bfd_per_xvec_warn): New function. * Makefile.am (LIBBFD_H_FILES): Add targets.c. * Makefile.in: Regenerate. * libbfd.h: Regenerate. diff --git a/bfd/Makefile.am b/bfd/Makefile.am index c23dff6cac3..a5652b2a9c7 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -927,7 +927,7 @@ BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c \ linker.c simple.c compress.c BFD64_H_FILES = archive64.c LIBBFD_H_FILES = libbfd-in.h libbfd.c bfdio.c bfdwin.c \ - cache.c reloc.c archures.c linker.c + cache.c reloc.c targets.c archures.c linker.c LIBCOFF_H_FILES = libcoff-in.h coffcode.h headers: stmp-bin2-h stmp-lbfd-h stmp-lcoff-h diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 82843d2d61d..83d686529a0 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -1214,7 +1214,7 @@ BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c \ BFD64_H_FILES = archive64.c LIBBFD_H_FILES = libbfd-in.h libbfd.c bfdio.c bfdwin.c \ - cache.c reloc.c archures.c linker.c + cache.c reloc.c targets.c archures.c linker.c LIBCOFF_H_FILES = libcoff-in.h coffcode.h diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 39c84b4d0fd..1392240f481 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -323,11 +323,11 @@ elf_swap_shdr_in (bfd *abfd, if (filesize != 0 && ((ufile_ptr) dst->sh_offset > filesize - || dst->sh_size > filesize - dst->sh_offset)) + || dst->sh_size > filesize - dst->sh_offset) + && !abfd->read_only) { - if (!abfd->read_only) - _bfd_error_handler (_("warning: %pB has a section " - "extending past end of file"), abfd); + const char **warn = _bfd_per_xvec_warn (abfd->xvec); + *warn = _("warning: %pB has a section extending past end of file"); abfd->read_only = 1; } } @@ -771,10 +771,12 @@ elf_object_p (bfd *abfd) So we are kind, and reset the string index value to 0 so that at least some processing can be done. */ i_ehdrp->e_shstrndx = SHN_UNDEF; - abfd->read_only = 1; - _bfd_error_handler - (_("warning: %pB has a corrupt string table index - ignoring"), - abfd); + if (!abfd->read_only) + { + const char **warn = _bfd_per_xvec_warn (abfd->xvec); + *warn = _("warning: %pB has a corrupt string table index"); + abfd->read_only = 1; + } } } else if (i_ehdrp->e_shstrndx != SHN_UNDEF) @@ -816,9 +818,14 @@ elf_object_p (bfd *abfd) two, as required by the ELF spec. */ if (i_phdr->p_align != (i_phdr->p_align & -i_phdr->p_align)) { - abfd->read_only = 1; - _bfd_error_handler (_("warning: %pB has a program header " - "with invalid alignment"), abfd); + i_phdr->p_align &= -i_phdr->p_align; + if (!abfd->read_only) + { + const char **warn = _bfd_per_xvec_warn (abfd->xvec); + *warn = _("warning: %pB has a program header " + "with invalid alignment"); + abfd->read_only = 1; + } } } } diff --git a/bfd/format.c b/bfd/format.c index 489ffcffd53..7e2813c97a4 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -202,6 +202,13 @@ bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve) preserve->marker = NULL; } +static void +clear_warnmsg (const bfd_target *targ) +{ + const char **warn = _bfd_per_xvec_warn (targ); + *warn = NULL; +} + /* FUNCTION bfd_check_format_matches @@ -275,6 +282,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) /* rewind! */ goto err_ret; + clear_warnmsg (abfd->xvec); cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); if (cleanup) @@ -341,6 +349,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) goto err_ret; + clear_warnmsg (abfd->xvec); cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); if (cleanup) { @@ -506,6 +515,13 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) bfd_preserve_finish (abfd, &preserve_match); bfd_preserve_finish (abfd, &preserve); + if (!abfd->my_archive) + { + const char **warn = _bfd_per_xvec_warn (abfd->xvec); + if (*warn) + _bfd_error_handler (*warn, abfd); + } + /* File position has moved, BTW. */ return true; } diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 68d0c4278b3..a17b98e8e30 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1,6 +1,6 @@ /* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically generated from "libbfd-in.h", "libbfd.c", "bfdio.c", "bfdwin.c", - "cache.c", "reloc.c", "archures.c" and "linker.c". + "cache.c", "reloc.c", "targets.c", "archures.c" and "linker.c". Run "make headers" in your build bfd/ to regenerate. */ /* libbfd.h -- Declarations used by bfd library *implementation*. @@ -3546,6 +3546,9 @@ bool _bfd_unrecognized_reloc sec_ptr section, unsigned int r_type); +/* Extracted from targets.c. */ +const char **_bfd_per_xvec_warn (const bfd_target *); + /* Extracted from archures.c. */ extern const bfd_arch_info_type bfd_default_arch_struct; const bfd_arch_info_type *bfd_default_compatible diff --git a/bfd/targets.c b/bfd/targets.c index dc331230aff..7dbc3a5dbf6 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -20,6 +20,7 @@ MA 02110-1301, USA. */ #include "sysdep.h" +#include "libiberty.h" #include "bfd.h" #include "libbfd.h" #include "fnmatch.h" @@ -1454,7 +1455,10 @@ const bfd_target *const *const bfd_associated_vector = _bfd_associated_vector; /* When there is an ambiguous match, bfd_check_format_matches puts the names of the matching targets in an array. This variable is the maximum number of entries that the array could possibly need. */ -const size_t _bfd_target_vector_entries = sizeof (_bfd_target_vector)/sizeof (*_bfd_target_vector); +const size_t _bfd_target_vector_entries = ARRAY_SIZE (_bfd_target_vector); + +/* A place to stash a warning from _bfd_check_format. */ +static const char *per_xvec_warn[ARRAY_SIZE (_bfd_target_vector) + 1]; /* This array maps configuration triplets onto BFD vectors. */ @@ -1474,6 +1478,29 @@ static const struct targmatch bfd_target_match[] = { { NULL, NULL } }; +/* +INTERNAL_FUNCTION + _bfd_per_xvec_warn + +SYNOPSIS + const char **_bfd_per_xvec_warn (const bfd_target *); + +DESCRIPTION + Return a location for the given target xvec to use for + warnings specific to that target. +*/ + +const char ** +_bfd_per_xvec_warn (const bfd_target *targ) +{ + size_t idx; + + for (idx = 0; idx < ARRAY_SIZE (_bfd_target_vector); idx++) + if (_bfd_target_vector[idx] == targ) + break; + return per_xvec_warn + idx; +} + /* Find a target vector, given a name or configuration triplet. */ static const bfd_target * -- Alan Modra Australia Development Lab, IBM