From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by sourceware.org (Postfix) with ESMTPS id 00E283858432 for ; Wed, 16 Feb 2022 11:33:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 00E283858432 Received: by mail-pg1-x52d.google.com with SMTP id 139so1910247pge.1 for ; Wed, 16 Feb 2022 03:33:11 -0800 (PST) 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=S+CY3CMr7woEGkX25RWJnkarzVaCrpJgxTlxTDXkbHE=; b=C+YwexIo1n9FLxvYAyRIsqLouzQ8TmzrtMVhs53rMwTkn1Wpk4DJ1aN4xRCVe0NtZv I0OinHz/A5cbenIgsQ0F2UXJ5cXeSB+5DeYra0kRhhF9OFE60rhLetCM5X7bF+xuYz6J sOFw3p5GtsvQPtl/gnd60yLR3JqljCnbdQO+R+YznbWP0r5b4iwLrNF5/Q1PudusD6XW 1IuNsRarZWHsmOucpaFTSMyOKD/QYekUjdyfl+eeseCHb6BXUuD+T6x3XxCS3F6WL0o6 aI4bIOiC1BRCFPhh+J+wbMF3QILuARZns8Rww0l2Gh4IFldHJe9nv0hWPDDwXEo1vgg0 0lEQ== X-Gm-Message-State: AOAM5308rp+/m4QrE4yFYW7zOt6ieFxw3m5wn+zUwo0JfGtHLMm2JEax CMqCA45gZwnMo4P5n9e8CVkYLIs1Obw= X-Google-Smtp-Source: ABdhPJw430sCOEJs9eb1j4Ui/c+2uGh/IT9cUHiXXVj4y4laP3W6DkY8vc8nh+4GtkCP0diF5ve3Ag== X-Received: by 2002:a63:ce54:0:b0:364:f310:6e0c with SMTP id r20-20020a63ce54000000b00364f3106e0cmr1896619pgi.456.1645011190689; Wed, 16 Feb 2022 03:33:10 -0800 (PST) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:5250:e0c3:7fe9:a164]) by smtp.gmail.com with ESMTPSA id w8sm45496700pfu.128.2022.02.16.03.33.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Feb 2022 03:33:09 -0800 (PST) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 27CAA114145A; Wed, 16 Feb 2022 22:03:07 +1030 (ACDT) Date: Wed, 16 Feb 2022 22:03:07 +1030 From: Alan Modra To: binutils@sourceware.org Subject: What to do when sh_addralign isn't a power of two 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.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Wed, 16 Feb 2022 11:33:13 -0000 BFD generally doesn't handle anything but a power of two section alignment, and ELF sh_addralign is required to be an integral power of two (or zero) by the ELF spec. Of course this is ignored by fuzzers, and because bfd_log2 rounds up, we can end up with alignment_power being 32 on a 32-bit object or 64 on a 64-bit object. That then triggers ubsan warnings in places like bfd_update_compression_header where we want to convert from alignment_power back to an alignment. I suppose we could reject object files that have non-compliant sh_addralign, but I think it's also reasonable to use the greatest power of two divisor of sh_addralign, ie. the rightmost 1 bit. * elf.c (_bfd_elf_make_section_from_shdr): Use greatest power of two divisor of sh_addralign. (_bfd_elf_assign_file_position_for_section): Likewise. (assign_file_positions_for_non_load_sections): Likewise. diff --git a/bfd/elf.c b/bfd/elf.c index 79f71aa81e2..a67415e76e1 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1104,7 +1104,8 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, if (!bfd_set_section_vma (newsect, hdr->sh_addr / opb) || !bfd_set_section_size (newsect, hdr->sh_size) - || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign))) + || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign + & -hdr->sh_addralign))) return false; /* As a GNU extension, if the name begins with .gnu.linkonce, we @@ -4227,7 +4228,7 @@ _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp, bool align) { if (align && i_shdrp->sh_addralign > 1) - offset = BFD_ALIGN (offset, i_shdrp->sh_addralign); + offset = BFD_ALIGN (offset, i_shdrp->sh_addralign & -i_shdrp->sh_addralign); i_shdrp->sh_offset = offset; if (i_shdrp->bfd_section != NULL) i_shdrp->bfd_section->filepos = offset; @@ -6149,6 +6150,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, for (hdrpp = i_shdrpp + 1; hdrpp < end_hdrpp; hdrpp++) { Elf_Internal_Shdr *hdr; + bfd_vma align; hdr = *hdrpp; if (hdr->bfd_section != NULL @@ -6174,11 +6176,10 @@ assign_file_positions_for_non_load_sections (bfd *abfd, : hdr->bfd_section->name)); /* We don't need to page align empty sections. */ if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0) - off += vma_page_aligned_bias (hdr->sh_addr, off, - maxpagesize); + align = maxpagesize; else - off += vma_page_aligned_bias (hdr->sh_addr, off, - hdr->sh_addralign); + align = hdr->sh_addralign & -hdr->sh_addralign; + off += vma_page_aligned_bias (hdr->sh_addr, off, align); off = _bfd_elf_assign_file_position_for_section (hdr, off, false); } -- Alan Modra Australia Development Lab, IBM