Fix several mix up between octets and bytes in ELF program headers
authorChristian Eggers <ceggers@gmx.de>
Mon, 2 Mar 2020 20:17:00 +0000 (20:17 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 13 Mar 2020 05:18:01 +0000 (15:48 +1030)
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 incorporated.

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.

bfd/ChangeLog
bfd/bfd.c
bfd/elf-bfd.h
bfd/elf.c
bfd/elfcode.h
bfd/elflink.c
bfd/merge.c
include/ChangeLog
include/bfdlink.h
include/elf/internal.h

index 32549b352086530763dce23ac9b8f834a237eaab..f5ad233ffa1e0a6992e99764a5bae6e199cd9ffe 100644 (file)
@@ -1,3 +1,43 @@
+2020-03-13  Christian Eggers  <ceggers@gmx.de>
+
+       * 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.
+
 2020-03-13  Christian Eggers  <ceggers@gmx.de>
 
        * elf.c (_bfd_elf_make_section_from_shdr): Introduce new temp
index 1c1238c036a546ccabeceb2f6cebc74d94f83855..100359ccfe6961c8f77f767eac2bbd80035a73d3 100644 (file)
--- 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;
index 5d9e0fedcda076a270b89bbfe40ad5c80f960448..d4ac5152dfe9a13e50eac3aca82157db57f25ec0 100644 (file)
@@ -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;
index 049882b87e5a17df240593d5e6dade0d85d8acda..2d0001b46395ef3ad4a206628a1532e5b188cb29 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4672,8 +4672,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.  */
@@ -4701,8 +4701,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));
@@ -4786,7 +4786,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;
@@ -4826,7 +4826,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;
@@ -5014,7 +5014,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++;
@@ -5312,15 +5312,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)
@@ -5591,7 +5593,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)
@@ -5628,7 +5630,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
@@ -5995,7 +5997,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.  */
@@ -6072,6 +6074,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);
@@ -6138,7 +6141,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)
@@ -6154,7 +6157,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
            {
@@ -6179,7 +6182,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;
@@ -6199,13 +6202,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
@@ -7188,8 +7188,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
@@ -7257,7 +7257,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.  */
@@ -7285,7 +7285,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);
            }
        }
 
@@ -7329,8 +7329,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
@@ -7396,7 +7396,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;
index 18a6dac64e04a83d62cbe7feec518be693f7ad13..7745c537658fc41a962cf5d195ac15566adcfec4 100644 (file)
@@ -1664,10 +1664,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 */
@@ -1680,9 +1681,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);
@@ -1780,17 +1782,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];
                }
            }
@@ -1846,9 +1848,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
@@ -1861,7 +1863,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)
          {
index 369f3cb3e7bef6baa0e5e23d4bb2bfe2a7b20db0..5852844498aa985fe2916f9a9def9809866ef50b 100644 (file)
@@ -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)
index 5a4e709ef388b1ebdabb72ecd45c4f020d3619f7..0c6f7a10d3d8c67946e26be3880d1f2e1c75e531 100644 (file)
@@ -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.  */
index aa2c5516723008766dfad0110627b13402fd2e9b..2fefb460c9538ee09ae2c7541b5df648c45659c8 100644 (file)
@@ -1,3 +1,12 @@
+2020-03-13  Christian Eggers  <ceggers@gmx.de>
+
+       * 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
+
 2020-03-13  Christian Eggers  <ceggers@gmx.de>
 
        * elf/internal.h (struct elf_internal_phdr): Add unit (octets)
index 8d85530e390a704fb5e8a2aa1f9f14e2cb507af4..40a6d4d40a6c1ac7a6739f9320dffc2f7ee2c2df 100644 (file)
@@ -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
index d626adece5bd98255875b687019b3ab9d155129a..9692028eed3ea49b9c67ee8df533fbb2cb0e3f3e 100644 (file)
@@ -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.  */
This page took 0.036786 seconds and 4 git commands to generate.