aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2024-06-27 12:31:46 +0930
committerAlan Modra <amodra@gmail.com>2024-06-27 14:28:51 +0930
commitd58dbdd2a6236df711e40086f365878a77b84a76 (patch)
treed14930b2351b983025429d5932e8210a25942821
parent6cb70d1bf43d6f069780296bf0aef2779ced28ff (diff)
downloadbinutils-d58dbdd2a6236df711e40086f365878a77b84a76.zip
binutils-d58dbdd2a6236df711e40086f365878a77b84a76.tar.gz
binutils-d58dbdd2a6236df711e40086f365878a77b84a76.tar.bz2
Re: Rewrite SHT_GROUP handling
There is no need to loop over the headers twice. Remove that leftover from the previous scheme. Also, the previous scheme silently ignored a section being mentioned in two or more SHT_GROUP sections. * elf.c (process_sht_group_entries): Prevent sections from belonging to two groups. (_bfd_elf_setup_sections): Process groups in a single loop over headers.
-rw-r--r--bfd/elf.c49
1 files changed, 15 insertions, 34 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index d7c4227..8bb296f 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -636,7 +636,9 @@ process_sht_group_entries (bfd *abfd,
shdr = elf_elfsections (abfd)[idx];
if (idx >= elf_numsections (abfd)
- || shdr->sh_type == SHT_GROUP)
+ || shdr->sh_type == SHT_GROUP
+ || (shdr->bfd_section != NULL
+ && elf_next_in_group (shdr->bfd_section) != NULL))
{
_bfd_error_handler
(_("%pB: invalid entry in SHT_GROUP section [%u]"), abfd, gidx);
@@ -698,12 +700,10 @@ process_sht_group_entries (bfd *abfd,
bool
_bfd_elf_setup_sections (bfd *abfd)
{
- unsigned int i;
bool result = true;
- asection *s;
/* Process SHF_LINK_ORDER. */
- for (s = abfd->sections; s != NULL; s = s->next)
+ for (asection *s = abfd->sections; s != NULL; s = s->next)
{
Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
@@ -746,46 +746,27 @@ _bfd_elf_setup_sections (bfd *abfd)
}
/* Process section groups. */
-
- /* First count the number of groups. If we have a SHT_GROUP
- section with just a flag word (ie. sh_size is 4), ignore it. */
- unsigned int num_group = 0;
- for (i = 1; i < elf_numsections (abfd); i++)
+ for (unsigned int i = 1; i < elf_numsections (abfd); i++)
{
Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
if (shdr && shdr->sh_type == SHT_GROUP)
{
- if (!is_valid_group_section_header (shdr, GRP_ENTRY_SIZE))
+ if (is_valid_group_section_header (shdr, GRP_ENTRY_SIZE))
{
- /* PR binutils/18758: Beware of corrupt binaries with invalid
- group data. */
+ if (shdr->sh_size >= 2 * GRP_ENTRY_SIZE
+ && !process_sht_group_entries (abfd, shdr, i))
+ result = false;
+ }
+ else
+ {
+ /* PR binutils/18758: Beware of corrupt binaries with
+ invalid group data. */
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: section group entry number %u is corrupt"),
- abfd, i);
+ (_("%pB: section group entry number %u is corrupt"), abfd, i);
result = false;
- continue;
}
- if (shdr->sh_size >= 2 * GRP_ENTRY_SIZE)
- ++num_group;
- }
- }
-
- if (num_group == 0)
- return result;
-
- for (i = 1; i < elf_numsections (abfd); i++)
- {
- Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
-
- if (shdr && shdr->sh_type == SHT_GROUP
- && is_valid_group_section_header (shdr, 2 * GRP_ENTRY_SIZE))
- {
- if (!process_sht_group_entries (abfd, shdr, i))
- result = false;
- if (--num_group == 0)
- break;
}
}