This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Hi Alan,

ping.... Seems you currently have some fun with ubsan.

regards
Christian


Am Montag, 9. Dezember 2019, 09:46:45 CET schrieb Christian Eggers:
> Alan Moda wrote:
> > I'm wondering if you would be better off leaving all the values as
> > octets when written to file.  There are things in the ELF spec, like
> > p_offset mod pagesize == p_vaddr mod pagesize, that assume p_offset
> > and p_vaddr have the same units.
>
> in v2 I've "kept" p_paddr, p_vaddr and sh_addr as octets. Compared to
> v1, the result is also ok for me. I had to disable one unit test for SDMA as
> 'objcopy --set-section-address .text=0x80000000' will overflow when
> converting 0x80000000 (LMA, bytes) to sh_addr (octets).
>
> ---
>
> 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.
>
>
> 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.
> 	* elf32-rx.c (OCTETS_PER_BYTE): Define.
> 	(rx_elf_object_p): Use OCTETS_PER_BYTE for calculating
> 	section LMA from program header addresses.
> 	* elf64-ia64-vms.c (OCTETS_PER_BYTE): Define.
> 	(elf64_vms_link_add_object_symbols): Use OCTETS_PER_BYTE for
> 	calculating section LMA from program header addresses.
> 	* 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/elf32-rx.c         |
>  8 ++-
>  bfd/elf64-ia64-vms.c   |   7 ++-
>  bfd/elflink.c          |  14 ++++--
>  include/elf/internal.h |  19 +++----
>  ld/ldexp.c             |   3 +-
>  6 files changed, 108 insertions(+), 74 deletions(-)
>
> diff --git a/bfd/elf.c b/bfd/elf.c
> index 1aa2603ee8c..d98cf9b8a51 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;
> @@ -5755,7 +5765,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
>  	    p->p_offset = off;
>  	  else
>  	    {
> -	      file_ptr adjust;
> +	      file_ptr adjust;  /* octets */
>
>  	      adjust = off - (p->p_offset + p->p_filesz);
>  	      if (!no_contents)
> @@ -5786,10 +5796,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
> @@ -5798,9 +5808,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;
>
> @@ -6186,8 +6197,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;
> @@ -6786,6 +6800,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);
> @@ -6808,17 +6823,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 * (opb) + SECTION_SIZE (section, segment) >=
> section->lma) \ +   && (section->lma * (opb) + SECTION_SIZE (section,
> segment)		\
>         <= SEGMENT_END (segment, base)))
>
>    /* Handle PT_NOTE segment.  */
> @@ -6864,10 +6879,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					\
> @@ -6879,15 +6894,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.  */
> @@ -6941,7 +6956,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;
>  	    }
>
> @@ -7027,7 +7042,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;
> @@ -7095,7 +7110,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;
> @@ -7149,7 +7164,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;
>
> @@ -7176,10 +7191,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)
>
> @@ -7223,7 +7239,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);
> @@ -7294,7 +7311,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)
> @@ -7445,6 +7463,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);
>
> @@ -7570,7 +7589,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)
> @@ -7580,7 +7599,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.  */
> @@ -7590,7 +7609,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/elf32-rx.c b/bfd/elf32-rx.c
> index a1a5ce11be1..1524a05cc50 100644
> --- a/bfd/elf32-rx.c
> +++ b/bfd/elf32-rx.c
> @@ -26,6 +26,9 @@
>  #include "libiberty.h"
>  #include "elf32-rx.h"
>
> +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
> +#define OCTETS_PER_BYTE(ABFD, SEC) 1
> +
>  #define RX_OPCODE_BIG_ENDIAN 0
>
>  /* This is a meta-target that's used only with objcopy, to avoid the
> @@ -3306,7 +3309,10 @@ rx_elf_object_p (bfd * abfd)
>  	      && phdr[i].p_vaddr <= bsec->vma
>  	      && bsec->vma <= phdr[i].p_vaddr + (phdr[i].p_filesz - 1))
>  	    {
> -	      bsec->lma = phdr[i].p_paddr + (bsec->vma - phdr[i].p_vaddr);
> +	      bsec->lma = (phdr[i].p_paddr / OCTETS_PER_BYTE (abfd, bsec)
> +			   + (bsec->vma
> +			      - (phdr[i].p_vaddr
> +				 / OCTETS_PER_BYTE (abfd, bsec))));
>  	    }
>  	  bsec = bsec->next;
>  	}
> diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c
> index d0cb7e08e10..6a3bd793a3d 100644
> --- a/bfd/elf64-ia64-vms.c
> +++ b/bfd/elf64-ia64-vms.c
> @@ -30,6 +30,9 @@
>  #include "vms.h"
>  #include "bfdver.h"
>
> +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
> +#define OCTETS_PER_BYTE(ABFD, SEC) 1
> +
>  /* THE RULES for all the stuff the linker creates --
>
>    GOT		Entries created in response to LTOFF or LTOFF_FPTR
> @@ -4833,8 +4836,8 @@ elf64_vms_link_add_object_symbols (bfd *abfd, struct
> bfd_link_info *info) s = bfd_make_section (abfd, ".dynamic");
>  		if (s == NULL)
>  		  goto error_return;
> -		s->vma = phdr->p_vaddr;
> -		s->lma = phdr->p_paddr;
> +		s->vma = phdr->p_vaddr / OCTETS_PER_BYTE (abfd, s);
> +		s->lma = phdr->p_paddr / OCTETS_PER_BYTE (abfd, s);
>  		s->size = phdr->p_filesz;
>  		s->filepos = phdr->p_offset;
>  		s->flags |= SEC_HAS_CONTENTS;
> diff --git a/bfd/elflink.c b/bfd/elflink.c
> index 7078a2fb6f4..e09ab908b60 100644
> --- a/bfd/elflink.c
> +++ b/bfd/elflink.c
> @@ -4227,11 +4227,15 @@ 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;
> -	    break;
> +	      {
> +		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;
> +	      }
>  	  }
>
>        /* We do not want to include any of the sections in a dynamic
> diff --git a/include/elf/internal.h b/include/elf/internal.h
> index 794c16812ee..4ede98aa54d 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 b287022f5a1..9c599c2d470 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





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]