aboutsummaryrefslogtreecommitdiff
path: root/bfd/xcofflink.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1995-11-09 19:44:09 +0000
committerIan Lance Taylor <ian@airs.com>1995-11-09 19:44:09 +0000
commit4a378b13e498c735d6f51c546466d4d6a06da74c (patch)
tree0696db9c68d79ae6b1ae7d15dfa27388b391c4b5 /bfd/xcofflink.c
parent7906bf87b9bed567a2e683aaa65c1bace627a04b (diff)
downloadfsf-binutils-gdb-4a378b13e498c735d6f51c546466d4d6a06da74c.zip
fsf-binutils-gdb-4a378b13e498c735d6f51c546466d4d6a06da74c.tar.gz
fsf-binutils-gdb-4a378b13e498c735d6f51c546466d4d6a06da74c.tar.bz2
* coffcode.h (coff_set_alignment_hook): Write RS6000COFF_C version
which checks for STYP_OVRFLO sections. (coff_compute_section_file_positions): If RS6000COFF_C, handle reloc and lineno count overflows. (coff_write_object_contents): Call coff_count_linenumbers before coff_compute_section_file_positions. If RS6000COFF_C, handle reloc and lineno count overflows. * xcofflink.c (_bfd_xcoff_bfd_final_link): Count line numbers and relocs before dealing with .pad sections. Count overflow section headers when handling .pad sections.
Diffstat (limited to 'bfd/xcofflink.c')
-rw-r--r--bfd/xcofflink.c133
1 files changed, 69 insertions, 64 deletions
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index ca0b27b..d91e341 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -3238,6 +3238,48 @@ _bfd_xcoff_bfd_final_link (abfd, info)
if (finfo.strtab == NULL)
goto error_return;
+ /* Count the line number and relocation entries required for the
+ output file. Determine a few maximum sizes. */
+ max_contents_size = 0;
+ max_lineno_count = 0;
+ max_reloc_count = 0;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order)
+ {
+ asection *sec;
+
+ sec = p->u.indirect.section;
+
+ if (info->strip == strip_none
+ || info->strip == strip_some)
+ o->lineno_count += sec->lineno_count;
+
+ o->reloc_count += sec->reloc_count;
+
+ if (sec->_raw_size > max_contents_size)
+ max_contents_size = sec->_raw_size;
+ if (sec->lineno_count > max_lineno_count)
+ max_lineno_count = sec->lineno_count;
+ if (coff_section_data (sec->owner, sec) != NULL
+ && xcoff_section_data (sec->owner, sec) != NULL
+ && (xcoff_section_data (sec->owner, sec)->lineno_count
+ > max_lineno_count))
+ max_lineno_count =
+ xcoff_section_data (sec->owner, sec)->lineno_count;
+ if (sec->reloc_count > max_reloc_count)
+ max_reloc_count = sec->reloc_count;
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ ++o->reloc_count;
+ }
+ }
+
/* Compute the file positions for all the sections. */
if (abfd->output_has_begun)
{
@@ -3303,6 +3345,9 @@ _bfd_xcoff_bfd_final_link (abfd, info)
sofar = bfd_coff_filhsz (abfd);
sofar += bfd_coff_aoutsz (abfd);
sofar += abfd->section_count * bfd_coff_scnhsz (abfd);
+ for (o = abfd->sections; o != NULL; o = o->next)
+ if (o->reloc_count >= 0xffff || o->lineno_count >= 0xffff)
+ sofar += bfd_coff_scnhsz (abfd);
for (o = abfd->sections; o != NULL; o = o->next)
{
@@ -3331,58 +3376,6 @@ _bfd_xcoff_bfd_final_link (abfd, info)
bfd_coff_compute_section_file_positions (abfd);
}
- /* Count the line numbers and relocation entries required for the
- output file. Set the file positions for the relocs. */
- rel_filepos = obj_relocbase (abfd);
- relsz = bfd_coff_relsz (abfd);
- max_contents_size = 0;
- max_lineno_count = 0;
- max_reloc_count = 0;
- for (o = abfd->sections; o != NULL; o = o->next)
- {
- o->reloc_count = 0;
- o->lineno_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
- {
- if (p->type == bfd_indirect_link_order)
- {
- asection *sec;
-
- sec = p->u.indirect.section;
-
- if (info->strip == strip_none
- || info->strip == strip_some)
- o->lineno_count += sec->lineno_count;
-
- o->reloc_count += sec->reloc_count;
-
- if (sec->_raw_size > max_contents_size)
- max_contents_size = sec->_raw_size;
- if (sec->lineno_count > max_lineno_count)
- max_lineno_count = sec->lineno_count;
- if (coff_section_data (sec->owner, sec) != NULL
- && xcoff_section_data (sec->owner, sec) != NULL
- && (xcoff_section_data (sec->owner, sec)->lineno_count
- > max_lineno_count))
- max_lineno_count =
- xcoff_section_data (sec->owner, sec)->lineno_count;
- if (sec->reloc_count > max_reloc_count)
- max_reloc_count = sec->reloc_count;
- }
- else if (p->type == bfd_section_reloc_link_order
- || p->type == bfd_symbol_reloc_link_order)
- ++o->reloc_count;
- }
- if (o->reloc_count == 0)
- o->rel_filepos = 0;
- else
- {
- o->flags |= SEC_RELOC;
- o->rel_filepos = rel_filepos;
- rel_filepos += o->reloc_count * relsz;
- }
- }
-
/* Allocate space for the pointers we need to keep for the relocs. */
{
unsigned int i;
@@ -3405,24 +3398,20 @@ _bfd_xcoff_bfd_final_link (abfd, info)
}
}
- /* We now know the size of the relocs, so we can determine the file
- positions of the line numbers. */
- line_filepos = rel_filepos;
- finfo.line_filepos = line_filepos;
- linesz = bfd_coff_linesz (abfd);
+ /* Set the file positions for the relocs. */
+ rel_filepos = obj_relocbase (abfd);
+ relsz = bfd_coff_relsz (abfd);
max_output_reloc_count = 0;
for (o = abfd->sections; o != NULL; o = o->next)
{
- if (o->lineno_count == 0)
- o->line_filepos = 0;
+ if (o->reloc_count == 0)
+ o->rel_filepos = 0;
else
{
- o->line_filepos = line_filepos;
- line_filepos += o->lineno_count * linesz;
- }
+ o->flags |= SEC_RELOC;
+ o->rel_filepos = rel_filepos;
+ rel_filepos += o->reloc_count * relsz;
- if (o->reloc_count != 0)
- {
/* We don't know the indices of global symbols until we have
written out all the local symbols. For each section in
the output file, we keep an array of pointers to hash
@@ -3453,6 +3442,22 @@ _bfd_xcoff_bfd_final_link (abfd, info)
if (o->reloc_count > max_output_reloc_count)
max_output_reloc_count = o->reloc_count;
}
+ }
+
+ /* We now know the size of the relocs, so we can determine the file
+ positions of the line numbers. */
+ line_filepos = rel_filepos;
+ finfo.line_filepos = line_filepos;
+ linesz = bfd_coff_linesz (abfd);
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (o->lineno_count == 0)
+ o->line_filepos = 0;
+ else
+ {
+ o->line_filepos = line_filepos;
+ line_filepos += o->lineno_count * linesz;
+ }
/* Reset the reloc and lineno counts, so that we can use them to
count the number of entries we have output so far. */