1999-09-11 Donn Terry <donn@interix.com>
authorIan Lance Taylor <ian@airs.com>
Sun, 12 Sep 1999 00:30:27 +0000 (00:30 +0000)
committerIan Lance Taylor <ian@airs.com>
Sun, 12 Sep 1999 00:30:27 +0000 (00:30 +0000)
* peicode.h (coff_swap_scnhdr_in): If COFF_IMAGE_WITH_PE, the
get the overflow of the s_nlnno field from the s_nreloc field.
* peigen.c (_bfd_pei_swap_scnhdr_out): If doing a final link, swap
the s_nlnno overflow of the .text section into the s_nreloc
field.

bfd/ChangeLog
bfd/peicode.h
bfd/peigen.c

index 28d5780..ff1f942 100644 (file)
@@ -7,6 +7,12 @@
 
 1999-09-11  Donn Terry  <donn@interix.com>
 
+       * peicode.h (coff_swap_scnhdr_in): If COFF_IMAGE_WITH_PE, the
+       get the overflow of the s_nlnno field from the s_nreloc field.
+       * peigen.c (_bfd_pei_swap_scnhdr_out): If doing a final link, swap
+       the s_nlnno overflow of the .text section into the s_nreloc
+       field.
+
        * peigen.c (add_data_entry): Declare.
        (pei_swap_aouthdr_out): Get image size right.  Set linker version
        more intuitively.
index 605b1c0..0b6bde4 100644 (file)
@@ -215,8 +215,20 @@ coff_swap_scnhdr_in (abfd, ext, in)
     GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
   scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
 
-  scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
-  scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
+  /* MS handles overflow of line numbers by carrying into the reloc
+     field (it appears).  Since it's supposed to be zero for PE
+     *IMAGE* format, that's safe.  This is still a bit iffy.  */
+#ifdef COFF_IMAGE_WITH_PE
+  scnhdr_int->s_nlnno =
+    (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nlnno)
+     + (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nreloc) << 16));
+  scnhdr_int->s_nreloc = 0;
+#else
+  scnhdr_int->s_nreloc = bfd_h_get_16 (abfd,
+                                      (bfd_byte *) scnhdr_ext->s_nreloc);
+  scnhdr_int->s_nlnno = bfd_h_get_16 (abfd,
+                                     (bfd_byte *) scnhdr_ext->s_nlnno);
+#endif
 
   if (scnhdr_int->s_vaddr != 0) 
     {
index 24945b4..a79b857 100644 (file)
@@ -958,27 +958,50 @@ _bfd_pei_swap_scnhdr_out (abfd, in, out)
     bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
   }
 
-  if (scnhdr_int->s_nlnno <= 0xffff)
-    bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
-  else
+  if (coff_data (abfd)->link_info
+      && ! coff_data (abfd)->link_info->relocateable
+      && ! coff_data (abfd)->link_info->shared
+      && strcmp (scnhdr_int->s_name, ".text") == 0)
     {
-      (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
-                            bfd_get_filename (abfd),
-                            scnhdr_int->s_nlnno);
-      bfd_set_error (bfd_error_file_truncated);
-      bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
-      ret = 0;
+      /* By inference from looking at MS output, the 32 bit field
+        which is the combintion of the number_of_relocs and
+        number_of_linenos is used for the line number count in
+        executables.  A 16-bit field won't do for cc1.  The MS
+        document says that the number of relocs is zero for
+        executables, but the 17-th bit has been observed to be there.
+        Overflow is not an issue: a 4G-line program will overflow a
+        bunch of other fields long before this!  */
+      bfd_h_put_16 (abfd, scnhdr_int->s_nlnno & 0xffff,
+                   (bfd_byte *) scnhdr_ext->s_nlnno);
+      bfd_h_put_16 (abfd, scnhdr_int->s_nlnno >> 16,
+                   (bfd_byte *) scnhdr_ext->s_nreloc);
     }
-  if (scnhdr_int->s_nreloc <= 0xffff)
-    bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
   else
     {
-      (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
-                            bfd_get_filename (abfd),
-                            scnhdr_int->s_nreloc);
-      bfd_set_error (bfd_error_file_truncated);
-      bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
-      ret = 0;
+      if (scnhdr_int->s_nlnno <= 0xffff)
+       bfd_h_put_16 (abfd, scnhdr_int->s_nlnno,
+                     (bfd_byte *) scnhdr_ext->s_nlnno);
+      else
+       {
+         (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
+                                bfd_get_filename (abfd),
+                                scnhdr_int->s_nlnno);
+         bfd_set_error (bfd_error_file_truncated);
+         bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+         ret = 0;
+       }
+      if (scnhdr_int->s_nreloc <= 0xffff)
+       bfd_h_put_16 (abfd, scnhdr_int->s_nreloc,
+                     (bfd_byte *) scnhdr_ext->s_nreloc);
+      else
+       {
+         (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
+                                bfd_get_filename (abfd),
+                                scnhdr_int->s_nreloc);
+         bfd_set_error (bfd_error_file_truncated);
+         bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+         ret = 0;
+       }
     }
   return ret;
 }