aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/coffcode.h12
-rw-r--r--bfd/cofflink.c25
-rw-r--r--bfd/peXXigen.c6
4 files changed, 46 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 45bb8e0..177f6ab 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 3b39f09..f5262f6 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -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
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index c1eee1b..1b059f6 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -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;
}
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 7f1a6a3..ea98bef 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -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
{