[PATCH v2 2/2] Fix several mix up between octets and bytes in ELF program headers

Christian Eggers ceggers@gmx.de
Thu Mar 12 18:24:45 GMT 2020


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







More information about the Binutils mailing list