* coffcode.h (coff_set_alignment_hook): With PE_COFF reloc
authorNathan Sidwell <nathan@codesourcery.com>
Tue, 7 Oct 2003 08:49:11 +0000 (08:49 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Tue, 7 Oct 2003 08:49:11 +0000 (08:49 +0000)
overflow, set reloc start position to after the count
reloc. Subtract one from num relocs. Give error on 0xffff relocs
and no overflow.
* cofflink.c (_bfd_coff_final_link): Deal with PE_COFF reloc
overflow.
* peXXigen.c (_bfd_XXi_swap_scnhdr_out): Do overflow if >=
0xffff.

bfd/ChangeLog
bfd/coffcode.h
bfd/cofflink.c
bfd/peXXigen.c

index 45bb8e03341e121dd123d557edcfaf5747fa5b6a..177f6ab8c3bd89dfac05b6ba89944d57c3779f5e 100644 (file)
@@ -1,3 +1,14 @@
+2003-10-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * coffcode.h (coff_set_alignment_hook): With PE_COFF reloc
+       overflow, set reloc start position to after the count
+       reloc. Subtract one from num relocs. Give error on 0xffff relocs
+       and no overflow.
+       * cofflink.c (_bfd_coff_final_link): Deal with PE_COFF reloc
+       overflow.
+       * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Do overflow if >=
+       0xffff.
+
 2003-10-06  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Pad the
index 3b39f095af648c5994bd632070edb0bebef9774c..f5262f656ef49c2b453988f4a764595bc85a017a 100644 (file)
@@ -1694,15 +1694,21 @@ coff_set_alignment_hook (abfd, section, scnhdr)
       struct external_reloc dst;
       struct internal_reloc n;
       file_ptr oldpos = bfd_tell (abfd);
+      bfd_size_type relsz = bfd_coff_relsz (abfd);
+      
       bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0);
-      if (bfd_bread ((PTR) &dst, (bfd_size_type) bfd_coff_relsz (abfd), abfd)
-         != bfd_coff_relsz (abfd))
+      if (bfd_bread ((PTR) &dst, relsz, abfd) != relsz)
        return;
 
       coff_swap_reloc_in (abfd, &dst, &n);
       bfd_seek (abfd, oldpos, 0);
-      section->reloc_count = hdr->s_nreloc = n.r_vaddr;
+      section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;
+      section->rel_filepos += relsz;
     }
+  else if (hdr->s_nreloc == 0xffff)
+    (*_bfd_error_handler)
+      ("%s: warning: claims to have 0xffff relocs, without overflow",
+       bfd_get_filename (abfd));
 }
 #undef ALIGN_SET
 #undef ELIFALIGN_SET
index c1eee1b2325a3c736b60e6cf7aef4db50ecc80d2..1b059f6bf53cccc0c599b06019b768aa1df15a56 100644 (file)
@@ -1028,10 +1028,27 @@ _bfd_coff_final_link (bfd *abfd,
              bfd_coff_swap_reloc_out (abfd, irel, erel);
            }
 
-         if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
-             || (bfd_bwrite (external_relocs,
-                            (bfd_size_type) relsz * o->reloc_count, abfd)
-                 != (bfd_size_type) relsz * o->reloc_count))
+         if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
+           goto error_return;
+         if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+           {
+             /* In PE COFF, write the count of relocs as the first
+                reloc.  The header overflow bit will be set
+                elsewhere. */
+             struct internal_reloc incount;
+             bfd_byte *excount = (bfd_byte *)bfd_malloc (relsz);
+             
+             memset (&incount, 0, sizeof (incount));
+             incount.r_vaddr = o->reloc_count + 1;
+             bfd_coff_swap_reloc_out (abfd, (PTR) &incount, (PTR) excount);
+             if (bfd_bwrite (excount, relsz, abfd) != relsz)
+               /* We'll leak, but it's an error anyway. */
+               goto error_return;
+             free (excount);
+           }
+         if (bfd_bwrite (external_relocs,
+                         (bfd_size_type) relsz * o->reloc_count, abfd)
+             != (bfd_size_type) relsz * o->reloc_count)
            goto error_return;
        }
 
index 7f1a6a3dfe214aba93c81b439688af77de8bac18..ea98befa1ad0ee9b1768f3a1677235ded2d6c3ee 100644 (file)
@@ -990,7 +990,11 @@ _bfd_XXi_swap_scnhdr_out (abfd, in, out)
          ret = 0;
        }
 
-      if (scnhdr_int->s_nreloc <= 0xffff)
+      /* Although we could encode 0xffff relocs here, we do not, to be
+         consistent with other parts of bfd. Also it lets us warn, as
+         we should never see 0xffff here w/o having the overflow flag
+         set.  */
+      if (scnhdr_int->s_nreloc < 0xffff)
        H_PUT_16 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
       else
        {