summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-08-06 14:57:27 +0930
committerAlan Modra <amodra@gmail.com>2022-08-06 18:43:24 +0930
commit578a7392c33c7c7cde5559278e519c75047318c9 (patch)
treea2c254b92055bfbfd070f2d60cb9d14ab6d6d35b /bfd
parent77b38f6db98e046232ecaac11b61c453965fb75a (diff)
objcopy section alignment
bfd_set_section_alignment currently always returns true. This patch changes it to return false on silly alignment values, avoiding yet another way to trigger ubsan errors like coffcode.h:3192:12: runtime error: shift exponent 299 is too large for 32-bit type 'int'. We'll catch that one in objcopy.c:setup_sections. However, setup_sections gives up on other setup operations that are necessary even after an error of some sort. Change that to keep going, which might change the error message but that shouldn't matter in the least. bfd/ * section.c (bfd_set_section_alignment): Return false and don't set alignment_power for stupidly large alignments. * bfd-in2.h: Regenerate. * coffcode.h (coff_compute_section_file_positions): Don't use an int constant when calculating alignment. binutils/ * objcopy.c (setup_section): Keep on going after hitting non-fatal errors.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/coffcode.h9
-rw-r--r--bfd/section.c2
3 files changed, 9 insertions, 4 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 0d2e915b41..4ab7e2d693 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1201,6 +1201,8 @@ bfd_set_section_lma (asection *sec, bfd_vma val)
static inline bool
bfd_set_section_alignment (asection *sec, unsigned int val)
{
+ if (val >= sizeof (bfd_vma) * 8 - 1)
+ return false;
sec->alignment_power = val;
return true;
}
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 0dc68a9a25..798b9f249b 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -3189,7 +3189,7 @@ coff_compute_section_file_positions (bfd * abfd)
#ifdef COFF_IMAGE_WITH_PE
sofar = BFD_ALIGN (sofar, page_size);
#else
- sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+ sofar = BFD_ALIGN (sofar, (bfd_vma) 1 << current->alignment_power);
#endif
#ifdef RS6000COFF_C
@@ -3259,7 +3259,7 @@ coff_compute_section_file_positions (bfd * abfd)
old_size = current->size;
current->size = BFD_ALIGN (current->size,
- 1 << current->alignment_power);
+ (bfd_vma) 1 << current->alignment_power);
align_adjust = current->size != old_size;
sofar += current->size - old_size;
}
@@ -3269,7 +3269,7 @@ coff_compute_section_file_positions (bfd * abfd)
#ifdef COFF_IMAGE_WITH_PE
sofar = BFD_ALIGN (sofar, page_size);
#else
- sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+ sofar = BFD_ALIGN (sofar, (bfd_vma) 1 << current->alignment_power);
#endif
align_adjust = sofar != old_sofar;
current->size += sofar - old_sofar;
@@ -3315,7 +3315,8 @@ coff_compute_section_file_positions (bfd * abfd)
/* Make sure the relocations are aligned. We don't need to make
sure that this byte exists, because it will only matter if there
really are relocs. */
- sofar = BFD_ALIGN (sofar, 1 << COFF_DEFAULT_SECTION_ALIGNMENT_POWER);
+ sofar = BFD_ALIGN (sofar,
+ (bfd_vma) 1 << COFF_DEFAULT_SECTION_ALIGNMENT_POWER);
obj_relocbase (abfd) = sofar;
abfd->output_has_begun = true;
diff --git a/bfd/section.c b/bfd/section.c
index 5a487ce6c6..c7a02d729f 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -631,6 +631,8 @@ CODE_FRAGMENT
.static inline bool
.bfd_set_section_alignment (asection *sec, unsigned int val)
.{
+. if (val >= sizeof (bfd_vma) * 8 - 1)
+. return false;
. sec->alignment_power = val;
. return true;
.}