diff options
author | Christian Eggers <ceggers@gmx.de> | 2020-03-02 20:17:00 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-03-13 15:48:01 +1030 |
commit | 666318230c54a348763927c80d085542d9890c42 (patch) | |
tree | 8156ad937b488fb6a4377ade6beb0f1db36b0b7d /bfd | |
parent | 502794d4321dc17d5c9fb591bedc8761118b2943 (diff) | |
download | gdb-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')
-rw-r--r-- | bfd/ChangeLog | 40 | ||||
-rw-r--r-- | bfd/bfd.c | 5 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 2 | ||||
-rw-r--r-- | bfd/elf.c | 54 | ||||
-rw-r--r-- | bfd/elfcode.h | 28 | ||||
-rw-r--r-- | bfd/elflink.c | 31 | ||||
-rw-r--r-- | bfd/merge.c | 22 |
7 files changed, 118 insertions, 64 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 32549b3..f5ad233 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,45 @@ 2020-03-13 Christian Eggers <ceggers@gmx.de> + * 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. + +2020-03-13 Christian Eggers <ceggers@gmx.de> + * elf.c (_bfd_elf_make_section_from_shdr): Introduce new temp opb. Divide Elf_Internal_Shdr::sh_addr by opb when setting section LMA/VMA. @@ -2168,7 +2168,7 @@ bfd_record_phdr (bfd *abfd, bfd_boolean flags_valid, flagword flags, bfd_boolean at_valid, - bfd_vma at, + bfd_vma at, /* Bytes. */ bfd_boolean includes_filehdr, bfd_boolean includes_phdrs, unsigned int count, @@ -2176,6 +2176,7 @@ bfd_record_phdr (bfd *abfd, { struct elf_segment_map *m, **pm; size_t amt; + unsigned int opb = bfd_octets_per_byte (abfd, NULL); if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) return TRUE; @@ -2188,7 +2189,7 @@ bfd_record_phdr (bfd *abfd, m->p_type = type; m->p_flags = flags; - m->p_paddr = at; + m->p_paddr = at * opb; m->p_flags_valid = flags_valid; m->p_paddr_valid = at_valid; m->includes_filehdr = includes_filehdr; diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 5d9e0fe..d4ac515 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -635,7 +635,7 @@ struct elf_link_hash_table /* Cached first output tls section and size of PT_TLS segment. */ asection *tls_sec; - bfd_size_type tls_size; + bfd_size_type tls_size; /* Bytes. */ /* A linked list of dynamic BFD's loaded in the link. */ struct elf_link_loaded_list *dyn_loaded; @@ -4672,8 +4672,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) asection *first_mbind = NULL; asection *dynsec, *eh_frame_hdr; size_t amt; - bfd_vma addr_mask, wrap_to = 0; - bfd_size_type phdr_size; + bfd_vma addr_mask, wrap_to = 0; /* Bytes. */ + bfd_size_type phdr_size; /* Octets/bytes. */ unsigned int opb = bfd_octets_per_byte (abfd, NULL); /* Select the allocated sections, and sort them. */ @@ -4701,8 +4701,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) sections[i] = s; ++i; /* A wrapping section potentially clashes with header. */ - if (((s->lma + s->size) & addr_mask) < (s->lma & addr_mask)) - wrap_to = (s->lma + s->size) & addr_mask; + if (((s->lma + s->size / opb) & addr_mask) < (s->lma & addr_mask)) + wrap_to = (s->lma + s->size / opb) & addr_mask; } } BFD_ASSERT (i <= bfd_count_sections (abfd)); @@ -4786,7 +4786,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) program headers we will need. */ if (phdr_in_segment && count > 0) { - bfd_vma phdr_lma; + bfd_vma phdr_lma; /* Bytes. */ bfd_boolean separate_phdr = FALSE; phdr_lma = (sections[0]->lma - phdr_size) & addr_mask & -maxpagesize; @@ -4826,7 +4826,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) m = make_mapping (abfd, sections, 0, 0, phdr_in_segment); if (m == NULL) goto error_return; - m->p_paddr = phdr_lma; + m->p_paddr = phdr_lma * opb; m->p_vaddr_offset = (sections[0]->vma - phdr_size) & addr_mask & -maxpagesize; m->p_paddr_valid = 1; @@ -5014,7 +5014,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) if (s2->next->alignment_power == alignment_power && (s2->next->flags & SEC_LOAD) != 0 && elf_section_type (s2->next) == SHT_NOTE - && align_power (s2->lma + s2->size, + && align_power (s2->lma + s2->size / opb, alignment_power) == s2->next->lma) count++; @@ -5312,15 +5312,17 @@ elf_sort_segments (const void *arg1, const void *arg2) return m1->no_sort_lma ? -1 : 1; if (m1->p_type == PT_LOAD && !m1->no_sort_lma) { - bfd_vma lma1, lma2; + unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner, + m1->sections[0]); + bfd_vma lma1, lma2; /* Bytes. */ lma1 = 0; if (m1->p_paddr_valid) - lma1 = m1->p_paddr; + lma1 = m1->p_paddr / opb; else if (m1->count != 0) lma1 = m1->sections[0]->lma + m1->p_vaddr_offset; lma2 = 0; if (m2->p_paddr_valid) - lma2 = m2->p_paddr; + lma2 = m2->p_paddr / opb; else if (m2->count != 0) lma2 = m2->sections[0]->lma + m2->p_vaddr_offset; if (lma1 != lma2) @@ -5591,7 +5593,7 @@ assign_file_positions_for_load_sections (bfd *abfd, if (p->p_type == PT_LOAD && m->count > 0) { - bfd_size_type align; + bfd_size_type align; /* Bytes. */ unsigned int align_power = 0; if (m->p_align_valid) @@ -5628,7 +5630,7 @@ assign_file_positions_for_load_sections (bfd *abfd, break; } - off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align); + off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align * opb); /* Broken hardware and/or kernel require that files do not map the same page with different permissions on some hppa @@ -5995,7 +5997,7 @@ assign_file_positions_for_load_sections (bfd *abfd, || hash->root.type == bfd_link_hash_common)) { asection *s = NULL; - bfd_vma filehdr_vaddr = phdrs[phdr_load_seg->idx].p_vaddr; + bfd_vma filehdr_vaddr = phdrs[phdr_load_seg->idx].p_vaddr / opb; if (phdr_load_seg->count != 0) /* The segment contains sections, so use the first one. */ @@ -6072,6 +6074,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, Elf_Internal_Phdr *p; struct elf_segment_map *m; file_ptr off; + unsigned int opb = bfd_octets_per_byte (abfd, NULL); i_shdrpp = elf_elfsections (abfd); end_hdrpp = i_shdrpp + elf_numsections (abfd); @@ -6138,7 +6141,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, { if (p->p_type == PT_GNU_RELRO) { - bfd_vma start, end; + bfd_vma start, end; /* Bytes. */ bfd_boolean ok; if (link_info != NULL) @@ -6154,7 +6157,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, if (!m->p_size_valid) abort (); start = m->sections[0]->vma; - end = start + m->p_size; + end = start + m->p_size / opb; } else { @@ -6179,7 +6182,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, && lm->count != 0 && (lm->sections[lm->count - 1]->vma + (!IS_TBSS (lm->sections[lm->count - 1]) - ? lm->sections[lm->count - 1]->size + ? lm->sections[lm->count - 1]->size / opb : 0)) > start && lm->sections[0]->vma < end) break; @@ -6199,13 +6202,10 @@ assign_file_positions_for_non_load_sections (bfd *abfd, if (i < lm->count) { - unsigned int opb = bfd_octets_per_byte (abfd, - lm->sections[i]); - p->p_vaddr = lm->sections[i]->vma * opb; p->p_paddr = lm->sections[i]->lma * opb; p->p_offset = lm->sections[i]->filepos; - p->p_memsz = end - p->p_vaddr; + p->p_memsz = end * opb - p->p_vaddr; p->p_filesz = p->p_memsz; /* The RELRO segment typically ends a few bytes @@ -7188,8 +7188,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) + (map->includes_phdrs ? iehdr->e_phnum * iehdr->e_phentsize : 0), - output_section->alignment_power) - == output_section->vma)) + output_section->alignment_power * opb) + == (output_section->vma * opb))) map->p_paddr = segment->p_vaddr; /* Match up the physical address of the segment with the @@ -7257,7 +7257,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) if (matching_lma == NULL) matching_lma = suggested_lma; - map->p_paddr = matching_lma->lma; + map->p_paddr = matching_lma->lma * opb; /* Offset the segment physical address from the lma to allow for space taken up by elf headers. */ @@ -7285,7 +7285,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) the same alignment. */ if (segment->p_align != 0 && segment->p_align < align) align = segment->p_align; - map->p_paddr &= -align; + map->p_paddr &= -(align * opb); } } @@ -7329,8 +7329,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) + (map->includes_phdrs ? iehdr->e_phnum * iehdr->e_phentsize : 0), - output_section->alignment_power) - != output_section->lma) + output_section->alignment_power * opb) + != output_section->lma * opb) goto sorry; } else @@ -7396,7 +7396,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) map->p_type = segment->p_type; map->p_flags = segment->p_flags; map->p_flags_valid = 1; - map->p_paddr = suggested_lma->lma; + map->p_paddr = suggested_lma->lma * opb; map->p_paddr_valid = p_paddr_valid; map->includes_filehdr = 0; map->includes_phdrs = 0; diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 18a6dac..7745c53 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1664,10 +1664,11 @@ elf_debug_file (Elf_Internal_Ehdr *ehdrp) bfd * NAME(_bfd_elf,bfd_from_remote_memory) (bfd *templ, - bfd_vma ehdr_vma, - bfd_size_type size, - bfd_vma *loadbasep, + bfd_vma ehdr_vma /* Bytes. */, + bfd_size_type size /* Octets. */, + bfd_vma *loadbasep /* Bytes. */, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)) + /* (Bytes , , octets ). */ { Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ @@ -1680,9 +1681,10 @@ NAME(_bfd_elf,bfd_from_remote_memory) unsigned int i; bfd_vma high_offset; bfd_vma shdr_end; - bfd_vma loadbase; + bfd_vma loadbase; /* Bytes. */ char *filename; size_t amt; + unsigned int opb = bfd_octets_per_byte (templ, NULL); /* Read in the ELF header in external format. */ err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr); @@ -1780,17 +1782,17 @@ NAME(_bfd_elf,bfd_from_remote_memory) header sits, then we can figure out the loadbase. */ if (first_phdr == NULL) { - bfd_vma p_offset = i_phdrs[i].p_offset; - bfd_vma p_vaddr = i_phdrs[i].p_vaddr; + bfd_vma p_offset = i_phdrs[i].p_offset; /* Octets. */ + bfd_vma p_vaddr = i_phdrs[i].p_vaddr; /* Octets. */ if (i_phdrs[i].p_align > 1) { - p_offset &= -i_phdrs[i].p_align; - p_vaddr &= -i_phdrs[i].p_align; + p_offset &= -(i_phdrs[i].p_align * opb); + p_vaddr &= -(i_phdrs[i].p_align * opb); } if (p_offset == 0) { - loadbase = ehdr_vma - p_vaddr; + loadbase = ehdr_vma - p_vaddr / opb; first_phdr = &i_phdrs[i]; } } @@ -1846,9 +1848,9 @@ NAME(_bfd_elf,bfd_from_remote_memory) for (i = 0; i < i_ehdr.e_phnum; ++i) if (i_phdrs[i].p_type == PT_LOAD) { - bfd_vma start = i_phdrs[i].p_offset; - bfd_vma end = start + i_phdrs[i].p_filesz; - bfd_vma vaddr = i_phdrs[i].p_vaddr; + bfd_vma start = i_phdrs[i].p_offset; /* Octets. */ + bfd_vma end = start + i_phdrs[i].p_filesz; /* Octets. */ + bfd_vma vaddr = i_phdrs[i].p_vaddr; /* Octets. */ /* Extend the beginning of the first pt_load to cover file header and program headers, if we proved earlier that its @@ -1861,7 +1863,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) /* Extend the end of the last pt_load to cover section headers. */ if (last_phdr == &i_phdrs[i]) end = high_offset; - err = target_read_memory (loadbase + vaddr, + err = target_read_memory (loadbase + vaddr / opb, contents + start, end - start); if (err) { diff --git a/bfd/elflink.c b/bfd/elflink.c index 369f3cb..5852844 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11566,8 +11566,8 @@ elf_fixup_link_order (bfd *abfd, asection *o) struct bfd_link_order *p; bfd *sub; struct bfd_link_order **sections; - asection *s, *other_sec, *linkorder_sec; - bfd_vma offset; + asection *other_sec, *linkorder_sec; + bfd_vma offset; /* Octets. */ other_sec = NULL; linkorder_sec = NULL; @@ -11577,7 +11577,7 @@ elf_fixup_link_order (bfd *abfd, asection *o) { if (p->type == bfd_indirect_link_order) { - s = p->u.indirect.section; + asection *s = p->u.indirect.section; sub = s->owner; if ((s->flags & SEC_LINKER_CREATED) == 0 && bfd_get_flavour (sub) == bfd_target_elf_flavour @@ -11632,11 +11632,12 @@ elf_fixup_link_order (bfd *abfd, asection *o) for (n = 0; n < seen_linkorder; n++) { bfd_vma mask; - s = sections[n]->u.indirect.section; - mask = ~(bfd_vma) 0 << s->alignment_power; + asection *s = sections[n]->u.indirect.section; + unsigned int opb = bfd_octets_per_byte (abfd, s); + + mask = ~(bfd_vma) 0 << s->alignment_power * opb; offset = (offset + ~mask) & mask; - s->output_offset = offset / bfd_octets_per_byte (abfd, s); - sections[n]->offset = offset; + sections[n]->offset = s->output_offset = offset / opb; offset += sections[n]->size; } @@ -12247,7 +12248,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (htab->tls_sec) { - bfd_vma base, end = 0; + bfd_vma base, end = 0; /* Both bytes. */ asection *sec; for (sec = htab->tls_sec; @@ -12255,6 +12256,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) sec = sec->next) { bfd_size_type size = sec->size; + unsigned int opb = bfd_octets_per_byte (abfd, sec); if (size == 0 && (sec->flags & SEC_HAS_CONTENTS) == 0) @@ -12262,9 +12264,9 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) struct bfd_link_order *ord = sec->map_tail.link_order; if (ord != NULL) - size = ord->offset + ord->size; + size = ord->offset * opb + ord->size; } - end = sec->vma + size; + end = sec->vma + size / opb; } base = htab->tls_sec->vma; /* Only align end of TLS section if static TLS doesn't have special @@ -12777,6 +12779,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (bed->dtrel_excludes_plt && htab->srelplt != NULL) { + unsigned int opb = bfd_octets_per_byte (abfd, o); + /* Don't count procedure linkage table relocs in the overall reloc count. */ sh_size -= htab->srelplt->size; @@ -12796,7 +12800,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* If .rela.plt is the first .rela section, exclude it from DT_RELA. */ else if (sh_addr == (htab->srelplt->output_section->vma - + htab->srelplt->output_offset)) + + htab->srelplt->output_offset) * opb) sh_addr += htab->srelplt->size; } @@ -14251,7 +14255,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) { asection *i; int eh_changed = 0; - unsigned int eh_alignment; + unsigned int eh_alignment; /* Octets. */ for (i = o->map_head.s; i != NULL; i = i->map_head.s) { @@ -14278,7 +14282,8 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) fini_reloc_cookie_for_section (&cookie, i); } - eh_alignment = 1 << o->alignment_power; + eh_alignment = ((1 << o->alignment_power) + * bfd_octets_per_byte (output_bfd, o)); /* Skip over zero terminator, and prevent empty sections from adding alignment padding at the end. */ for (i = o->map_tail.s; i != NULL; i = i->map_tail.s) 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. */ |