public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [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).