[PATCH v2] Fix several mix up between octets and bytes in ELF program headers
Christian Eggers
ceggers@gmx.de
Tue Dec 17 20:45:00 GMT 2019
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
More information about the Binutils
mailing list