summaryrefslogtreecommitdiffstats
path: root/bfd/coffcode.h
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2000-10-06 19:47:51 +0000
committerDJ Delorie <dj@redhat.com>2000-10-06 19:47:51 +0000
commit3e4554a2064c06f1b49a759095ad5f2d172d45bc (patch)
tree8b7e2125fe2e18d4ea4815db4306b516b1a40158 /bfd/coffcode.h
parentfb27a91c6ce3ad4153ab103d2dfbb54b704922a2 (diff)
downloadppe42-binutils-3e4554a2064c06f1b49a759095ad5f2d172d45bc.tar.gz
ppe42-binutils-3e4554a2064c06f1b49a759095ad5f2d172d45bc.zip
* peigen.c (_bfd_pei_swap_scnhdr_out): note extended relocs
* coffcode.h (coff_set_alignment_hook): read extended reloc count (coff_write_relocs): write extended reloc count (coff_write_object_contents): account for extended relocs
Diffstat (limited to 'bfd/coffcode.h')
-rw-r--r--bfd/coffcode.h51
1 files changed, 49 insertions, 2 deletions
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 2750ad7d82..3bdf307f7b 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1607,6 +1607,23 @@ coff_set_alignment_hook (abfd, section, scnhdr)
pei_section_data (abfd, section)->pe_flags = hdr->s_flags;
section->lma = hdr->s_vaddr;
+
+ /* check for extended relocs */
+ if (hdr->s_flags & IMAGE_SCN_LNK_NRELOC_OVFL)
+ {
+ struct external_reloc dst;
+ struct internal_reloc n;
+ int oldpos = bfd_tell (abfd);
+ bfd_seek (abfd, hdr->s_relptr, 0);
+ if (bfd_read ((PTR) & dst, 1, bfd_coff_relsz (abfd), abfd)
+ != bfd_coff_relsz (abfd))
+ return;
+
+ coff_swap_reloc_in (abfd, &dst, &n);
+ bfd_seek (abfd, oldpos, 0);
+ section->reloc_count =
+ hdr->s_nreloc = n.r_vaddr;
+ }
}
#undef ALIGN_SET
#undef ELIFALIGN_SET
@@ -2336,6 +2353,22 @@ coff_write_relocs (abfd, first_undef)
if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0)
return false;
+
+#ifdef COFF_WITH_PE
+ if (s->reloc_count > 0xffff)
+ {
+ /* encode real count here as first reloc */
+ struct internal_reloc n;
+ memset ((PTR) & n, 0, sizeof (n));
+ /* add one to count *this* reloc (grr) */
+ n.r_vaddr = s->reloc_count + 1;
+ coff_swap_reloc_out (abfd, &n, &dst);
+ if (bfd_write ((PTR) & dst, 1, bfd_coff_relsz (abfd), abfd)
+ != bfd_coff_relsz (abfd))
+ return false;
+ }
+#endif
+
for (i = 0; i < s->reloc_count; i++)
{
struct internal_reloc n;
@@ -3176,7 +3209,7 @@ coff_write_object_contents (abfd)
file_ptr reloc_base;
file_ptr lineno_base;
file_ptr sym_base;
- unsigned long reloc_size = 0;
+ unsigned long reloc_size = 0, reloc_count = 0;
unsigned long lnno_size = 0;
boolean long_section_names;
asection *text_sec = NULL;
@@ -3207,7 +3240,16 @@ coff_write_object_contents (abfd)
for (current = abfd->sections; current != NULL; current =
current->next)
- reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
+ {
+#ifdef COFF_WITH_PE
+ /* we store the actual reloc count in the first reloc's addr */
+ if (current->reloc_count > 0xffff)
+ reloc_count ++;
+#endif
+ reloc_count += current->reloc_count;
+ }
+
+ reloc_size = reloc_count * bfd_coff_relsz (abfd);
lineno_base = reloc_base + reloc_size;
sym_base = lineno_base + lnno_size;
@@ -3230,6 +3272,11 @@ coff_write_object_contents (abfd)
{
current->rel_filepos = reloc_base;
reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
+#ifdef COFF_WITH_PE
+ /* extra reloc to hold real count */
+ if (current->reloc_count > 0xffff)
+ reloc_base += bfd_coff_relsz (abfd);
+#endif
}
else
{
OpenPOWER on IntegriCloud