Make ld -N more reasonable for ELF:
authorIan Lance Taylor <ian@airs.com>
Wed, 31 Jul 1996 19:58:05 +0000 (19:58 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 31 Jul 1996 19:58:05 +0000 (19:58 +0000)
* elf.c (map_sections_to_segments): If D_PAGED is not set, set
phdr_in_section to false, and always use a single load segment.
(elf_sort_sections): Sort sections by LMA after VMA.
(assign_file_positions_for_segments): If D_PAGED is not set, don't
align to maxpagesize.
(assign_file_positions_except_relocs): Likewise.
* elfcode.h (elf_object_p): If a section is loaded but not page
aligned, clear D_PAGED.

bfd/ChangeLog
bfd/elf.c

index d9fffa57f17bd7b7dbfeb8ed1064264b29aeb834..aeb9f54f2ce04dd788a7756542c658e259c64108 100644 (file)
@@ -1,3 +1,15 @@
+Wed Jul 31 15:50:55 1996  Ian Lance Taylor  <ian@cygnus.com>
+
+       Make ld -N more reasonable for ELF:
+       * elf.c (map_sections_to_segments): If D_PAGED is not set, set
+       phdr_in_section to false, and always use a single load segment.
+       (elf_sort_sections): Sort sections by LMA after VMA.
+       (assign_file_positions_for_segments): If D_PAGED is not set, don't
+       align to maxpagesize.
+       (assign_file_positions_except_relocs): Likewise.
+       * elfcode.h (elf_object_p): If a section is loaded but not page
+       aligned, clear D_PAGED.
+
 Wed Jul 31 15:00:12 1996  James G. Smith  <jsmith@cygnus.co.uk>
 
        * reloc.c: (BFD_RELOC_ARM_OFFSETIMM8, BFD_RELOC_ARM_HWLITERAL):
index 89818000606cd0e8da75c918f3259b965f61851b..6a27ba56dd743bf63c322c8542ae0c48514e884d 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1746,7 +1746,8 @@ map_sections_to_segments (abfd)
       phdr_size = elf_tdata (abfd)->program_header_size;
       if (phdr_size == 0)
        phdr_size = get_elf_backend_data (abfd)->s->sizeof_phdr;
-      if (sections[0]->lma % maxpagesize < phdr_size % maxpagesize)
+      if ((abfd->flags & D_PAGED) == 0
+         || sections[0]->lma % maxpagesize < phdr_size % maxpagesize)
        phdr_in_section = false;
     }
 
@@ -1765,6 +1766,7 @@ map_sections_to_segments (abfd)
          program segment; anybody can use PHDRS in their linker script
          to control what happens anyhow).  */
       if (last_hdr == NULL
+         || (abfd->flags & D_PAGED) == 0
          || ((BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize)
               >= hdr->lma)
              && ((last_hdr->flags & SEC_LOAD) != 0
@@ -1775,7 +1777,6 @@ map_sections_to_segments (abfd)
                  || (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size,
                                 maxpagesize)
                      > hdr->lma))))
-                     
        {
          if ((hdr->flags & SEC_READONLY) == 0)
            writable = true;
@@ -1858,6 +1859,13 @@ elf_sort_sections (arg1, arg2)
   else if (sec1->vma > sec2->vma)
     return 1;
 
+  /* Sort by LMA.  Normally the LMA and the VMA will be the same, and
+     this will do nothing.  */
+  if (sec1->lma < sec2->lma)
+    return -1;
+  else if (sec1->lma > sec2->lma)
+    return 1;
+
   /* Put !SEC_LOAD sections after SEC_LOAD ones.  */
 
 #define TOEND(x) (((x)->flags & SEC_LOAD) == 0)
@@ -1976,7 +1984,13 @@ assign_file_positions_for_segments (abfd)
       if (p->p_type == PT_LOAD
          && m->count > 0
          && (m->sections[0]->flags & SEC_LOAD) != 0)
-       off += (m->sections[0]->vma - off) % bed->maxpagesize;
+       {
+         if ((abfd->flags & D_PAGED) != 0)
+           off += (m->sections[0]->vma - off) % bed->maxpagesize;
+         else
+           off += ((m->sections[0]->vma - off)
+                   % (1 << bfd_get_section_alignment (abfd, m->sections[0])));
+       }
 
       if (m->count == 0)
        p->p_vaddr = 0;
@@ -1990,7 +2004,8 @@ assign_file_positions_for_segments (abfd)
       else
        p->p_paddr = m->sections[0]->lma;
 
-      if (p->p_type == PT_LOAD)
+      if (p->p_type == PT_LOAD
+         && (abfd->flags & D_PAGED) != 0)
        p->p_align = bed->maxpagesize;
       else if (m->count == 0)
        p->p_align = bed->s->file_align;
@@ -2077,6 +2092,7 @@ assign_file_positions_for_segments (abfd)
 
          sec = *secpp;
          flags = sec->flags;
+         align = 1 << bfd_get_section_alignment (abfd, sec);
 
          if (p->p_type == PT_LOAD)
            {
@@ -2086,7 +2102,10 @@ assign_file_positions_for_segments (abfd)
                  the page size.  */
              if ((flags & SEC_ALLOC) != 0)
                {
-                 adjust = (sec->vma - voff) % bed->maxpagesize;
+                 if ((abfd->flags & D_PAGED) != 0)
+                   adjust = (sec->vma - voff) % bed->maxpagesize;
+                 else
+                   adjust = (sec->vma - voff) % align;
                  if (adjust != 0)
                    {
                      if (i == 0)
@@ -2112,7 +2131,6 @@ assign_file_positions_for_segments (abfd)
          if ((flags & SEC_LOAD) != 0)
            p->p_filesz += sec->_raw_size;
 
-         align = 1 << bfd_get_section_alignment (abfd, sec);
          if (align > p->p_align)
            p->p_align = align;
 
@@ -2324,7 +2342,10 @@ assign_file_positions_except_relocs (abfd)
                (hdr->bfd_section == NULL
                 ? "*unknown*"
                 : hdr->bfd_section->name)));
-             off += (hdr->sh_addr - off) % bed->maxpagesize;
+             if ((abfd->flags & D_PAGED) != 0)
+               off += (hdr->sh_addr - off) % bed->maxpagesize;
+             else
+               off += (hdr->sh_addr - off) % hdr->sh_addralign;
              off = _bfd_elf_assign_file_position_for_section (hdr, off,
                                                               false);
            }
This page took 0.03698 seconds and 4 git commands to generate.