Fix several mix up between octets and bytes in ELF program headers
authorChristian Eggers <ceggers@gmx.de>
Mon, 2 Mar 2020 20:11:00 +0000 (20:11 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 13 Mar 2020 05:07:11 +0000 (15:37 +1030)
When converting between addresses in ELF headers [octets] and bfd
LMA/VMA [bytes], the number of octets per byte needs to be
incorporated.

In ld, the SIZEOF_HEADERS linker script statement must be resolved to
bytes instead of 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.
* 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.

bfd/ChangeLog
bfd/elf.c
bfd/elflink.c
include/ChangeLog
include/elf/internal.h
ld/ChangeLog
ld/ldexp.c

index 3b252e1196830c44cfbf8b0eda7c8f64eb3d5bd7..32549b352086530763dce23ac9b8f834a237eaab 100644 (file)
@@ -1,3 +1,26 @@
+2020-03-13  Christian Eggers  <ceggers@gmx.de>
+
+       * 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.
+
 2020-03-11  Alan Modra  <amodra@gmail.com>
 
        * som.c (setup_sections): Sanity check subspace.name.
index e6db2ff64d8a975b9bab0767d5e010a0f04e7a1e..049882b87e5a17df240593d5e6dade0d85d8acda 100644 (file)
--- 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
@@ -2949,6 +2953,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)
@@ -2965,8 +2970,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;
@@ -3001,8 +3006,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;
@@ -3278,7 +3283,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;
 
@@ -4669,6 +4674,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.  */
 
@@ -4708,6 +4714,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;
@@ -4932,7 +4940,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;
            }
 
@@ -4958,7 +4966,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;
        }
@@ -5412,11 +5420,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))
@@ -5524,7 +5533,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
@@ -5538,16 +5547,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)
@@ -5628,7 +5637,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)
@@ -5719,7 +5729,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;
@@ -5753,7 +5763,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)
@@ -5784,10 +5794,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
@@ -5796,9 +5806,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;
 
@@ -6188,8 +6199,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;
@@ -6788,6 +6802,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);
@@ -6810,17 +6825,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.  */
@@ -6866,10 +6881,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                                  \
@@ -6881,15 +6896,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.  */
@@ -6943,7 +6958,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;
            }
 
@@ -7029,7 +7044,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;
@@ -7097,7 +7112,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;
@@ -7152,7 +7167,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;
 
@@ -7179,10 +7194,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)
@@ -7226,7 +7242,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);
@@ -7297,7 +7314,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)
@@ -7449,6 +7467,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);
 
@@ -7574,7 +7593,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)
@@ -7584,7 +7603,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.  */
@@ -7594,7 +7613,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));
        }
 
index c04712a10f6a6b188882380709bc04f40a5a7fd2..369f3cb3e7bef6baa0e5e23d4bb2bfe2a7b20db0 100644 (file)
@@ -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;
          }
 
index ad0ad9add651bbdb3cdcebc035bfdddc588a8800..aa2c5516723008766dfad0110627b13402fd2e9b 100644 (file)
@@ -1,3 +1,9 @@
+2020-03-13  Christian Eggers  <ceggers@gmx.de>
+
+       * elf/internal.h (struct elf_internal_phdr): Add unit (octets)
+       to several member field comments.
+       (Elf_Internal_Shdr): likewise.
+
 2020-03-10  Alan Modra  <amodra@gmail.com>
 
        * som/aout.h (SOM_AUX_ID_MANDATORY, SOM_SPACE_IS_LOADABLE),
index 844675c30f3bfb59db6d8ba43ffc6fd9d73dc639..d626adece5bd98255875b687019b3ab9d155129a 100644 (file)
@@ -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;
index 5b8db22775dedf42b7351c1eea198d6255963d03..8ac66fc2e58bdca2aea702b7022d97d9a4de74e3 100644 (file)
@@ -1,3 +1,7 @@
+2020-03-13  Christian Eggers  <ceggers@gmx.de>
+
+       * ldexp.c (fold_name): Return SIZEOF_HEADERS in bytes.
+
 2020-03-11  Alan Modra  <amodra@gmail.com>
 
        * ldelf.c (elf_orphan_compatible): Return false when two sections
index 6d1457b929abd027d413b882cf058e874178ffe2..3ffabb8c1da6e2f2677b1dc63e25e7ee92221c03 100644 (file)
@@ -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;