aboutsummaryrefslogtreecommitdiff
path: root/bfd/merge.c
diff options
context:
space:
mode:
authorChristian Eggers <ceggers@gmx.de>2020-03-02 20:17:00 +0000
committerAlan Modra <amodra@gmail.com>2020-03-13 15:48:01 +1030
commit666318230c54a348763927c80d085542d9890c42 (patch)
tree8156ad937b488fb6a4377ade6beb0f1db36b0b7d /bfd/merge.c
parent502794d4321dc17d5c9fb591bedc8761118b2943 (diff)
downloadgdb-666318230c54a348763927c80d085542d9890c42.zip
gdb-666318230c54a348763927c80d085542d9890c42.tar.gz
gdb-666318230c54a348763927c80d085542d9890c42.tar.bz2
Fix several mix up between octets and bytes in ELF program headers
Fixes additional locations not handled in the first patch. When converting between addresses in ELF headers [octets] and bfd LMA/VMA [bytes], the number of octets per byte needs to be incorporated. include/ * bfdlink.h (struct bfd_link_order): Add unit (bytes/octets) to offset and size members. * elf/internal.h (struct elf_internal_phdr): Likewise for p_align member. (struct elf_segment_map): Likewise for p_paddr and p_size members bfd/ * bfd.c (bfd_record_phdr): New local "opb". Fix assignment of "p_paddr" from "at". * elfcode.h (bfd_from_remote_memory): Add units to several parameters. New local "opb". Fix usage of p_align. Fix calculation of "localbase" from "ehdr_vma" and "p_vaddr". Fix call of target_read_memory. * elflink.c (elf_fixup_link_order): Fix scope of "s" local. Fix calculation of "offset" and "output_offset". (bfd_elf_final_link): New local "opb". Fix calculation of "size" from "offset" and fix calculation of "end" from "vma+size". Fix comparison between "sh_addr" and "vma"/"output_offset". (bfd_elf_discard_info): Fix calculation of "eh_alignment". * elf-bfd.h (struct elf_link_hash_table): Add unit to tls_size member. * elf.c (_bfd_elf_map_sections_to_segments): Add unit (bytes/ octets) to "wrap_to2 and "phdr_size" locals. Fix calculation of "wrap_to" value. Add unit (bytes) to phdr_lma variable. Fix assignment of p_paddr from phdr_lma. Fix comparison between "lma+size" and "next->lma". (elf_sort_segments): Fix assignment from p_paddr to lma. (assign_file_positions_for_load_sections): Add unit (bytes) to local "align". Fix calculation of local "off_adjust". Fix calculation of local "filehdr_vaddr". (assign_file_positions_for_non_load_sections): New local "opb". Fix calculation of "end" from "p_size". Fix comparison between "vma+SECTION_SIZE" and "start". Fix calculation of "p_memsz" from "end" and "p_vaddr". (rewrite_elf_program_header): Fix comparison between p_vaddr and vma. Fix assignment to p_paddr from lma. Fix comparison between p_paddr and lma. Fix assignment to p_paddr from lma. * merge.c (sec_merge_emit): New local "opb". Convert "alignment_power" to octets. (_bfd_add_merge_section): New locals "alignment_power" and "opb". Fix comparison between "alignment_power" and "sizeof(align)". (_bfd_merge_sections): New local "opb". Divide size by opb before checking align mask.
Diffstat (limited to 'bfd/merge.c')
-rw-r--r--bfd/merge.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/bfd/merge.c b/bfd/merge.c
index 5a4e709..0c6f7a1 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -292,8 +292,9 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
asection *sec = secinfo->sec;
char *pad = NULL;
bfd_size_type off = 0;
- int alignment_power = sec->output_section->alignment_power;
- bfd_size_type pad_len;
+ unsigned int opb = bfd_octets_per_byte (abfd, sec);
+ int alignment_power = sec->output_section->alignment_power * opb;
+ bfd_size_type pad_len; /* Octets. */
/* FIXME: If alignment_power is 0 then really we should scan the
entry list for the largest required alignment and use that. */
@@ -364,9 +365,11 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
{
struct sec_merge_info *sinfo;
struct sec_merge_sec_info *secinfo;
- unsigned int align;
+ unsigned int alignment_power; /* Octets. */
+ unsigned int align; /* Octets. */
bfd_size_type amt;
bfd_byte *contents;
+ unsigned int opb = bfd_octets_per_byte (abfd, sec);
if ((abfd->flags & DYNAMIC) != 0
|| (sec->flags & SEC_MERGE) == 0)
@@ -389,10 +392,11 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
- if (sec->alignment_power >= sizeof (align) * CHAR_BIT)
+ alignment_power = sec->alignment_power * opb;
+ if (alignment_power >= sizeof (align) * CHAR_BIT)
return TRUE;
- align = 1u << sec->alignment_power;
+ align = 1u << alignment_power;
if ((sec->entsize < align
&& ((sec->entsize & (sec->entsize - 1))
|| !(sec->flags & SEC_STRINGS)))
@@ -739,7 +743,7 @@ _bfd_merge_sections (bfd *abfd,
for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
{
struct sec_merge_sec_info *secinfo;
- bfd_size_type align;
+ bfd_size_type align; /* Bytes. */
if (! sinfo->chain)
continue;
@@ -764,8 +768,10 @@ _bfd_merge_sections (bfd *abfd,
return FALSE;
if (align)
{
+ unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
+
align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
- if ((secinfo->sec->size & (align - 1)) != 0)
+ if (((secinfo->sec->size / opb) & (align - 1)) != 0)
align = 0;
}
}
@@ -782,7 +788,7 @@ _bfd_merge_sections (bfd *abfd,
else
{
struct sec_merge_hash_entry *e;
- bfd_size_type size = 0;
+ bfd_size_type size = 0; /* Octets. */
/* Things are much simpler for non-strings.
Just assign them slots in the section. */