diff options
author | Jeff Law <law@redhat.com> | 1993-11-14 00:33:00 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1993-11-14 00:33:00 +0000 |
commit | 0b35f7ec591b7b31ab0800276a6ff007360821a6 (patch) | |
tree | 817dc070f52fdc727adc87230ecbf315d7ee03ea /bfd/som.c | |
parent | 9d0dea6fcadf34de771c782b42bba555216da8e3 (diff) | |
download | gdb-0b35f7ec591b7b31ab0800276a6ff007360821a6.zip gdb-0b35f7ec591b7b31ab0800276a6ff007360821a6.tar.gz gdb-0b35f7ec591b7b31ab0800276a6ff007360821a6.tar.bz2 |
* som.c (som_write_space_strings): New function.
(som_write_symbol_strings): New function.
Diffstat (limited to 'bfd/som.c')
-rw-r--r-- | bfd/som.c | 180 |
1 files changed, 180 insertions, 0 deletions
@@ -169,6 +169,11 @@ static boolean som_write_headers PARAMS ((bfd *)); static boolean som_build_and_write_symbol_table PARAMS ((bfd *)); static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long)); static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *)); +static boolean som_write_space_strings PARAMS ((bfd *, unsigned long, + unsigned int *)); +static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long, + asymbol **, unsigned int, + unsigned *)); static reloc_howto_type som_hppa_howto_table[] = { @@ -1795,6 +1800,181 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep) return true; } +/* Write out the space/subspace string table. */ + +static boolean +som_write_space_strings (abfd, current_offset, string_sizep) + bfd *abfd; + unsigned long current_offset; + unsigned int *string_sizep; +{ + unsigned char *tmp_space, *p; + unsigned int strings_size = 0; + asection *section; + + /* Get a chunk of memory that we can use as buffer space, then throw + away. */ + tmp_space = alloca (SOM_TMP_BUFSIZE); + bzero (tmp_space, SOM_TMP_BUFSIZE); + p = tmp_space; + + /* Seek to the start of the space strings in preparation for writing + them out. */ + if (bfd_seek (abfd, current_offset, SEEK_SET) != 0) + { + bfd_error = system_call_error; + return false; + } + + /* Walk through all the spaces and subspaces (order is not important) + building up and writing string table entries for their names. */ + for (section = abfd->sections; section != NULL; section = section->next) + { + int length; + + /* Only work with space/subspaces; avoid any other sections + which might have been made (.text for example). */ + if (som_section_data (section)->is_space == 0 + && som_section_data (section)->is_subspace == 0) + continue; + + /* Get the length of the space/subspace name. */ + length = strlen (section->name); + + /* If there is not enough room for the next entry, then dump the + current buffer contents now. Each entry will take 4 bytes to + hold the string length + the string itself + null terminator. */ + if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE) + { + if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) + != p - tmp_space) + { + bfd_error = system_call_error; + return false; + } + /* Reset to beginning of the buffer space. */ + p = tmp_space; + } + + /* First element in a string table entry is the length of the + string. Alignment issues are already handled. */ + bfd_put_32 (abfd, length, p); + p += 4; + strings_size += 4; + + /* Record the index in the space/subspace records. */ + if (som_section_data (section)->is_space) + som_section_data (section)->space_dict.name.n_strx = strings_size; + else + som_section_data (section)->subspace_dict.name.n_strx = strings_size; + + /* Next comes the string itself + a null terminator. */ + strcpy (p, section->name); + p += length + 1; + strings_size += length + 1; + + /* Always align up to the next word boundary. */ + while (strings_size % 4) + { + bfd_put_8 (abfd, 0, p); + p++; + strings_size++; + } + } + + /* Done with the space/subspace strings. Write out any information + contained in a partial block. */ + if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) != p - tmp_space) + { + bfd_error = system_call_error; + return false; + } + *string_sizep = strings_size; + return true; +} + +/* Write out the symbol string table. */ + +static boolean +som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep) + bfd *abfd; + unsigned long current_offset; + asymbol **syms; + unsigned int num_syms; + unsigned int *string_sizep; +{ + unsigned int i; + unsigned char *tmp_space, *p; + unsigned int strings_size = 0; + + /* Get a chunk of memory that we can use as buffer space, then throw + away. */ + tmp_space = alloca (SOM_TMP_BUFSIZE); + bzero (tmp_space, SOM_TMP_BUFSIZE); + p = tmp_space; + + /* Seek to the start of the space strings in preparation for writing + them out. */ + if (bfd_seek (abfd, current_offset, SEEK_SET) != 0) + { + bfd_error = system_call_error; + return false; + } + + for (i = 0; i < num_syms; i++) + { + int length = strlen (syms[i]->name); + + /* If there is not enough room for the next entry, then dump the + current buffer contents now. */ + if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE) + { + if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) + != p - tmp_space) + { + bfd_error = system_call_error; + return false; + } + /* Reset to beginning of the buffer space. */ + p = tmp_space; + } + + /* First element in a string table entry is the length of the + string. This must always be 4 byte aligned. This is also + an appropriate time to fill in the string index field in the + symbol table entry. */ + bfd_put_32 (abfd, length, p); + strings_size += 4; + p += 4; + + /* Next comes the string itself + a null terminator. */ + strcpy (p, syms[i]->name); + + /* ACK. FIXME. */ + syms[i]->name = (char *)strings_size; + p += length + 1; + strings_size += length + 1; + + /* Always align up to the next word boundary. */ + while (strings_size % 4) + { + bfd_put_8 (abfd, 0, p); + strings_size++; + p++; + } + } + + /* Scribble out any partial block. */ + if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) != p - tmp_space) + { + bfd_error = system_call_error; + return false; + } + + *string_sizep = strings_size; + return true; +} + /* Finally, scribble out the various headers to the disk. */ static boolean |