diff options
author | Jan Beulich <jbeulich@suse.com> | 2024-10-11 08:19:34 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2024-10-11 08:19:34 +0200 |
commit | 1f1b5e506bf0d9bffef8525eb9bee19646713eb6 (patch) | |
tree | 0e7ff853c88a222cadaa41603f2f8594318aff63 /bfd | |
parent | 873e7b6cf61b5e3fca8ab55ea1b8574dd00a3caf (diff) | |
download | gdb-1f1b5e506bf0d9bffef8525eb9bee19646713eb6.zip gdb-1f1b5e506bf0d9bffef8525eb9bee19646713eb6.tar.gz gdb-1f1b5e506bf0d9bffef8525eb9bee19646713eb6.tar.bz2 |
bfd/ELF: restrict file alignment for object files
While for executables properly aligning sections within the file can be
quite relevant, the same is of pretty little importance for relocatable
object files. Avoid passing "true" into
_bfd_elf_assign_file_position_for_section() when dealing with object
files, but compensate minimally by applying log_file_align in such
cases as a cap to the alignment put in place.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elf-bfd.h | 2 | ||||
-rw-r--r-- | bfd/elf.c | 44 | ||||
-rw-r--r-- | bfd/elflink.c | 6 |
3 files changed, 34 insertions, 18 deletions
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index b89d3dd..96cf119 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2540,7 +2540,7 @@ extern long _bfd_elf_link_lookup_local_dynindx extern bool _bfd_elf_compute_section_file_positions (bfd *, struct bfd_link_info *); extern file_ptr _bfd_elf_assign_file_position_for_section - (Elf_Internal_Shdr *, file_ptr, bool); + (Elf_Internal_Shdr *, file_ptr, bool, unsigned char); extern bool _bfd_elf_modify_headers (bfd *, struct bfd_link_info *); @@ -4572,10 +4572,23 @@ align_file_position (file_ptr off, int align) file_ptr _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp, file_ptr offset, - bool align) + bool align, + unsigned char log_file_align) { - if (align && i_shdrp->sh_addralign > 1) - offset = BFD_ALIGN (offset, i_shdrp->sh_addralign & -i_shdrp->sh_addralign); + if (i_shdrp->sh_addralign > 1) + { + file_ptr salign = i_shdrp->sh_addralign & -i_shdrp->sh_addralign; + + if (align) + offset = BFD_ALIGN (offset, salign); + else if (log_file_align) + { + /* Heuristic: Cap alignment at log_file_align. */ + file_ptr falign = 1u << log_file_align; + + offset = BFD_ALIGN (offset, salign < falign ? salign : falign); + } + } i_shdrp->sh_offset = offset; if (i_shdrp->bfd_section != NULL) i_shdrp->bfd_section->filepos = offset; @@ -4663,18 +4676,18 @@ _bfd_elf_compute_section_file_positions (bfd *abfd, off = elf_next_file_pos (abfd); hdr = & elf_symtab_hdr (abfd); - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0); if (elf_symtab_shndx_list (abfd) != NULL) { hdr = & elf_symtab_shndx_list (abfd)->hdr; if (hdr->sh_size != 0) - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0); /* FIXME: What about other symtab_shndx sections in the list ? */ } hdr = &elf_tdata (abfd)->strtab_hdr; - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0); elf_next_file_pos (abfd) = off; @@ -6548,8 +6561,8 @@ assign_file_positions_for_non_load_sections (bfd *abfd, else 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); + off = _bfd_elf_assign_file_position_for_section (hdr, off, false, + bed->s->log_file_align); } else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) && hdr->bfd_section == NULL) @@ -6566,7 +6579,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, || hdr == i_shdrpp[elf_shstrtab_sec (abfd)]) hdr->sh_offset = -1; else - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0); } elf_next_file_pos (abfd) = off; @@ -6803,7 +6816,8 @@ assign_file_positions_except_relocs (bfd *abfd, hdr->sh_offset = -1; } else - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, false, + 0); } elf_next_file_pos (abfd) = off; @@ -7018,7 +7032,7 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd) Elf_Internal_Shdr **shdrpp, **end_shdrpp; Elf_Internal_Shdr *shdrp; Elf_Internal_Ehdr *i_ehdrp; - const struct elf_backend_data *bed; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); /* Skip non-load sections without section header. */ if ((abfd->flags & BFD_NO_SECTION_HEADER) != 0) @@ -7086,7 +7100,10 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd) sec->contents = NULL; } - off = _bfd_elf_assign_file_position_for_section (shdrp, off, true); + off = _bfd_elf_assign_file_position_for_section (shdrp, off, + (abfd->flags & (EXEC_P | DYNAMIC)) + || bfd_get_format (abfd) == bfd_core, + bed->s->log_file_align); } } @@ -7095,11 +7112,10 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd) _bfd_elf_strtab_finalize (elf_shstrtab (abfd)); shdrp = &elf_tdata (abfd)->shstrtab_hdr; shdrp->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd)); - off = _bfd_elf_assign_file_position_for_section (shdrp, off, true); + off = _bfd_elf_assign_file_position_for_section (shdrp, off, true, 0); /* Place the section headers. */ i_ehdrp = elf_elfheader (abfd); - bed = get_elf_backend_data (abfd); off = align_file_position (off, 1 << bed->s->log_file_align); i_ehdrp->e_shoff = off; off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; diff --git a/bfd/elflink.c b/bfd/elflink.c index a498dbb..19a9aec 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12926,7 +12926,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) { file_ptr off = elf_next_file_pos (abfd); - _bfd_elf_assign_file_position_for_section (symtab_hdr, off, true); + _bfd_elf_assign_file_position_for_section (symtab_hdr, off, true, 0); /* Note that at this point elf_next_file_pos (abfd) is incorrect. We do not yet know the size of the .symtab section. @@ -13370,7 +13370,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) symtab_shndx_hdr->sh_size = amt; off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, - off, true); + off, true, 0); if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 || (bfd_write (flinfo.symshndxbuf, amt, abfd) != amt)) @@ -13394,7 +13394,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) symstrtab_hdr->sh_addralign = 1; off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, - off, true); + off, true, 0); elf_next_file_pos (abfd) = off; if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 |