* [PATCH 2/2] Fix several mix up between octets and bytes in ELF program headers
[not found] <20200215193050.22717-1-ceggers@gmx.de>
@ 2020-02-15 19:31 ` Christian Eggers
2020-03-02 14:18 ` Nick Clifton
2020-02-15 19:31 ` [PATCH 1/2] " Christian Eggers
1 sibling, 1 reply; 8+ messages in thread
From: Christian Eggers @ 2020-02-15 19:31 UTC (permalink / raw)
To: binutils; +Cc: amodra, Christian Eggers
This is a follow-up patch for my patch from december 09 with the same
subject. It 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 incorperated.
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.
Signed-off-by: Christian Eggers <ceggers@gmx.de>
---
bfd/bfd.c | 5 +++--
bfd/elf-bfd.h | 2 +-
bfd/elf.c | 54 +++++++++++++++++++++++++-------------------------
bfd/elfcode.h | 28 ++++++++++++++------------
bfd/elflink.c | 31 +++++++++++++++++------------
bfd/merge.c | 22 ++++++++++++--------
include/bfdlink.h | 4 ++--
include/elf/internal.h | 7 ++++---
8 files changed, 84 insertions(+), 69 deletions(-)
diff --git a/bfd/bfd.c b/bfd/bfd.c
index b1050626b68..5802985099a 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2162,7 +2162,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,
@@ -2170,6 +2170,7 @@ bfd_record_phdr (bfd *abfd,
{
struct elf_segment_map *m, **pm;
bfd_size_type amt;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
return TRUE;
@@ -2182,7 +2183,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 cbbba153f49..f74afacc976 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 BFD's loaded in the link. */
struct elf_link_loaded_list *loaded;
diff --git a/bfd/elf.c b/bfd/elf.c
index d941b33b15c..fbc45f6d30f 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4688,8 +4688,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
asection *first_mbind = NULL;
asection *dynsec, *eh_frame_hdr;
bfd_size_type 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. */
@@ -4717,8 +4717,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));
@@ -4802,7 +4802,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;
@@ -4842,7 +4842,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;
@@ -5030,7 +5030,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++;
@@ -5328,15 +5328,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)
@@ -5607,7 +5609,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)
@@ -5644,7 +5646,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
@@ -6007,7 +6009,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. */
@@ -6084,6 +6086,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);
@@ -6150,7 +6153,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)
@@ -6166,7 +6169,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
{
@@ -6191,7 +6194,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;
@@ -6211,13 +6214,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
@@ -7199,8 +7199,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
@@ -7268,7 +7268,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. */
@@ -7296,7 +7296,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);
}
}
@@ -7340,8 +7340,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
@@ -7407,7 +7407,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 e1e89cf78f2..9ffdba56b66 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -1635,10 +1635,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 */
@@ -1651,8 +1652,9 @@ 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;
+ 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);
@@ -1746,17 +1748,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];
}
}
@@ -1812,9 +1814,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
@@ -1827,7 +1829,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 43fbbf0dd1b..788fd803f35 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11570,8 +11570,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;
@@ -11581,7 +11581,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
@@ -11636,11 +11636,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;
}
@@ -12250,7 +12251,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;
@@ -12258,6 +12259,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)
@@ -12265,9 +12267,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
@@ -12780,6 +12782,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;
@@ -12799,7 +12803,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;
}
@@ -14254,7 +14258,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)
{
@@ -14281,7 +14285,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 2ed1ef595c4..59805325273 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. */
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 8d85530e390..40a6d4d40a6 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -801,9 +801,9 @@ struct bfd_link_order
struct bfd_link_order *next;
/* Type of link_order. */
enum bfd_link_order_type type;
- /* Offset within output section. */
+ /* Offset within output section in bytes. */
bfd_vma offset;
- /* Size within output section. */
+ /* Size within output section in octets. */
bfd_size_type size;
/* Type specific information. */
union
diff --git a/include/elf/internal.h b/include/elf/internal.h
index c436e64fe56..c9be57fa1f7 100644
--- a/include/elf/internal.h
+++ b/include/elf/internal.h
@@ -91,7 +91,8 @@ struct elf_internal_phdr {
bfd_vma p_paddr; /* Segment physical address in octets */
bfd_vma p_filesz; /* Segment size in file in octets */
bfd_vma p_memsz; /* Segment size in memory in octets */
- bfd_vma p_align; /* Segment alignment, file & memory */
+ bfd_vma p_align; /* Segment alignment in bytes, file
+ & memory */
};
typedef struct elf_internal_phdr Elf_Internal_Phdr;
@@ -266,13 +267,13 @@ struct elf_segment_map
unsigned long p_type;
/* Program segment flags. */
unsigned long p_flags;
- /* Program segment physical address. */
+ /* Program segment physical address in octets. */
bfd_vma p_paddr;
/* Program segment virtual address offset from section vma in bytes. */
bfd_vma p_vaddr_offset;
/* Program segment alignment. */
bfd_vma p_align;
- /* Segment size in file and memory */
+ /* Segment size in file and memory in octets. */
bfd_vma p_size;
/* Whether the p_flags field is valid; if not, the flags are based
on the section flags. */
--
2.16.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] Fix several mix up between octets and bytes in ELF program headers
[not found] <20200215193050.22717-1-ceggers@gmx.de>
2020-02-15 19:31 ` [PATCH 2/2] Fix several mix up between octets and bytes in ELF program headers Christian Eggers
@ 2020-02-15 19:31 ` Christian Eggers
2020-03-02 14:17 ` Nick Clifton
1 sibling, 1 reply; 8+ messages in thread
From: Christian Eggers @ 2020-02-15 19:31 UTC (permalink / raw)
To: binutils; +Cc: amodra, Christian Eggers
When converting between addresses in ELF headers [octets] and bfd
LMA/VMA [bytes], the number of octets per byte needs to be incorperated.
In ld, the SIZEOF_HEADERS linker script statement must be resolved to
bytes instead of octets.
Patch changelog:
v2:
- Keep ELF header entries as octets.
v3:
- Revert changes to elf32-rx.c and elf64-ia64-vmx.c
- Revert change of "break" statement in the patch for elf.c,
elf_link_add_object_symbols()
- Fix change of IS_CONTAINED_BY_LMA()
include/
* elf/internal.h (struct elf_internal_phdr): Add unit (octets)
to several member field comments.
(Elf_Internal_Shdr): likewise.
bfd/
* 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.
(_bfd_elf_make_section_from_phdr): Similarly.
(elf_fake_sections): Fix calculation of
Elf_Internal_shdr::sh_addr from section VMA.
(_bfd_elf_map_sections_to_segments): Fix mixup between octets
and bytes.
(assign_file_positions_for_load_sections): Fix calculations of
Elf_Internal_shdr::p_vaddr and p_paddr from section LMA/VMA. Fix
comparison between program header address and section LMA.
(assign_file_positions_for_non_load_sections): Likewise.
(rewrite_elf_program_header): Likewise. Introduce new temp opb.
(IS_CONTAINED_BY_VMA): Add parameter opb.
(IS_CONTAINED_BY_LMA,IS_SECTION_IN_INPUT_SEGMENT,
INCLUDE_SECTION_IN_SEGMENT): Likewise.
(copy_elf_program_header): Update call to
ELF_SECTION_IN_SEGMENT(). Fix calculations of p_addr_valid and
p_vaddr_offset.
* elflink.c (elf_link_add_object_symbols): Multiply section VMA
with octets per byte when comparing against p_vaddr.
ld/
* ldexp.c (fold_name): Return SIZEOF_HEADERS in bytes.
Signed-off-by: Christian Eggers <ceggers@gmx.de>
---
bfd/elf.c | 131 ++++++++++++++++++++++++++++---------------------
bfd/elflink.c | 12 +++--
include/elf/internal.h | 19 +++----
ld/ldexp.c | 3 +-
4 files changed, 95 insertions(+), 70 deletions(-)
diff --git a/bfd/elf.c b/bfd/elf.c
index c85face6309..d941b33b15c 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1028,6 +1028,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
asection *newsect;
flagword flags;
const struct elf_backend_data *bed;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
if (hdr->bfd_section != NULL)
return TRUE;
@@ -1046,11 +1047,6 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
newsect->filepos = hdr->sh_offset;
- if (!bfd_set_section_vma (newsect, hdr->sh_addr)
- || !bfd_set_section_size (newsect, hdr->sh_size)
- || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign)))
- return FALSE;
-
flags = SEC_NO_FLAGS;
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_HAS_CONTENTS;
@@ -1108,7 +1104,10 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
flags |= SEC_DEBUGGING | SEC_ELF_OCTETS;
else if (strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) == 0
|| strncmp (name, ".note.gnu", 9) == 0)
- flags |= SEC_ELF_OCTETS;
+ {
+ flags |= SEC_ELF_OCTETS;
+ opb = 1;
+ }
else if (strncmp (name, ".line", 5) == 0
|| strncmp (name, ".stab", 5) == 0
|| strcmp (name, ".gdb_index") == 0)
@@ -1116,6 +1115,11 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
}
}
+ if (!bfd_set_section_vma (newsect, hdr->sh_addr / opb)
+ || !bfd_set_section_size (newsect, hdr->sh_size)
+ || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign)))
+ return FALSE;
+
/* As a GNU extension, if the name begins with .gnu.linkonce, we
only link a single copy of the section. This is used to support
g++. g++ will emit each template expansion in its own section.
@@ -1177,7 +1181,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
{
if ((flags & SEC_LOAD) == 0)
newsect->lma = (phdr->p_paddr
- + hdr->sh_addr - phdr->p_vaddr);
+ + hdr->sh_addr - phdr->p_vaddr) / opb;
else
/* We used to use the same adjustment for SEC_LOAD
sections, but that doesn't work if the segment
@@ -1187,7 +1191,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
segment will contain sections with contiguous
LMAs, even if the VMAs are not. */
newsect->lma = (phdr->p_paddr
- + hdr->sh_offset - phdr->p_offset);
+ + hdr->sh_offset - phdr->p_offset) / opb;
/* With contiguous segments, we can't tell from file
offsets whether a section with zero size should
@@ -2970,6 +2974,7 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
char namebuf[64];
size_t len;
int split;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
split = ((hdr->p_memsz > 0)
&& (hdr->p_filesz > 0)
@@ -2986,8 +2991,8 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
newsect = bfd_make_section (abfd, name);
if (newsect == NULL)
return FALSE;
- newsect->vma = hdr->p_vaddr;
- newsect->lma = hdr->p_paddr;
+ newsect->vma = hdr->p_vaddr / opb;
+ newsect->lma = hdr->p_paddr / opb;
newsect->size = hdr->p_filesz;
newsect->filepos = hdr->p_offset;
newsect->flags |= SEC_HAS_CONTENTS;
@@ -3022,8 +3027,8 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
newsect = bfd_make_section (abfd, name);
if (newsect == NULL)
return FALSE;
- newsect->vma = hdr->p_vaddr + hdr->p_filesz;
- newsect->lma = hdr->p_paddr + hdr->p_filesz;
+ newsect->vma = (hdr->p_vaddr + hdr->p_filesz) / opb;
+ newsect->lma = (hdr->p_paddr + hdr->p_filesz) / opb;
newsect->size = hdr->p_memsz - hdr->p_filesz;
newsect->filepos = hdr->p_offset + hdr->p_filesz;
align = newsect->vma & -newsect->vma;
@@ -3299,7 +3304,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
if ((asect->flags & SEC_ALLOC) != 0
|| asect->user_set_vma)
- this_hdr->sh_addr = asect->vma;
+ this_hdr->sh_addr = asect->vma * bfd_octets_per_byte (abfd, asect);
else
this_hdr->sh_addr = 0;
@@ -4685,6 +4690,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
bfd_size_type amt;
bfd_vma addr_mask, wrap_to = 0;
bfd_size_type phdr_size;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
/* Select the allocated sections, and sort them. */
@@ -4724,6 +4730,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
if (phdr_size == (bfd_size_type) -1)
phdr_size = get_program_header_size (abfd, info);
phdr_size += bed->s->sizeof_ehdr;
+ /* phdr_size is compared to LMA values which are in bytes */
+ phdr_size /= opb;
maxpagesize = bed->maxpagesize;
if (maxpagesize == 0)
maxpagesize = 1;
@@ -4948,7 +4956,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
executable = TRUE;
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
- last_size = !IS_TBSS (hdr) ? hdr->size : 0;
+ last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
continue;
}
@@ -4974,7 +4982,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
- last_size = !IS_TBSS (hdr) ? hdr->size : 0;
+ last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
hdr_index = i;
phdr_in_segment = FALSE;
}
@@ -5428,11 +5436,12 @@ assign_file_positions_for_load_sections (bfd *abfd,
struct elf_segment_map *phdr_load_seg;
Elf_Internal_Phdr *phdrs;
Elf_Internal_Phdr *p;
- file_ptr off;
+ file_ptr off; /* octets */
bfd_size_type maxpagesize;
unsigned int alloc, actual;
unsigned int i, j;
struct elf_segment_map **sorted_seg_map;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
if (link_info == NULL
&& !_bfd_elf_map_sections_to_segments (abfd, link_info))
@@ -5540,7 +5549,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
for (j = 0; j < alloc; j++)
{
asection **secpp;
- bfd_vma off_adjust;
+ bfd_vma off_adjust; /* octets */
bfd_boolean no_contents;
/* An ELF segment (described by Elf_Internal_Phdr) may contain a
@@ -5554,16 +5563,16 @@ assign_file_positions_for_load_sections (bfd *abfd,
p->p_flags = m->p_flags;
if (m->count == 0)
- p->p_vaddr = m->p_vaddr_offset;
+ p->p_vaddr = m->p_vaddr_offset * opb;
else
- p->p_vaddr = m->sections[0]->vma + m->p_vaddr_offset;
+ p->p_vaddr = (m->sections[0]->vma + m->p_vaddr_offset) * opb;
if (m->p_paddr_valid)
p->p_paddr = m->p_paddr;
else if (m->count == 0)
p->p_paddr = 0;
else
- p->p_paddr = m->sections[0]->lma + m->p_vaddr_offset;
+ p->p_paddr = (m->sections[0]->lma + m->p_vaddr_offset) * opb;
if (p->p_type == PT_LOAD
&& (abfd->flags & D_PAGED) != 0)
@@ -5644,7 +5653,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
&& (abfd->flags & D_PAGED) != 0
&& bed->no_page_alias
&& (off & (maxpagesize - 1)) != 0
- && (off & -maxpagesize) == ((off + off_adjust) & -maxpagesize))
+ && ((off & -maxpagesize)
+ == ((off + off_adjust) & -maxpagesize)))
off_adjust += maxpagesize;
off += off_adjust;
if (no_contents)
@@ -5735,7 +5745,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
else if (phdr_load_seg != NULL)
{
Elf_Internal_Phdr *phdr = phdrs + phdr_load_seg->idx;
- bfd_vma phdr_off = 0;
+ bfd_vma phdr_off = 0; /* octets */
if (phdr_load_seg->includes_filehdr)
phdr_off = bed->s->sizeof_ehdr;
p->p_vaddr = phdr->p_vaddr + phdr_off;
@@ -5769,7 +5779,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
}
else
{
- file_ptr adjust;
+ file_ptr adjust; /* octets */
adjust = off - (p->p_offset + p->p_filesz);
if (!no_contents)
@@ -5800,10 +5810,10 @@ assign_file_positions_for_load_sections (bfd *abfd,
&& ((this_hdr->sh_flags & SHF_TLS) == 0
|| p->p_type == PT_TLS))))
{
- bfd_vma p_start = p->p_paddr;
- bfd_vma p_end = p_start + p->p_memsz;
- bfd_vma s_start = sec->lma;
- bfd_vma adjust = s_start - p_end;
+ bfd_vma p_start = p->p_paddr; /* octets */
+ bfd_vma p_end = p_start + p->p_memsz; /* octets */
+ bfd_vma s_start = sec->lma * opb; /* octets */
+ bfd_vma adjust = s_start - p_end; /* octets */
if (adjust != 0
&& (s_start < p_end
@@ -5812,9 +5822,10 @@ assign_file_positions_for_load_sections (bfd *abfd,
_bfd_error_handler
/* xgettext:c-format */
(_("%pB: section %pA lma %#" PRIx64 " adjusted to %#" PRIx64),
- abfd, sec, (uint64_t) s_start, (uint64_t) p_end);
+ abfd, sec, (uint64_t) s_start / opb,
+ (uint64_t) p_end / opb);
adjust = 0;
- sec->lma = p_end;
+ sec->lma = p_end / opb;
}
p->p_memsz += adjust;
@@ -6200,8 +6211,11 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
if (i < lm->count)
{
- p->p_vaddr = lm->sections[i]->vma;
- p->p_paddr = lm->sections[i]->lma;
+ 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_filesz = p->p_memsz;
@@ -6800,6 +6814,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
struct elf_segment_map *phdr_adjust_seg = NULL;
unsigned int phdr_adjust_num = 0;
const struct elf_backend_data *bed;
+ unsigned int opb = bfd_octets_per_byte (ibfd, NULL);
bed = get_elf_backend_data (ibfd);
iehdr = elf_elfheader (ibfd);
@@ -6822,17 +6837,17 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Returns TRUE if the given section is contained within
the given segment. VMA addresses are compared. */
-#define IS_CONTAINED_BY_VMA(section, segment) \
- (section->vma >= segment->p_vaddr \
- && (section->vma + SECTION_SIZE (section, segment) \
+#define IS_CONTAINED_BY_VMA(section, segment, opb) \
+ (section->vma * (opb) >= segment->p_vaddr \
+ && (section->vma * (opb) + SECTION_SIZE (section, segment) \
<= (SEGMENT_END (segment, segment->p_vaddr))))
/* Returns TRUE if the given section is contained within
the given segment. LMA addresses are compared. */
-#define IS_CONTAINED_BY_LMA(section, segment, base) \
- (section->lma >= base \
- && (section->lma + SECTION_SIZE (section, segment) >= section->lma) \
- && (section->lma + SECTION_SIZE (section, segment) \
+#define IS_CONTAINED_BY_LMA(section, segment, base, opb) \
+ (section->lma * (opb) >= base \
+ && (section->lma + SECTION_SIZE (section, segment) / (opb) >= section->lma) \
+ && (section->lma * (opb) + SECTION_SIZE (section, segment) \
<= SEGMENT_END (segment, base)))
/* Handle PT_NOTE segment. */
@@ -6878,10 +6893,10 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
8. PT_DYNAMIC should not contain empty sections at the beginning
(with the possible exception of .dynamic). */
-#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \
+#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed, opb) \
((((segment->p_paddr \
- ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \
- : IS_CONTAINED_BY_VMA (section, segment)) \
+ ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr, opb) \
+ : IS_CONTAINED_BY_VMA (section, segment, opb)) \
&& (section->flags & SEC_ALLOC) != 0) \
|| IS_NOTE (segment, section)) \
&& segment->p_type != PT_GNU_STACK \
@@ -6893,15 +6908,15 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
&& (segment->p_type != PT_DYNAMIC \
|| SECTION_SIZE (section, segment) > 0 \
|| (segment->p_paddr \
- ? segment->p_paddr != section->lma \
- : segment->p_vaddr != section->vma) \
+ ? segment->p_paddr != section->lma * (opb) \
+ : segment->p_vaddr != section->vma * (opb)) \
|| (strcmp (bfd_section_name (section), ".dynamic") == 0)) \
&& (segment->p_type != PT_LOAD || !section->segment_mark))
/* If the output section of a section in the input segment is NULL,
it is removed from the corresponding output segment. */
-#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
- (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed) \
+#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed, opb) \
+ (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb) \
&& section->output_section != NULL)
/* Returns TRUE iff seg1 starts after the end of seg2. */
@@ -6955,7 +6970,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
/* Mininal change so that the normal section to segment
assignment code will work. */
- segment->p_vaddr = section->vma;
+ segment->p_vaddr = section->vma * opb;
break;
}
@@ -7041,7 +7056,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
/* Find the first section in the input segment, which may be
removed from the corresponding output segment. */
- if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed))
+ if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb))
{
if (first_section == NULL)
first_section = section;
@@ -7109,7 +7124,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
" at vaddr=%#" PRIx64 ", is this intentional?"),
ibfd, (uint64_t) segment->p_vaddr);
- map->p_vaddr_offset = segment->p_vaddr;
+ map->p_vaddr_offset = segment->p_vaddr / opb;
map->count = 0;
*pointer_to_map = map;
pointer_to_map = &map->next;
@@ -7163,7 +7178,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
section != NULL;
section = section->next)
{
- if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
+ if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed, opb))
{
output_section = section->output_section;
@@ -7190,10 +7205,11 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Match up the physical address of the segment with the
LMA address of the output section. */
- if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
+ if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr,
+ opb)
|| IS_COREFILE_NOTE (segment, section)
|| (bed->want_p_paddr_set_to_zero
- && IS_CONTAINED_BY_VMA (output_section, segment)))
+ && IS_CONTAINED_BY_VMA (output_section, segment, opb)))
{
if (matching_lma == NULL
|| output_section->lma < matching_lma->lma)
@@ -7237,7 +7253,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Account for padding before the first section in the
segment. */
- map->p_vaddr_offset = map->p_paddr + hdr_size - matching_lma->lma;
+ map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
+ - matching_lma->lma);
}
free (sections);
@@ -7308,7 +7325,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
BFD_ASSERT (output_section != NULL);
- if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
+ if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr,
+ opb)
|| IS_COREFILE_NOTE (segment, section))
{
if (map->count == 0)
@@ -7460,6 +7478,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
unsigned int num_segments;
bfd_boolean phdr_included = FALSE;
bfd_boolean p_paddr_valid;
+ unsigned int opb = bfd_octets_per_byte (ibfd, NULL);
iehdr = elf_elfheader (ibfd);
@@ -7585,7 +7604,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
seg_off = this_hdr->sh_offset - segment->p_offset;
else
seg_off = this_hdr->sh_addr - segment->p_vaddr;
- if (section->lma - segment->p_paddr != seg_off)
+ if (section->lma * opb - segment->p_paddr != seg_off)
map->p_paddr_valid = FALSE;
}
if (isec == section_count)
@@ -7595,7 +7614,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
}
if (section_count == 0)
- map->p_vaddr_offset = segment->p_vaddr;
+ map->p_vaddr_offset = segment->p_vaddr / opb;
else if (map->p_paddr_valid)
{
/* Account for padding before the first section in the segment. */
@@ -7605,7 +7624,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
if (map->includes_phdrs)
hdr_size += iehdr->e_phnum * iehdr->e_phentsize;
- map->p_vaddr_offset = (map->p_paddr + hdr_size
+ map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
- (lowest_section ? lowest_section->lma : 0));
}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 3add9f18bd7..43fbbf0dd1b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4227,10 +4227,14 @@ error_free_dyn:
if (phdr->p_type == PT_GNU_RELRO)
{
for (s = abfd->sections; s != NULL; s = s->next)
- if ((s->flags & SEC_ALLOC) != 0
- && s->vma >= phdr->p_vaddr
- && s->vma + s->size <= phdr->p_vaddr + phdr->p_memsz)
- s->flags |= SEC_READONLY;
+ {
+ unsigned int opb = bfd_octets_per_byte (abfd, s);
+
+ if ((s->flags & SEC_ALLOC) != 0
+ && s->vma * opb >= phdr->p_vaddr
+ && s->vma * opb + s->size <= phdr->p_vaddr + phdr->p_memsz)
+ s->flags |= SEC_READONLY;
+ }
break;
}
diff --git a/include/elf/internal.h b/include/elf/internal.h
index 844675c30f3..c436e64fe56 100644
--- a/include/elf/internal.h
+++ b/include/elf/internal.h
@@ -86,11 +86,11 @@ typedef struct elf_internal_ehdr {
struct elf_internal_phdr {
unsigned long p_type; /* Identifies program segment type */
unsigned long p_flags; /* Segment flags */
- bfd_vma p_offset; /* Segment file offset */
- bfd_vma p_vaddr; /* Segment virtual address */
- bfd_vma p_paddr; /* Segment physical address */
- bfd_vma p_filesz; /* Segment size in file */
- bfd_vma p_memsz; /* Segment size in memory */
+ bfd_vma p_offset; /* Segment file offset in octets */
+ bfd_vma p_vaddr; /* Segment virtual address in octets */
+ bfd_vma p_paddr; /* Segment physical address in octets */
+ bfd_vma p_filesz; /* Segment size in file in octets */
+ bfd_vma p_memsz; /* Segment size in memory in octets */
bfd_vma p_align; /* Segment alignment, file & memory */
};
@@ -102,9 +102,10 @@ typedef struct elf_internal_shdr {
unsigned int sh_name; /* Section name, index in string tbl */
unsigned int sh_type; /* Type of section */
bfd_vma sh_flags; /* Miscellaneous section attributes */
- bfd_vma sh_addr; /* Section virtual addr at execution */
- file_ptr sh_offset; /* Section file offset */
- bfd_size_type sh_size; /* Size of section in bytes */
+ bfd_vma sh_addr; /* Section virtual addr at execution in
+ octets */
+ file_ptr sh_offset; /* Section file offset in octets */
+ bfd_size_type sh_size; /* Size of section in octets */
unsigned int sh_link; /* Index of another section */
unsigned int sh_info; /* Additional section information */
bfd_vma sh_addralign; /* Section alignment */
@@ -267,7 +268,7 @@ struct elf_segment_map
unsigned long p_flags;
/* Program segment physical address. */
bfd_vma p_paddr;
- /* Program segment virtual address offset from section vma. */
+ /* Program segment virtual address offset from section vma in bytes. */
bfd_vma p_vaddr_offset;
/* Program segment alignment. */
bfd_vma p_align;
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 6d1457b929a..3ffabb8c1da 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -700,7 +700,8 @@ fold_name (etree_type *tree)
/* Don't find the real header size if only marking sections;
The bfd function may cache incorrect data. */
if (expld.phase != lang_mark_phase_enum)
- hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info);
+ hdr_size = (bfd_sizeof_headers (link_info.output_bfd, &link_info)
+ / bfd_octets_per_byte (link_info.output_bfd, NULL));
new_number (hdr_size);
}
break;
--
2.16.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] Fix several mix up between octets and bytes in ELF program headers
2020-02-15 19:31 ` [PATCH 1/2] " Christian Eggers
@ 2020-03-02 14:17 ` Nick Clifton
2020-03-02 20:11 ` [PATCH v4] " Christian Eggers
0 siblings, 1 reply; 8+ messages in thread
From: Nick Clifton @ 2020-03-02 14:17 UTC (permalink / raw)
To: Christian Eggers, binutils; +Cc: amodra
Hi Christian,
> include/
> * elf/internal.h (struct elf_internal_phdr): Add unit (octets)
> to several member field comments.
> (Elf_Internal_Shdr): likewise.
>
> bfd/
> * 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.
> (_bfd_elf_make_section_from_phdr): Similarly.
> (elf_fake_sections): Fix calculation of
> Elf_Internal_shdr::sh_addr from section VMA.
> (_bfd_elf_map_sections_to_segments): Fix mixup between octets
> and bytes.
> (assign_file_positions_for_load_sections): Fix calculations of
> Elf_Internal_shdr::p_vaddr and p_paddr from section LMA/VMA. Fix
> comparison between program header address and section LMA.
> (assign_file_positions_for_non_load_sections): Likewise.
> (rewrite_elf_program_header): Likewise. Introduce new temp opb.
> (IS_CONTAINED_BY_VMA): Add parameter opb.
> (IS_CONTAINED_BY_LMA,IS_SECTION_IN_INPUT_SEGMENT,
> INCLUDE_SECTION_IN_SEGMENT): Likewise.
> (copy_elf_program_header): Update call to
> ELF_SECTION_IN_SEGMENT(). Fix calculations of p_addr_valid and
> p_vaddr_offset.
> * elflink.c (elf_link_add_object_symbols): Multiply section VMA
> with octets per byte when comparing against p_vaddr.
>
> ld/
> * ldexp.c (fold_name): Return SIZEOF_HEADERS in bytes.
Approved - please apply - but with one change:
> + bfd_vma p_start = p->p_paddr; /* octets */
Please could yoy change the format of these comments so that they follow
the GNU Coding Standard guidelines ? Ie, please start with a capital
letter and end with a period:
/* Octets. */
And similarly for you /* bytes */ comments - they should be /* Bytes. */
Thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] Fix several mix up between octets and bytes in ELF program headers
2020-02-15 19:31 ` [PATCH 2/2] Fix several mix up between octets and bytes in ELF program headers Christian Eggers
@ 2020-03-02 14:18 ` Nick Clifton
2020-03-02 20:17 ` [PATCH v2 " Christian Eggers
0 siblings, 1 reply; 8+ messages in thread
From: Nick Clifton @ 2020-03-02 14:18 UTC (permalink / raw)
To: Christian Eggers, binutils; +Cc: amodra
Hi Christian,
> 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.
Approved - please apply - but please fixup the comments first.
Cheers
Nick
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4] Fix several mix up between octets and bytes in ELF program headers
2020-03-02 14:17 ` Nick Clifton
@ 2020-03-02 20:11 ` Christian Eggers
0 siblings, 0 replies; 8+ messages in thread
From: Christian Eggers @ 2020-03-02 20:11 UTC (permalink / raw)
To: binutils, Nick Clifton; +Cc: amodra, Christian Eggers
On Monday, March 2nd 2020, Nick Clifton wrote:
> Approved - please apply - but with one change:
> > + bfd_vma p_start = p->p_paddr; /* octets */
>
> Please could yoy change the format of these comments so that they follow
> the GNU Coding Standard guidelines ? Ie, please start with a capital
> letter and end with a period:
>
> /* Octets. */
>
> And similarly for you /* bytes */ comments - they should be /* Bytes. */
Changed all occurrences in the patch.
Thanks
Christian
---
When converting between addresses in ELF headers [octets] and bfd
LMA/VMA [bytes], the number of octets per byte needs to be incorperated.
In ld, the SIZEOF_HEADERS linker script statement must be resolved to
bytes instead of octets.
Patch changelog:
v2:
- Keep ELF header entries as octets.
v3:
- Revert changes to elf32-rx.c and elf64-ia64-vmx.c
- Revert change of "break" statement in the patch for elf.c,
elf_link_add_object_symbols()
- Fix change of IS_CONTAINED_BY_LMA()
v4:
- GNU coding style for comments.
include/
* elf/internal.h (struct elf_internal_phdr): Add unit (octets)
to several member field comments.
(Elf_Internal_Shdr): likewise.
bfd/
* 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.
(_bfd_elf_make_section_from_phdr): Similarly.
(elf_fake_sections): Fix calculation of
Elf_Internal_shdr::sh_addr from section VMA.
(_bfd_elf_map_sections_to_segments): Fix mixup between octets
and bytes.
(assign_file_positions_for_load_sections): Fix calculations of
Elf_Internal_shdr::p_vaddr and p_paddr from section LMA/VMA. Fix
comparison between program header address and section LMA.
(assign_file_positions_for_non_load_sections): Likewise.
(rewrite_elf_program_header): Likewise. Introduce new temp opb.
(IS_CONTAINED_BY_VMA): Add parameter opb.
(IS_CONTAINED_BY_LMA,IS_SECTION_IN_INPUT_SEGMENT,
INCLUDE_SECTION_IN_SEGMENT): Likewise.
(copy_elf_program_header): Update call to
ELF_SECTION_IN_SEGMENT(). Fix calculations of p_addr_valid and
p_vaddr_offset.
* elflink.c (elf_link_add_object_symbols): Multiply section VMA
with octets per byte when comparing against p_vaddr.
ld/
* ldexp.c (fold_name): Return SIZEOF_HEADERS in bytes.
Signed-off-by: Christian Eggers <ceggers@gmx.de>
---
bfd/elf.c | 131 ++++++++++++++++++++++++++++---------------------
bfd/elflink.c | 12 +++--
include/elf/internal.h | 25 +++++-----
ld/ldexp.c | 3 +-
4 files changed, 98 insertions(+), 73 deletions(-)
diff --git a/bfd/elf.c b/bfd/elf.c
index fcd84d2d17b..a329e239828 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1016,6 +1016,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
asection *newsect;
flagword flags;
const struct elf_backend_data *bed;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
if (hdr->bfd_section != NULL)
return TRUE;
@@ -1034,11 +1035,6 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
newsect->filepos = hdr->sh_offset;
- if (!bfd_set_section_vma (newsect, hdr->sh_addr)
- || !bfd_set_section_size (newsect, hdr->sh_size)
- || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign)))
- return FALSE;
-
flags = SEC_NO_FLAGS;
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_HAS_CONTENTS;
@@ -1096,7 +1092,10 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
flags |= SEC_DEBUGGING | SEC_ELF_OCTETS;
else if (strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) == 0
|| strncmp (name, ".note.gnu", 9) == 0)
- flags |= SEC_ELF_OCTETS;
+ {
+ flags |= SEC_ELF_OCTETS;
+ opb = 1;
+ }
else if (strncmp (name, ".line", 5) == 0
|| strncmp (name, ".stab", 5) == 0
|| strcmp (name, ".gdb_index") == 0)
@@ -1104,6 +1103,11 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
}
}
+ if (!bfd_set_section_vma (newsect, hdr->sh_addr / opb)
+ || !bfd_set_section_size (newsect, hdr->sh_size)
+ || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign)))
+ return FALSE;
+
/* As a GNU extension, if the name begins with .gnu.linkonce, we
only link a single copy of the section. This is used to support
g++. g++ will emit each template expansion in its own section.
@@ -1165,7 +1169,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
{
if ((newsect->flags & SEC_LOAD) == 0)
newsect->lma = (phdr->p_paddr
- + hdr->sh_addr - phdr->p_vaddr);
+ + hdr->sh_addr - phdr->p_vaddr) / opb;
else
/* We used to use the same adjustment for SEC_LOAD
sections, but that doesn't work if the segment
@@ -1175,7 +1179,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
segment will contain sections with contiguous
LMAs, even if the VMAs are not. */
newsect->lma = (phdr->p_paddr
- + hdr->sh_offset - phdr->p_offset);
+ + hdr->sh_offset - phdr->p_offset) / opb;
/* With contiguous segments, we can't tell from file
offsets whether a section with zero size should
@@ -2945,6 +2949,7 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
char namebuf[64];
size_t len;
int split;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
split = ((hdr->p_memsz > 0)
&& (hdr->p_filesz > 0)
@@ -2961,8 +2966,8 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
newsect = bfd_make_section (abfd, name);
if (newsect == NULL)
return FALSE;
- newsect->vma = hdr->p_vaddr;
- newsect->lma = hdr->p_paddr;
+ newsect->vma = hdr->p_vaddr / opb;
+ newsect->lma = hdr->p_paddr / opb;
newsect->size = hdr->p_filesz;
newsect->filepos = hdr->p_offset;
newsect->flags |= SEC_HAS_CONTENTS;
@@ -2997,8 +3002,8 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
newsect = bfd_make_section (abfd, name);
if (newsect == NULL)
return FALSE;
- newsect->vma = hdr->p_vaddr + hdr->p_filesz;
- newsect->lma = hdr->p_paddr + hdr->p_filesz;
+ newsect->vma = (hdr->p_vaddr + hdr->p_filesz) / opb;
+ newsect->lma = (hdr->p_paddr + hdr->p_filesz) / opb;
newsect->size = hdr->p_memsz - hdr->p_filesz;
newsect->filepos = hdr->p_offset + hdr->p_filesz;
align = newsect->vma & -newsect->vma;
@@ -3274,7 +3279,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
if ((asect->flags & SEC_ALLOC) != 0
|| asect->user_set_vma)
- this_hdr->sh_addr = asect->vma;
+ this_hdr->sh_addr = asect->vma * bfd_octets_per_byte (abfd, asect);
else
this_hdr->sh_addr = 0;
@@ -4662,6 +4667,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
size_t amt;
bfd_vma addr_mask, wrap_to = 0;
bfd_size_type phdr_size;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
/* Select the allocated sections, and sort them. */
@@ -4701,6 +4707,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
if (phdr_size == (bfd_size_type) -1)
phdr_size = get_program_header_size (abfd, info);
phdr_size += bed->s->sizeof_ehdr;
+ /* phdr_size is compared to LMA values which are in bytes. */
+ phdr_size /= opb;
maxpagesize = bed->maxpagesize;
if (maxpagesize == 0)
maxpagesize = 1;
@@ -4925,7 +4933,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
executable = TRUE;
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
- last_size = !IS_TBSS (hdr) ? hdr->size : 0;
+ last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
continue;
}
@@ -4951,7 +4959,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
- last_size = !IS_TBSS (hdr) ? hdr->size : 0;
+ last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
hdr_index = i;
phdr_in_segment = FALSE;
}
@@ -5405,11 +5413,12 @@ assign_file_positions_for_load_sections (bfd *abfd,
struct elf_segment_map *phdr_load_seg;
Elf_Internal_Phdr *phdrs;
Elf_Internal_Phdr *p;
- file_ptr off;
+ file_ptr off; /* Octets. */
bfd_size_type maxpagesize;
unsigned int alloc, actual;
unsigned int i, j;
struct elf_segment_map **sorted_seg_map;
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
if (link_info == NULL
&& !_bfd_elf_map_sections_to_segments (abfd, link_info))
@@ -5517,7 +5526,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
for (j = 0; j < alloc; j++)
{
asection **secpp;
- bfd_vma off_adjust;
+ bfd_vma off_adjust; /* Octets. */
bfd_boolean no_contents;
/* An ELF segment (described by Elf_Internal_Phdr) may contain a
@@ -5531,16 +5540,16 @@ assign_file_positions_for_load_sections (bfd *abfd,
p->p_flags = m->p_flags;
if (m->count == 0)
- p->p_vaddr = m->p_vaddr_offset;
+ p->p_vaddr = m->p_vaddr_offset * opb;
else
- p->p_vaddr = m->sections[0]->vma + m->p_vaddr_offset;
+ p->p_vaddr = (m->sections[0]->vma + m->p_vaddr_offset) * opb;
if (m->p_paddr_valid)
p->p_paddr = m->p_paddr;
else if (m->count == 0)
p->p_paddr = 0;
else
- p->p_paddr = m->sections[0]->lma + m->p_vaddr_offset;
+ p->p_paddr = (m->sections[0]->lma + m->p_vaddr_offset) * opb;
if (p->p_type == PT_LOAD
&& (abfd->flags & D_PAGED) != 0)
@@ -5621,7 +5630,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
&& (abfd->flags & D_PAGED) != 0
&& bed->no_page_alias
&& (off & (maxpagesize - 1)) != 0
- && (off & -maxpagesize) == ((off + off_adjust) & -maxpagesize))
+ && ((off & -maxpagesize)
+ == ((off + off_adjust) & -maxpagesize)))
off_adjust += maxpagesize;
off += off_adjust;
if (no_contents)
@@ -5712,7 +5722,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
else if (phdr_load_seg != NULL)
{
Elf_Internal_Phdr *phdr = phdrs + phdr_load_seg->idx;
- bfd_vma phdr_off = 0;
+ bfd_vma phdr_off = 0; /* Octets. */
if (phdr_load_seg->includes_filehdr)
phdr_off = bed->s->sizeof_ehdr;
p->p_vaddr = phdr->p_vaddr + phdr_off;
@@ -5746,7 +5756,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
}
else
{
- file_ptr adjust;
+ file_ptr adjust; /* Octets. */
adjust = off - (p->p_offset + p->p_filesz);
if (!no_contents)
@@ -5777,10 +5787,10 @@ assign_file_positions_for_load_sections (bfd *abfd,
&& ((this_hdr->sh_flags & SHF_TLS) == 0
|| p->p_type == PT_TLS))))
{
- bfd_vma p_start = p->p_paddr;
- bfd_vma p_end = p_start + p->p_memsz;
- bfd_vma s_start = sec->lma;
- bfd_vma adjust = s_start - p_end;
+ bfd_vma p_start = p->p_paddr; /* Octets. */
+ bfd_vma p_end = p_start + p->p_memsz; /* Octets. */
+ bfd_vma s_start = sec->lma * opb; /* Octets. */
+ bfd_vma adjust = s_start - p_end; /* Octets. */
if (adjust != 0
&& (s_start < p_end
@@ -5789,9 +5799,10 @@ assign_file_positions_for_load_sections (bfd *abfd,
_bfd_error_handler
/* xgettext:c-format */
(_("%pB: section %pA lma %#" PRIx64 " adjusted to %#" PRIx64),
- abfd, sec, (uint64_t) s_start, (uint64_t) p_end);
+ abfd, sec, (uint64_t) s_start / opb,
+ (uint64_t) p_end / opb);
adjust = 0;
- sec->lma = p_end;
+ sec->lma = p_end / opb;
}
p->p_memsz += adjust;
@@ -6181,8 +6192,11 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
if (i < lm->count)
{
- p->p_vaddr = lm->sections[i]->vma;
- p->p_paddr = lm->sections[i]->lma;
+ 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_filesz = p->p_memsz;
@@ -6781,6 +6795,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
struct elf_segment_map *phdr_adjust_seg = NULL;
unsigned int phdr_adjust_num = 0;
const struct elf_backend_data *bed;
+ unsigned int opb = bfd_octets_per_byte (ibfd, NULL);
bed = get_elf_backend_data (ibfd);
iehdr = elf_elfheader (ibfd);
@@ -6803,17 +6818,17 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Returns TRUE if the given section is contained within
the given segment. VMA addresses are compared. */
-#define IS_CONTAINED_BY_VMA(section, segment) \
- (section->vma >= segment->p_vaddr \
- && (section->vma + SECTION_SIZE (section, segment) \
+#define IS_CONTAINED_BY_VMA(section, segment, opb) \
+ (section->vma * (opb) >= segment->p_vaddr \
+ && (section->vma * (opb) + SECTION_SIZE (section, segment) \
<= (SEGMENT_END (segment, segment->p_vaddr))))
/* Returns TRUE if the given section is contained within
the given segment. LMA addresses are compared. */
-#define IS_CONTAINED_BY_LMA(section, segment, base) \
- (section->lma >= base \
- && (section->lma + SECTION_SIZE (section, segment) >= section->lma) \
- && (section->lma + SECTION_SIZE (section, segment) \
+#define IS_CONTAINED_BY_LMA(section, segment, base, opb) \
+ (section->lma * (opb) >= base \
+ && (section->lma + SECTION_SIZE (section, segment) / (opb) >= section->lma) \
+ && (section->lma * (opb) + SECTION_SIZE (section, segment) \
<= SEGMENT_END (segment, base)))
/* Handle PT_NOTE segment. */
@@ -6859,10 +6874,10 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
8. PT_DYNAMIC should not contain empty sections at the beginning
(with the possible exception of .dynamic). */
-#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \
+#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed, opb) \
((((segment->p_paddr \
- ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \
- : IS_CONTAINED_BY_VMA (section, segment)) \
+ ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr, opb) \
+ : IS_CONTAINED_BY_VMA (section, segment, opb)) \
&& (section->flags & SEC_ALLOC) != 0) \
|| IS_NOTE (segment, section)) \
&& segment->p_type != PT_GNU_STACK \
@@ -6874,15 +6889,15 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
&& (segment->p_type != PT_DYNAMIC \
|| SECTION_SIZE (section, segment) > 0 \
|| (segment->p_paddr \
- ? segment->p_paddr != section->lma \
- : segment->p_vaddr != section->vma) \
+ ? segment->p_paddr != section->lma * (opb) \
+ : segment->p_vaddr != section->vma * (opb)) \
|| (strcmp (bfd_section_name (section), ".dynamic") == 0)) \
&& (segment->p_type != PT_LOAD || !section->segment_mark))
/* If the output section of a section in the input segment is NULL,
it is removed from the corresponding output segment. */
-#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
- (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed) \
+#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed, opb) \
+ (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb) \
&& section->output_section != NULL)
/* Returns TRUE iff seg1 starts after the end of seg2. */
@@ -6936,7 +6951,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
/* Mininal change so that the normal section to segment
assignment code will work. */
- segment->p_vaddr = section->vma;
+ segment->p_vaddr = section->vma * opb;
break;
}
@@ -7022,7 +7037,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
/* Find the first section in the input segment, which may be
removed from the corresponding output segment. */
- if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed))
+ if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb))
{
if (first_section == NULL)
first_section = section;
@@ -7090,7 +7105,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
" at vaddr=%#" PRIx64 ", is this intentional?"),
ibfd, (uint64_t) segment->p_vaddr);
- map->p_vaddr_offset = segment->p_vaddr;
+ map->p_vaddr_offset = segment->p_vaddr / opb;
map->count = 0;
*pointer_to_map = map;
pointer_to_map = &map->next;
@@ -7145,7 +7160,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
section != NULL;
section = section->next)
{
- if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
+ if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed, opb))
{
output_section = section->output_section;
@@ -7172,10 +7187,11 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Match up the physical address of the segment with the
LMA address of the output section. */
- if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
+ if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr,
+ opb)
|| IS_COREFILE_NOTE (segment, section)
|| (bed->want_p_paddr_set_to_zero
- && IS_CONTAINED_BY_VMA (output_section, segment)))
+ && IS_CONTAINED_BY_VMA (output_section, segment, opb)))
{
if (matching_lma == NULL
|| output_section->lma < matching_lma->lma)
@@ -7219,7 +7235,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Account for padding before the first section in the
segment. */
- map->p_vaddr_offset = map->p_paddr + hdr_size - matching_lma->lma;
+ map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
+ - matching_lma->lma);
}
free (sections);
@@ -7290,7 +7307,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
BFD_ASSERT (output_section != NULL);
- if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
+ if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr,
+ opb)
|| IS_COREFILE_NOTE (segment, section))
{
if (map->count == 0)
@@ -7442,6 +7460,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
unsigned int num_segments;
bfd_boolean phdr_included = FALSE;
bfd_boolean p_paddr_valid;
+ unsigned int opb = bfd_octets_per_byte (ibfd, NULL);
iehdr = elf_elfheader (ibfd);
@@ -7567,7 +7586,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
seg_off = this_hdr->sh_offset - segment->p_offset;
else
seg_off = this_hdr->sh_addr - segment->p_vaddr;
- if (section->lma - segment->p_paddr != seg_off)
+ if (section->lma * opb - segment->p_paddr != seg_off)
map->p_paddr_valid = FALSE;
}
if (isec == section_count)
@@ -7577,7 +7596,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
}
if (section_count == 0)
- map->p_vaddr_offset = segment->p_vaddr;
+ map->p_vaddr_offset = segment->p_vaddr / opb;
else if (map->p_paddr_valid)
{
/* Account for padding before the first section in the segment. */
@@ -7587,7 +7606,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
if (map->includes_phdrs)
hdr_size += iehdr->e_phnum * iehdr->e_phentsize;
- map->p_vaddr_offset = (map->p_paddr + hdr_size
+ map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
- (lowest_section ? lowest_section->lma : 0));
}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c04712a10f6..369f3cb3e7b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4218,10 +4218,14 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
if (phdr->p_type == PT_GNU_RELRO)
{
for (s = abfd->sections; s != NULL; s = s->next)
- if ((s->flags & SEC_ALLOC) != 0
- && s->vma >= phdr->p_vaddr
- && s->vma + s->size <= phdr->p_vaddr + phdr->p_memsz)
- s->flags |= SEC_READONLY;
+ {
+ unsigned int opb = bfd_octets_per_byte (abfd, s);
+
+ if ((s->flags & SEC_ALLOC) != 0
+ && s->vma * opb >= phdr->p_vaddr
+ && s->vma * opb + s->size <= phdr->p_vaddr + phdr->p_memsz)
+ s->flags |= SEC_READONLY;
+ }
break;
}
diff --git a/include/elf/internal.h b/include/elf/internal.h
index 844675c30f3..d626adece5b 100644
--- a/include/elf/internal.h
+++ b/include/elf/internal.h
@@ -84,14 +84,14 @@ typedef struct elf_internal_ehdr {
/* Program header */
struct elf_internal_phdr {
- unsigned long p_type; /* Identifies program segment type */
- unsigned long p_flags; /* Segment flags */
- bfd_vma p_offset; /* Segment file offset */
- bfd_vma p_vaddr; /* Segment virtual address */
- bfd_vma p_paddr; /* Segment physical address */
- bfd_vma p_filesz; /* Segment size in file */
- bfd_vma p_memsz; /* Segment size in memory */
- bfd_vma p_align; /* Segment alignment, file & memory */
+ unsigned long p_type; /* Identifies program segment type. */
+ unsigned long p_flags; /* Segment flags. */
+ bfd_vma p_offset; /* Segment file offset in octets. */
+ bfd_vma p_vaddr; /* Segment virtual address in octets. */
+ bfd_vma p_paddr; /* Segment physical address in octets. */
+ bfd_vma p_filesz; /* Segment size in file in octets. */
+ bfd_vma p_memsz; /* Segment size in memory in octets. */
+ bfd_vma p_align; /* Segment alignment, file & memory. */
};
typedef struct elf_internal_phdr Elf_Internal_Phdr;
@@ -102,9 +102,10 @@ typedef struct elf_internal_shdr {
unsigned int sh_name; /* Section name, index in string tbl */
unsigned int sh_type; /* Type of section */
bfd_vma sh_flags; /* Miscellaneous section attributes */
- bfd_vma sh_addr; /* Section virtual addr at execution */
- file_ptr sh_offset; /* Section file offset */
- bfd_size_type sh_size; /* Size of section in bytes */
+ bfd_vma sh_addr; /* Section virtual addr at execution in
+ octets. */
+ file_ptr sh_offset; /* Section file offset in octets. */
+ bfd_size_type sh_size; /* Size of section in octets. */
unsigned int sh_link; /* Index of another section */
unsigned int sh_info; /* Additional section information */
bfd_vma sh_addralign; /* Section alignment */
@@ -267,7 +268,7 @@ struct elf_segment_map
unsigned long p_flags;
/* Program segment physical address. */
bfd_vma p_paddr;
- /* Program segment virtual address offset from section vma. */
+ /* Program segment virtual address offset from section vma in bytes. */
bfd_vma p_vaddr_offset;
/* Program segment alignment. */
bfd_vma p_align;
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 6d1457b929a..3ffabb8c1da 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -700,7 +700,8 @@ fold_name (etree_type *tree)
/* Don't find the real header size if only marking sections;
The bfd function may cache incorrect data. */
if (expld.phase != lang_mark_phase_enum)
- hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info);
+ hdr_size = (bfd_sizeof_headers (link_info.output_bfd, &link_info)
+ / bfd_octets_per_byte (link_info.output_bfd, NULL));
new_number (hdr_size);
}
break;
--
2.16.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] Fix several mix up between octets and bytes in ELF program headers
2020-03-02 14:18 ` Nick Clifton
@ 2020-03-02 20:17 ` Christian Eggers
2020-03-12 18:24 ` Christian Eggers
0 siblings, 1 reply; 8+ messages in thread
From: Christian Eggers @ 2020-03-02 20:17 UTC (permalink / raw)
To: binutils, Nick Clifton; +Cc: amodra, Christian Eggers
Hi Nick,
On Monday, March 2nd 2020, Nick Clifton wrote:
> Approved - please apply - but please fixup the comments first.
Comments changed, thanks.
Christian
---
This is a follow-up patch for my patch from december 09 with the same
subject. It 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 incorperated.
Patch changelog:
v2:
- GNU coding style for comments.
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.
Signed-off-by: Christian Eggers <ceggers@gmx.de>
---
bfd/bfd.c | 5 +++--
bfd/elf-bfd.h | 2 +-
bfd/elf.c | 54 +++++++++++++++++++++++++-------------------------
bfd/elfcode.h | 28 ++++++++++++++------------
bfd/elflink.c | 31 +++++++++++++++++------------
bfd/merge.c | 22 ++++++++++++--------
include/bfdlink.h | 4 ++--
include/elf/internal.h | 7 ++++---
8 files changed, 84 insertions(+), 69 deletions(-)
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 1c1238c036a..100359ccfe6 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -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 38a9aa06019..54c27a1b76c 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;
diff --git a/bfd/elf.c b/bfd/elf.c
index a329e239828..bc75b96adcb 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4665,8 +4665,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. */
@@ -4694,8 +4694,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));
@@ -4779,7 +4779,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;
@@ -4819,7 +4819,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;
@@ -5007,7 +5007,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++;
@@ -5305,15 +5305,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)
@@ -5584,7 +5586,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)
@@ -5621,7 +5623,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
@@ -5988,7 +5990,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. */
@@ -6065,6 +6067,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);
@@ -6131,7 +6134,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)
@@ -6147,7 +6150,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
{
@@ -6172,7 +6175,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;
@@ -6192,13 +6195,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
@@ -7181,8 +7181,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
@@ -7250,7 +7250,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. */
@@ -7278,7 +7278,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);
}
}
@@ -7322,8 +7322,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
@@ -7389,7 +7389,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 600abfe836e..ec5156a433d 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -1648,10 +1648,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 */
@@ -1664,9 +1665,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);
@@ -1764,17 +1766,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];
}
}
@@ -1830,9 +1832,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
@@ -1845,7 +1847,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 369f3cb3e7b..5852844498a 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 5a4e709ef38..0c6f7a10d3d 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. */
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 8d85530e390..40a6d4d40a6 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -801,9 +801,9 @@ struct bfd_link_order
struct bfd_link_order *next;
/* Type of link_order. */
enum bfd_link_order_type type;
- /* Offset within output section. */
+ /* Offset within output section in bytes. */
bfd_vma offset;
- /* Size within output section. */
+ /* Size within output section in octets. */
bfd_size_type size;
/* Type specific information. */
union
diff --git a/include/elf/internal.h b/include/elf/internal.h
index d626adece5b..9692028eed3 100644
--- a/include/elf/internal.h
+++ b/include/elf/internal.h
@@ -91,7 +91,8 @@ struct elf_internal_phdr {
bfd_vma p_paddr; /* Segment physical address in octets. */
bfd_vma p_filesz; /* Segment size in file in octets. */
bfd_vma p_memsz; /* Segment size in memory in octets. */
- bfd_vma p_align; /* Segment alignment, file & memory. */
+ bfd_vma p_align; /* Segment alignment in bytes, file
+ & memory */
};
typedef struct elf_internal_phdr Elf_Internal_Phdr;
@@ -266,13 +267,13 @@ struct elf_segment_map
unsigned long p_type;
/* Program segment flags. */
unsigned long p_flags;
- /* Program segment physical address. */
+ /* Program segment physical address in octets. */
bfd_vma p_paddr;
/* Program segment virtual address offset from section vma in bytes. */
bfd_vma p_vaddr_offset;
/* Program segment alignment. */
bfd_vma p_align;
- /* Segment size in file and memory */
+ /* Segment size in file and memory in octets. */
bfd_vma p_size;
/* Whether the p_flags field is valid; if not, the flags are based
on the section flags. */
--
2.16.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] Fix several mix up between octets and bytes in ELF program headers
2020-03-02 20:17 ` [PATCH v2 " Christian Eggers
@ 2020-03-12 18:24 ` Christian Eggers
2020-03-13 5:31 ` Alan Modra
0 siblings, 1 reply; 8+ messages in thread
From: Christian Eggers @ 2020-03-12 18:24 UTC (permalink / raw)
To: binutils
Ping? Who can apply these two patches? I have not write access for GIT.
Link to the first patch of this series:
https://sourceware.org/pipermail/binutils/2020-March/109971.html
Regards
Christian
Am Montag, 2. März 2020, 21:15:24 CET schrieb Christian Eggers:
> Hi Nick,
>
> On Monday, March 2nd 2020, Nick Clifton wrote:
> > Approved - please apply - but please fixup the comments first.
>
> Comments changed, thanks.
>
> Christian
>
> ---
> This is a follow-up patch for my patch from december 09 with the same
> subject. It 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 incorperated.
>
> Patch changelog:
> v2:
> - GNU coding style for comments.
>
> 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.
>
> Signed-off-by: Christian Eggers <ceggers@gmx.de>
> ---
> bfd/bfd.c | 5 +++--
> bfd/elf-bfd.h | 2 +-
> bfd/elf.c | 54
> +++++++++++++++++++++++++------------------------- bfd/elfcode.h |
> 28 ++++++++++++++------------
> bfd/elflink.c | 31 +++++++++++++++++------------
> bfd/merge.c | 22 ++++++++++++--------
> include/bfdlink.h | 4 ++--
> include/elf/internal.h | 7 ++++---
> 8 files changed, 84 insertions(+), 69 deletions(-)
>
> diff --git a/bfd/bfd.c b/bfd/bfd.c
> index 1c1238c036a..100359ccfe6 100644
> --- a/bfd/bfd.c
> +++ b/bfd/bfd.c
> @@ -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 38a9aa06019..54c27a1b76c 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;
> diff --git a/bfd/elf.c b/bfd/elf.c
> index a329e239828..bc75b96adcb 100644
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -4665,8 +4665,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. */
> @@ -4694,8 +4694,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));
> @@ -4779,7 +4779,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;
> @@ -4819,7 +4819,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;
> @@ -5007,7 +5007,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++;
> @@ -5305,15 +5305,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)
> @@ -5584,7 +5586,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)
> @@ -5621,7 +5623,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
> @@ -5988,7 +5990,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. */
> @@ -6065,6 +6067,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);
> @@ -6131,7 +6134,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)
> @@ -6147,7 +6150,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
> {
> @@ -6172,7 +6175,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;
> @@ -6192,13 +6195,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
> @@ -7181,8 +7181,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
> @@ -7250,7 +7250,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. */
> @@ -7278,7 +7278,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);
> }
> }
>
> @@ -7322,8 +7322,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
> @@ -7389,7 +7389,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 600abfe836e..ec5156a433d 100644
> --- a/bfd/elfcode.h
> +++ b/bfd/elfcode.h
> @@ -1648,10 +1648,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 */
> @@ -1664,9 +1665,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);
> @@ -1764,17 +1766,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];
> }
> }
> @@ -1830,9 +1832,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
> @@ -1845,7 +1847,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 369f3cb3e7b..5852844498a 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 5a4e709ef38..0c6f7a10d3d 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. */
> diff --git a/include/bfdlink.h b/include/bfdlink.h
> index 8d85530e390..40a6d4d40a6 100644
> --- a/include/bfdlink.h
> +++ b/include/bfdlink.h
> @@ -801,9 +801,9 @@ struct bfd_link_order
> struct bfd_link_order *next;
> /* Type of link_order. */
> enum bfd_link_order_type type;
> - /* Offset within output section. */
> + /* Offset within output section in bytes. */
> bfd_vma offset;
> - /* Size within output section. */
> + /* Size within output section in octets. */
> bfd_size_type size;
> /* Type specific information. */
> union
> diff --git a/include/elf/internal.h b/include/elf/internal.h
> index d626adece5b..9692028eed3 100644
> --- a/include/elf/internal.h
> +++ b/include/elf/internal.h
> @@ -91,7 +91,8 @@ struct elf_internal_phdr {
> bfd_vma p_paddr; /* Segment physical address in octets. */
> bfd_vma p_filesz; /* Segment size in file in octets. */
> bfd_vma p_memsz; /* Segment size in memory in octets. */
> - bfd_vma p_align; /* Segment alignment, file & memory. */
> + bfd_vma p_align; /* Segment alignment in bytes, file
> + & memory */
> };
>
> typedef struct elf_internal_phdr Elf_Internal_Phdr;
> @@ -266,13 +267,13 @@ struct elf_segment_map
> unsigned long p_type;
> /* Program segment flags. */
> unsigned long p_flags;
> - /* Program segment physical address. */
> + /* Program segment physical address in octets. */
> bfd_vma p_paddr;
> /* Program segment virtual address offset from section vma in bytes. */
> bfd_vma p_vaddr_offset;
> /* Program segment alignment. */
> bfd_vma p_align;
> - /* Segment size in file and memory */
> + /* Segment size in file and memory in octets. */
> bfd_vma p_size;
> /* Whether the p_flags field is valid; if not, the flags are based
> on the section flags. */
> --
> 2.16.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] Fix several mix up between octets and bytes in ELF program headers
2020-03-12 18:24 ` Christian Eggers
@ 2020-03-13 5:31 ` Alan Modra
0 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2020-03-13 5:31 UTC (permalink / raw)
To: Christian Eggers; +Cc: binutils, Nick Clifton
On Thu, Mar 12, 2020 at 07:24:45PM +0100, Christian Eggers wrote:
> Ping? Who can apply these two patches? I have not write access for GIT.
Applied.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-03-13 5:31 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20200215193050.22717-1-ceggers@gmx.de>
2020-02-15 19:31 ` [PATCH 2/2] Fix several mix up between octets and bytes in ELF program headers Christian Eggers
2020-03-02 14:18 ` Nick Clifton
2020-03-02 20:17 ` [PATCH v2 " Christian Eggers
2020-03-12 18:24 ` Christian Eggers
2020-03-13 5:31 ` Alan Modra
2020-02-15 19:31 ` [PATCH 1/2] " Christian Eggers
2020-03-02 14:17 ` Nick Clifton
2020-03-02 20:11 ` [PATCH v4] " Christian Eggers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).