2013-08-21 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Wed, 21 Aug 2013 08:15:23 +0000 (08:15 +0000)
committerTristan Gingold <gingold@adacore.com>
Wed, 21 Aug 2013 08:15:23 +0000 (08:15 +0000)
* coff-rs6000.c (_bfd_xcoff_sizeof_headers): Also count
.ovrflo sections.
* coffcode.h (coff_compute_section_file_positions): Force
match between file offset and vma offset.

bfd/ChangeLog
bfd/coff-rs6000.c
bfd/coffcode.h

index 3c36e07..824c171 100644 (file)
@@ -1,3 +1,10 @@
+2013-08-21  Tristan Gingold  <gingold@adacore.com>
+
+       * coff-rs6000.c (_bfd_xcoff_sizeof_headers): Also count
+       .ovrflo sections.
+       * coffcode.h (coff_compute_section_file_positions): Force
+       match between file offset and vma offset.
+
 2013-08-21  Alan Modra  <amodra@gmail.com>
 
        * elflink.c (_bfd_elf_merge_symbol): Set *poldbfd, *poldweak,
index 309ea77..0386e9a 100644 (file)
@@ -2570,6 +2570,60 @@ _bfd_xcoff_sizeof_headers (bfd *abfd,
   else
     size += SMALL_AOUTSZ;
   size += abfd->section_count * SCNHSZ;
+
+  if (info->strip != strip_all)
+    {
+      /* There can be additional sections just for dealing with overflow in
+        reloc and lineno counts. But the numbers of relocs and lineno aren't
+        known when bfd_sizeof_headers is called, so we compute them by
+        summing the numbers from input sections.  */
+      struct nbr_reloc_lineno
+      {
+       unsigned int reloc_count;
+       unsigned int lineno_count;
+      };
+      struct nbr_reloc_lineno *n_rl;
+      bfd *sub;
+      int max_index;
+      asection *s;
+
+      /* Although the number of sections is known, the maximum value of
+        section->index isn't (because some sections may have been removed).
+        Don't try to renumber sections, just compute the upper bound.  */
+      max_index = 0;
+      for (s = abfd->sections; s != NULL; s = s->next)
+       if (s->index > max_index)
+         max_index = s->index;
+
+      /* Allocate the per section counters. It could be possible to use a
+        preallocated array as the number of sections is limited on XCOFF,
+        but this creates a maintainance issue.  */
+      n_rl = bfd_zmalloc ((max_index + 1) * sizeof (*n_rl));
+      if (n_rl == NULL)
+       return -1;
+
+      /* Sum.  */
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+       for (s = sub->sections; s != NULL; s = s->next)
+         {
+           struct nbr_reloc_lineno *e = &n_rl[s->output_section->index];
+           e->reloc_count += s->reloc_count;
+           e->lineno_count += s->lineno_count;
+         }
+
+      /* Add the size of a section for each section with an overflow.  */
+      for (s = abfd->sections; s != NULL; s = s->next)
+       {
+         struct nbr_reloc_lineno *e = &n_rl[s->index];
+
+         if (e->reloc_count >= 0xffff
+             || (e->lineno_count >= 0xffff && info->strip != strip_debugger))
+           size += SCNHSZ;
+       }
+
+      free (n_rl);
+    }
+
   return size;
 }
 \f
index a198e1c..542b5b7 100644 (file)
@@ -3363,36 +3363,38 @@ coff_compute_section_file_positions (bfd * abfd)
             padding the previous section up if necessary.  */
          old_sofar = sofar;
 
+         sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+
 #ifdef RS6000COFF_C
-         /* AIX loader checks the text section alignment of (vma - filepos)
-            So even though the filepos may be aligned wrt the o_algntext, for
-            AIX executables, this check fails. This shows up when a native
-            AIX executable is stripped with gnu strip because the default vma
-            of native is 0x10000150 but default for gnu is 0x10000140.  Gnu
-            stripped gnu excutable passes this check because the filepos is
-            0x0140.  This problem also show up with 64 bit shared objects. The
-            data section must also be aligned.  */
+         /* Make sure the file offset and the vma of .text/.data are at the
+            same page offset, so that the file can be mmap'ed without being
+            relocated.  Failing that, AIX is able to load and execute the
+            program, but it will be silently relocated (possible as
+            executables are PIE).  But the relocation is slightly costly and
+            complexify the use of addr2line or gdb.  So better to avoid it,
+            like does the native linker.  Usually gnu ld makes sure that
+            the vma of .text is the file offset so this issue shouldn't
+            appear unless you are stripping such an executable.
+
+            AIX loader checks the text section alignment of (vma - filepos),
+            and the native linker doesn't try to align the text sections.
+            For example:
+
+            0 .text         000054cc  10000128  10000128  00000128  2**5
+                             CONTENTS, ALLOC, LOAD, CODE
+         */
+
          if (!strcmp (current->name, _TEXT)
              || !strcmp (current->name, _DATA))
            {
-             bfd_vma pad;
-             bfd_vma align;
-
-             sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
-
-             align = 1 << current->alignment_power;
-             pad = abs (current->vma - sofar) % align;
-
-             if (pad)
-               {
-                 pad = align - pad;
-                 sofar += pad;
-               }
-           }
-         else
-#else
-           {
-             sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+             bfd_vma align = 4096;
+             bfd_vma sofar_off = sofar % align;
+             bfd_vma vma_off = current->vma % align;
+
+             if (vma_off > sofar_off)
+               sofar += vma_off - sofar_off;
+             else if (vma_off < sofar_off)
+               sofar += align + vma_off - sofar_off;
            }
 #endif
          if (previous != NULL)