diff options
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/coffcode.h | 12 | ||||
-rw-r--r-- | bfd/cofflink.c | 25 | ||||
-rw-r--r-- | bfd/peXXigen.c | 6 |
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 { |