public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Alan Modra <amodra@gmail.com>
To: binutils@sourceware.org
Subject: What to do when sh_addralign isn't a power of two
Date: Wed, 16 Feb 2022 22:03:07 +1030	[thread overview]
Message-ID: <Ygzg85mSECd5zwFt@squeak.grove.modra.org> (raw)

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

                 reply	other threads:[~2022-02-16 11:33 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Ygzg85mSECd5zwFt@squeak.grove.modra.org \
    --to=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).