diff -rup binutils.orig/binutils/doc/binutils.texi binutils-2.35.2/binutils/doc/binutils.texi
--- binutils.orig/binutils/doc/binutils.texi	2024-04-03 11:32:37.507595411 +0100
+++ binutils-2.35.2/binutils/doc/binutils.texi	2024-04-03 11:32:53.188615675 +0100
@@ -1643,6 +1643,10 @@ above.  If @var{sectionpattern} does not
 input file, a warning will be issued, unless
 @option{--no-change-warnings} is used.
 
+Note - changing the VMA of sections in a fully linked binary can be
+dangerous since there may be code that expects the sections to be
+located at their old address.
+
 @item --change-warnings
 @itemx --adjust-warnings
 If @option{--change-section-address} or @option{--change-section-lma} or
@@ -1671,7 +1675,14 @@ ELF format files.
 @item --set-section-alignment @var{sectionpattern}=@var{align}
 Set the alignment for any sections matching @var{sectionpattern}.
 @var{align} specifies the alignment in bytes and must be a power of
-two, i.e. 1, 2, 4, 8@dots{}. 
+two, i.e. 1, 2, 4, 8@dots{}.
+
+Note - setting a section's alignment will not automatically align its
+LMA or VMA addresses.  If those need to be changed as well then the
+@option{--change-section-lma} and/or @option{--change-section-vma}
+options should be used.  Also note that changing VMAs can cause
+problems in fully linked binaries where there may be code that expects
+the contents of the sections to be located at their old address.
 
 @item --add-section @var{sectionname}=@var{filename}
 Add a new section named @var{sectionname} while copying the file.  The
@@ -2029,11 +2040,21 @@ for dlls.
 [This option is specific to PE targets.]
 
 @item --section-alignment @var{num}
-Sets the section alignment field in the PE header.  Sections in memory
-will always begin at addresses which are a multiple of this number.
-Defaults to 0x1000.
 [This option is specific to PE targets.]
 
+Sets the section alignment field in the PE header - if one is present
+in the binary.  Sections in memory will always begin at addresses
+which are a multiple of this number.  Defaults to 0x1000.
+
+Note - this option will also set the alignment field in each section's
+flags.
+
+Note - if a section's LMA or VMA addresses are no longer aligned, and
+those addresses have not been set via the @option{--set-section-lma} or
+@option{--set-section-vma} options, and the file has been fully
+relocated then a warning message will be issued.  It will then be up
+to the user to decide if the LMA and VMA need updating.
+
 @item --stack @var{reserve}
 @itemx --stack @var{reserve},@var{commit}
 Specify the number of bytes of memory to reserve (and optionally commit)
diff -rup binutils.orig/binutils/objcopy.c binutils-2.35.2/binutils/objcopy.c
--- binutils.orig/binutils/objcopy.c	2024-04-03 11:32:37.862595870 +0100
+++ binutils-2.35.2/binutils/objcopy.c	2024-04-03 11:32:53.189615676 +0100
@@ -3954,6 +3954,50 @@ setup_bfd_headers (bfd *ibfd, bfd *obfd)
   return;
 }
 
+static inline signed int
+power_of_two (bfd_vma val)
+{
+  signed int result = 0;
+
+  if (val == 0)
+    return 0;
+
+  while ((val & 1) == 0)
+    {
+      val >>= 1;
+      ++result;
+    }
+
+  if (val != 1)
+    /* Number has more than one 1, i.e. wasn't a power of 2.  */
+    return -1;
+
+  return result;
+}
+
+static unsigned int
+image_scn_align (unsigned int alignment)
+{
+  switch (alignment)
+    {
+    case 8192: return IMAGE_SCN_ALIGN_8192BYTES;
+    case 4096: return IMAGE_SCN_ALIGN_4096BYTES;
+    case 2048: return IMAGE_SCN_ALIGN_2048BYTES;
+    case 1024: return IMAGE_SCN_ALIGN_1024BYTES;
+    case  512: return IMAGE_SCN_ALIGN_512BYTES;
+    case  256: return IMAGE_SCN_ALIGN_256BYTES;
+    case  128: return IMAGE_SCN_ALIGN_128BYTES;
+    case   64: return IMAGE_SCN_ALIGN_64BYTES;
+    case   32: return IMAGE_SCN_ALIGN_32BYTES;
+    case   16: return IMAGE_SCN_ALIGN_16BYTES;
+    case    8: return IMAGE_SCN_ALIGN_8BYTES;
+    case    4: return IMAGE_SCN_ALIGN_4BYTES;
+    case    2: return IMAGE_SCN_ALIGN_2BYTES;
+    case    1: return IMAGE_SCN_ALIGN_1BYTES;
+    default: return 0;
+    }
+}
+
 /* Create a section in OBFD with the same
    name and attributes as ISECTION in IBFD.  */
 
@@ -4058,6 +4102,8 @@ setup_section (bfd *ibfd, sec_ptr isecti
       goto loser;
     }
 
+  bfd_boolean vma_set_by_user = FALSE;
+
   vma = bfd_section_vma (isection);
   p = find_section_list (bfd_section_name (isection), FALSE,
 			 SECTION_CONTEXT_ALTER_VMA | SECTION_CONTEXT_SET_VMA);
@@ -4067,6 +4113,7 @@ setup_section (bfd *ibfd, sec_ptr isecti
 	vma = p->vma_val;
       else
 	vma += p->vma_val;
+      vma_set_by_user = TRUE;
     }
   else
     vma += change_section_address;
@@ -4077,6 +4124,8 @@ setup_section (bfd *ibfd, sec_ptr isecti
       goto loser;
     }
 
+  bfd_boolean lma_set_by_user = FALSE;
+
   lma = isection->lma;
   p = find_section_list (bfd_section_name (isection), FALSE,
 			 SECTION_CONTEXT_ALTER_LMA | SECTION_CONTEXT_SET_LMA);
@@ -4086,6 +4135,7 @@ setup_section (bfd *ibfd, sec_ptr isecti
 	lma += p->lma_val;
       else
 	lma = p->lma_val;
+      lma_set_by_user = TRUE;
     }
   else
     lma += change_section_address;
@@ -4096,6 +4146,24 @@ setup_section (bfd *ibfd, sec_ptr isecti
 			 SECTION_CONTEXT_SET_ALIGNMENT);
   if (p != NULL)
     alignment = p->alignment;
+  else if (pe_section_alignment != (bfd_vma) -1
+	   && bfd_get_flavour (obfd) == bfd_target_coff_flavour)
+    {
+      alignment = power_of_two (pe_section_alignment);
+
+      if (coff_section_data (ibfd, isection))
+	{
+	  struct pei_section_tdata * pei_data = pei_section_data (ibfd, isection);
+
+	  if (pei_data != NULL)
+	    {
+	      /* Set the alignment flag of the input section, which will
+		 be copied to the output section later on.  */
+	      pei_data->pe_flags &= ~IMAGE_SCN_ALIGN_POWER_BIT_MASK;
+	      pei_data->pe_flags |= image_scn_align (pe_section_alignment);
+	    }
+	}
+    }
   else
     alignment = bfd_section_alignment (isection);
 
@@ -4107,6 +4175,32 @@ setup_section (bfd *ibfd, sec_ptr isecti
       goto loser;
     }
 
+  /* If the output section's VMA is not aligned
+     and the alignment has changed
+     and the VMA was not set by the user
+     and the section does not have relocations associated with it
+     then warn the user.  */
+  if (osection->vma & ((1 << alignment) - 1)
+      && alignment != bfd_section_alignment (isection)
+      && change_section_address == 0
+      && ! vma_set_by_user
+      && bfd_get_reloc_upper_bound (ibfd, isection) < 1)
+    {
+      non_fatal (_("output section %s's alignment does not match its VMA"), name);
+    }
+
+  /* Similar check for a non-aligned LMA.
+     FIXME: Since this is only an LMA, maybe it does not matter if
+     it is not aligned ?  */
+  if (osection->lma & ((1 << alignment) - 1)
+      && alignment != bfd_section_alignment (isection)
+      && change_section_address == 0
+      && ! lma_set_by_user
+      && bfd_get_reloc_upper_bound (ibfd, isection) < 1)
+    {
+      non_fatal (_("output section %s's alignment does not match its LMA"), name);
+    }
+
   /* Copy merge entity size.  */
   osection->entsize = isection->entsize;
 
@@ -5530,15 +5624,8 @@ copy_main (int argc, char *argv[])
 	      fatal (_("bad format for --set-section-alignment: numeric argument needed"));
 
 	    /* Convert integer alignment into a power-of-two alignment.  */
-	    palign = 0;
-	    while ((align & 1) == 0)
-	      {
-	    	align >>= 1;
-	    	++palign;
-	      }
-
-	    if (align != 1)
-	      /* Number has more than on 1, i.e. wasn't a power of 2.  */
+	    palign = power_of_two (align);
+	    if (palign == -1)
 	      fatal (_("bad format for --set-section-alignment: alignment is not a power of two"));
 
 	    /* Add the alignment setting to the section list.  */
@@ -5751,6 +5838,11 @@ copy_main (int argc, char *argv[])
 	case OPTION_PE_SECTION_ALIGNMENT:
 	  pe_section_alignment = parse_vma (optarg,
 					    "--section-alignment");
+	  if (power_of_two (pe_section_alignment) == -1)
+	    {
+	      non_fatal (_("--section-alignment argument is not a power of two: %s - ignoring"), optarg);
+	      pe_section_alignment = (bfd_vma) -1;
+	    }
 	  break;
 
 	case OPTION_SUBSYSTEM:
diff -rup binutils.orig/binutils/testsuite/binutils-all/objcopy.exp binutils-2.35.2/binutils/testsuite/binutils-all/objcopy.exp
--- binutils.orig/binutils/testsuite/binutils-all/objcopy.exp	2024-04-03 11:32:37.781595765 +0100
+++ binutils-2.35.2/binutils/testsuite/binutils-all/objcopy.exp	2024-04-03 11:33:00.878625614 +0100
@@ -1342,6 +1342,7 @@ objcopy_remove_relocations_from_executab
 run_dump_test "pr23633"
 
 run_dump_test "set-section-alignment"
+run_dump_test "section-alignment"
 
 setup_xfail "hppa*-*-*"
 setup_xfail "sh-*-coff*"
--- /dev/null	2024-06-27 08:39:51.717818400 +0100
+++ binutils-2.35.2/binutils/testsuite/binutils-all/section-alignment.d	2024-06-27 15:43:00.626529058 +0100
@@ -0,0 +1,9 @@
+#source: pr23633.s
+#PROG: objcopy
+#objcopy: --section-alignment=512
+#objdump: -P sections
+#target: [is_pecoff_format]
+
+#...
+.* Align: 512.*
+#pass
--- binutils.orig/binutils/objcopy.c	2024-07-25 15:30:49.380323472 +0100
+++ binutils-2.35.2/binutils/objcopy.c	2024-07-25 15:33:35.779466989 +0100
@@ -4147,6 +4147,7 @@ setup_section (bfd *ibfd, sec_ptr isecti
   if (p != NULL)
     alignment = p->alignment;
   else if (pe_section_alignment != (bfd_vma) -1
+	   && bfd_get_flavour (ibfd) == bfd_target_coff_flavour
 	   && bfd_get_flavour (obfd) == bfd_target_coff_flavour)
     {
       alignment = power_of_two (pe_section_alignment);
--- binutils.orig/bfd/coffcode.h	2024-08-12 09:44:06.041128327 +0100
+++ binutils-2.35.2/bfd/coffcode.h	2024-08-12 11:13:58.209619284 +0100
@@ -2942,7 +2942,7 @@ coff_compute_section_file_positions (bfd
 #endif
 
 #ifdef COFF_IMAGE_WITH_PE
-  int page_size;
+  unsigned int page_size;
 
   if (coff_data (abfd)->link_info
       || (pe_data (abfd) && pe_data (abfd)->pe_opthdr.FileAlignment))
@@ -2953,22 +2953,12 @@ coff_compute_section_file_positions (bfd
 	 This repairs 'ld -r' for arm-wince-pe target.  */
       if (page_size == 0)
 	page_size = 1;
-
-      /* PR 17512: file: 0ac816d3.  */
-      if (page_size < 0)
-	{
-	  bfd_set_error (bfd_error_file_too_big);
-	  _bfd_error_handler
-	    /* xgettext:c-format */
-	    (_("%pB: page size is too large (0x%x)"), abfd, page_size);
-	  return FALSE;
-	}
     }
   else
     page_size = PE_DEF_FILE_ALIGNMENT;
 #else
 #ifdef COFF_PAGE_SIZE
-  int page_size = COFF_PAGE_SIZE;
+  unsigned int page_size = COFF_PAGE_SIZE;
 #endif
 #endif
 
@@ -3050,10 +3040,11 @@ coff_compute_section_file_positions (bfd
     bfd_size_type amt;
 
 #ifdef COFF_PAGE_SIZE
-    /* Clear D_PAGED if section alignment is smaller than
-       COFF_PAGE_SIZE.  */
-   if (pe_data (abfd)->pe_opthdr.SectionAlignment < COFF_PAGE_SIZE)
-     abfd->flags &= ~D_PAGED;
+    /* Clear D_PAGED if section / file alignment aren't suitable for
+       paging at COFF_PAGE_SIZE granularity.  */
+    if (pe_data (abfd)->pe_opthdr.SectionAlignment < COFF_PAGE_SIZE
+	|| page_size < COFF_PAGE_SIZE)
+      abfd->flags &= ~D_PAGED;
 #endif
 
     count = 0;
@@ -3173,7 +3164,11 @@ coff_compute_section_file_positions (bfd
 	     padding the previous section up if necessary.  */
 	  old_sofar = sofar;
 
+#ifdef COFF_IMAGE_WITH_PE
+	  sofar = BFD_ALIGN (sofar, page_size);
+#else
 	  sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+#endif
 
 #ifdef RS6000COFF_C
 	  /* Make sure the file offset and the vma of .text/.data are at the
@@ -3210,7 +3205,6 @@ coff_compute_section_file_positions (bfd
 	  if (previous != NULL)
 	    previous->size += sofar - old_sofar;
 	}
-
 #endif
 
       /* In demand paged files the low order bits of the file offset
@@ -3221,7 +3215,7 @@ coff_compute_section_file_positions (bfd
 	sofar += (current->vma - (bfd_vma) sofar) % page_size;
 #endif
       current->filepos = sofar;
-
+      
 #ifdef COFF_IMAGE_WITH_PE
       /* Set the padded size.  */
       current->size = (current->size + page_size - 1) & -page_size;
@@ -3244,7 +3238,11 @@ coff_compute_section_file_positions (bfd
       else
 	{
 	  old_sofar = sofar;
+#ifdef COFF_IMAGE_WITH_PE
+	  sofar = BFD_ALIGN (sofar, page_size);
+#else
 	  sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+#endif
 	  align_adjust = sofar != old_sofar;
 	  current->size += sofar - old_sofar;
 	}
--- binutils.orig/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d	2024-08-14 13:10:49.565104090 +0100
+++ binutils-2.35.2/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d	2024-08-14 13:15:44.378037490 +0100
@@ -12,5 +12,5 @@ start address 0x0000000000000000
 
 Sections:
 Idx Name          Size      VMA               LMA               File off  Algn
-  0 \.text         00000030  0[^ ]+  0[^ ]+  0[^ ]+  2\*\*12
+  0 \.text         00000030  0[^ ]+  0[^ ]+  0[^ ]+  2\*\*2
                   CONTENTS, ALLOC, LOAD, READONLY, CODE