static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long,
asymbol **, unsigned int,
unsigned *));
+static boolean som_begin_writing PARAMS ((bfd *));
static reloc_howto_type som_hppa_howto_table[] =
{
return true;
}
+/* Compute variable information to be placed in the SOM headers,
+ space/subspace dictionaries, relocation streams, etc. Begin
+ writing parts of the object file. */
+
+static boolean
+som_begin_writing (abfd)
+ bfd *abfd;
+{
+ unsigned long current_offset = 0;
+ int strings_size = 0;
+ unsigned int total_reloc_size = 0;
+ unsigned long num_spaces, num_subspaces, num_syms, i;
+ asection *section;
+ asymbol **syms = bfd_get_outsymbols (abfd);
+ unsigned int total_subspaces = 0;
+
+ /* The file header will always be first in an object file,
+ everything else can be in random locations. To keep things
+ "simple" BFD will lay out the object file in the manner suggested
+ by the PRO ABI for PA-RISC Systems. */
+
+ /* Before any output can really begin offsets for all the major
+ portions of the object file must be computed. So, starting
+ with the initial file header compute (and sometimes write)
+ each portion of the object file. */
+
+ /* Make room for the file header, it's contents are not complete
+ yet, so it can not be written at this time. */
+ current_offset += sizeof (struct header);
+
+ /* Any auxiliary headers will follow the file header. Right now
+ we have no auxiliary headers, so current_offset does not change. */
+ obj_som_file_hdr (abfd)->aux_header_location = current_offset;
+ obj_som_file_hdr (abfd)->aux_header_size = 0;
+
+ /* Next comes the initialization pointers; again we have no
+ initialization pointers, so current offset does not change. */
+ obj_som_file_hdr (abfd)->init_array_location = current_offset;
+ obj_som_file_hdr (abfd)->init_array_total = 0;
+
+ /* Next are the space records. These are fixed length records.
+
+ Count the number of spaces to determine how much room is needed
+ in the object file for the space records.
+
+ The names of the spaces are stored in a separate string table,
+ and the index for each space into the string table is computed
+ below. Therefore, it is not possible to write the space headers
+ at this time. */
+ num_spaces = som_count_spaces (abfd);
+ obj_som_file_hdr (abfd)->space_location = current_offset;
+ obj_som_file_hdr (abfd)->space_total = num_spaces;
+ current_offset += num_spaces * sizeof (struct space_dictionary_record);
+
+ /* Next are the subspace records. These are fixed length records.
+
+ Count the number of subspaes to determine how much room is needed
+ in the object file for the subspace records.
+
+ A variety if fields in the subspace record are still unknown at
+ this time (index into string table, fixup stream location/size, etc). */
+ num_subspaces = som_count_subspaces (abfd);
+ obj_som_file_hdr (abfd)->subspace_location = current_offset;
+ obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
+ current_offset += num_subspaces * sizeof (struct subspace_dictionary_record);
+
+ /* Next is the string table for the space/subspace names. We will
+ build and write the string table on the fly. At the same time
+ we will fill in the space/subspace name index fields. */
+
+ /* The string table needs to be aligned on a word boundary. */
+ if (current_offset % 4)
+ current_offset += (4 - (current_offset % 4));
+
+ /* Mark the offset of the space/subspace string table in the
+ file header. */
+ obj_som_file_hdr (abfd)->space_strings_location = current_offset;
+
+ /* Scribble out the space strings. */
+ if (som_write_space_strings (abfd, current_offset, &strings_size) == false)
+ return false;
+
+ /* Record total string table size in the header and update the
+ current offset. */
+ obj_som_file_hdr (abfd)->space_strings_size = strings_size;
+ current_offset += strings_size;
+
+ /* Next is the symbol table. These are fixed length records.
+
+ Count the number of symbols to determine how much room is needed
+ in the object file for the symbol table.
+
+ The names of the symbols are stored in a separate string table,
+ and the index for each symbol name into the string table is computed
+ below. Therefore, it is not possible to write the symobl table
+ at this time. */
+ num_syms = bfd_get_symcount (abfd);
+ obj_som_file_hdr (abfd)->symbol_location = current_offset;
+ obj_som_file_hdr (abfd)->symbol_total = num_syms;
+ current_offset += num_syms * sizeof (struct symbol_dictionary_record);
+
+ /* Do prep work before handling fixups. */
+ som_prep_for_fixups (abfd, syms, num_syms);
+
+ /* Next comes the fixup stream which starts on a word boundary. */
+ if (current_offset % 4)
+ current_offset += (4 - (current_offset % 4));
+ obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
+
+ /* Write the fixups and update fields in subspace headers which
+ relate to the fixup stream. */
+ if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false)
+ return false;
+
+ /* Record the total size of the fixup stream in the file header. */
+ obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
+ current_offset += total_reloc_size;
+
+ /* Next are the symbol strings.
+ Align them to a word boundary. */
+ if (current_offset % 4)
+ current_offset += (4 - (current_offset % 4));
+ obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
+
+ /* Scribble out the symbol strings. */
+ if (som_write_symbol_strings (abfd, current_offset, syms,
+ num_syms, &strings_size)
+ == false)
+ return false;
+
+ /* Record total string table size in header and update the
+ current offset. */
+ obj_som_file_hdr (abfd)->symbol_strings_size = strings_size;
+ current_offset += strings_size;
+
+ /* Next is the compiler records. We do not use these. */
+ obj_som_file_hdr (abfd)->compiler_location = current_offset;
+ obj_som_file_hdr (abfd)->compiler_total = 0;
+
+ /* Now compute the file positions for the loadable subspaces. */
+
+ section = abfd->sections;
+ for (i = 0; i < num_spaces; i++)
+ {
+ asection *subsection;
+
+ /* Find a space. */
+ while (som_section_data (section)->is_space == 0)
+ section = section->next;
+
+ /* Now look for all its subspaces. */
+ for (subsection = abfd->sections;
+ subsection != NULL;
+ subsection = subsection->next)
+ {
+
+ if (som_section_data (subsection)->is_subspace == 0
+ || som_section_data (subsection)->containing_space != section
+ || (subsection->flags & SEC_ALLOC) == 0)
+ continue;
+
+ som_section_data (subsection)->subspace_index = total_subspaces++;
+ /* This is real data to be loaded from the file. */
+ if (subsection->flags & SEC_LOAD)
+ {
+ som_section_data (subsection)->subspace_dict.file_loc_init_value
+ = current_offset;
+ section->filepos = current_offset;
+ current_offset += bfd_section_size (abfd, subsection);
+ }
+ /* Looks like uninitialized data. */
+ else
+ {
+ som_section_data (subsection)->subspace_dict.file_loc_init_value
+ = 0;
+ som_section_data (subsection)->subspace_dict.
+ initialization_length = 0;
+ }
+ }
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* Finally compute the file positions for unloadable subspaces. */
+
+ obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset;
+ section = abfd->sections;
+ for (i = 0; i < num_spaces; i++)
+ {
+ asection *subsection;
+
+ /* Find a space. */
+ while (som_section_data (section)->is_space == 0)
+ section = section->next;
+
+ /* Now look for all its subspaces. */
+ for (subsection = abfd->sections;
+ subsection != NULL;
+ subsection = subsection->next)
+ {
+
+ if (som_section_data (subsection)->is_subspace == 0
+ || som_section_data (subsection)->containing_space != section
+ || (subsection->flags & SEC_ALLOC) != 0)
+ continue;
+
+ som_section_data (subsection)->subspace_index = total_subspaces++;
+ /* This is real data to be loaded from the file. */
+ if ((subsection->flags & SEC_LOAD) == 0)
+ {
+ som_section_data (subsection)->subspace_dict.file_loc_init_value
+ = current_offset;
+ section->filepos = current_offset;
+ current_offset += bfd_section_size (abfd, subsection);
+ }
+ /* Looks like uninitialized data. */
+ else
+ {
+ som_section_data (subsection)->subspace_dict.file_loc_init_value
+ = 0;
+ som_section_data (subsection)->subspace_dict.
+ initialization_length = bfd_section_size (abfd, subsection);
+ }
+ }
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ obj_som_file_hdr (abfd)->unloadable_sp_size
+ = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location;
+
+ /* Loader fixups are not supported in any way shape or form. */
+ obj_som_file_hdr (abfd)->loader_fixup_location = 0;
+ obj_som_file_hdr (abfd)->loader_fixup_total = 0;
+
+ /* Done. Store the total size of the SOM. */
+ obj_som_file_hdr (abfd)->som_length = current_offset;
+ return true;
+}
+
/* Finally, scribble out the various headers to the disk. */
static boolean
Notify the world that output has begun. */
som_prep_headers (abfd);
abfd->output_has_begun = true;
-#if 0
- /* Not in Cygnus sources yet. */
/* Start writing the object file. This include all the string
tables, fixup streams, and other portions of the object file. */
som_begin_writing (abfd);
-#endif
}
/* Now that the symbol table information is complete, build and
Notify the world that output has begun. */
som_prep_headers (abfd);
abfd->output_has_begun = true;
-#if 0
- /* Not in Cygnus sources yet. */
/* Start writing the object file. This include all the string
tables, fixup streams, and other portions of the object file. */
som_begin_writing (abfd);
-#endif
}
/* Only write subspaces which have "real" contents (eg. the contents