* som.c (som_begin_writing): New function.

This commit is contained in:
Jeff Law 1993-11-14 00:56:58 +00:00
parent 0b35f7ec59
commit 6eb644081a
2 changed files with 243 additions and 7 deletions

View File

@ -3,7 +3,8 @@ Sat Nov 13 15:27:15 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
* som.c (som_prep_for_fixups): New function.
(som_write_fixups): New function.
(som_write_space_strings): New function.
(som_write_symboL_strings): New function.
(som_write_symbol_strings): New function.
(som_begin_writing): New function.
Fri Nov 12 15:29:36 1993 Jeffrey A. Law (law@snake.cs.utah.edu)

247
bfd/som.c
View File

@ -174,6 +174,7 @@ static boolean som_write_space_strings PARAMS ((bfd *, unsigned long,
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[] =
{
@ -1975,6 +1976,246 @@ som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep)
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
@ -2333,12 +2574,9 @@ som_write_object_contents (abfd)
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
@ -2758,12 +2996,9 @@ som_set_section_contents (abfd, section, location, offset, count)
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