* Finish basic read-write support for SOM archive libraries. Bugs

surely remain as this hasn't been tested all that much.
	* som.c (SOM_LST_HASH_SIZE, SOM_LST_MODULE_LIMIT): Define.
	(struct som_misc_symbol_info): New structure to hold info necessary
	to build both normal and library symbol tables.
	(som_derive_misc_symbol_info): New function to derive info necessary
	to build both normal and library symbol tables.
	(som_build_and_write_symbol_table): Use new function to derive misc
	symbol information.
	(som_slurp_symbol_table): Update backend private data for symbols
	appropriately.
	(som_bfd_prep_for_ar_write): New function.
	(som_bfd_ar_symbol_hash): New function.
	(som_bfd_ar_write_symbol_stuff): New function.
	(som_write_armap): Flesh out.
	(som_vec): Fix ar padding character.

	* som.c: Consistently use memset rather than bzero.
This commit is contained in:
Jeff Law 1994-02-15 07:05:04 +00:00
parent caa0901f00
commit 6e033f8639
2 changed files with 595 additions and 122 deletions

View file

@ -1,3 +1,24 @@
Mon Feb 14 22:55:20 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
* Finish basic read-write support for SOM archive libraries. Bugs
surely remain as this hasn't been tested all that much.
* som.c (SOM_LST_HASH_SIZE, SOM_LST_MODULE_LIMIT): Define.
(struct som_misc_symbol_info): New structure to hold info necessary
to build both normal and library symbol tables.
(som_derive_misc_symbol_info): New function to derive info necessary
to build both normal and library symbol tables.
(som_build_and_write_symbol_table): Use new function to derive misc
symbol information.
(som_slurp_symbol_table): Update backend private data for symbols
appropriately.
(som_bfd_prep_for_ar_write): New function.
(som_bfd_ar_symbol_hash): New function.
(som_bfd_ar_write_symbol_stuff): New function.
(som_write_armap): Flesh out.
(som_vec): Fix ar padding character.
* som.c: Consistently use memset rather than bzero.
Mon Feb 14 17:02:28 1994 Stu Grossman (grossman at cygnus.com)
* coff-rs6000.c: Add Lynx core file support, use HOST_AIX, where
@ -14,6 +35,7 @@ Sun Feb 13 14:30:00 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
* som.h (som_symbol_data): Safely access backend private data
for BFD symbols. All callers changed.
* Read-only SOM archive support.
* som.c (som_bfd_count_ar_symbols): New helper function.
(som_bfd_fill_in_ar_symbols): New helper function.
(som_slurp_armap): New function to read a SOM LST.

691
bfd/som.c
View file

@ -72,6 +72,11 @@
#define SOM_TMP_BUFSIZE 8192
/* Size of the hash table in archives. */
#define SOM_LST_HASH_SIZE 31
/* Max number of SOMs to be found in an archive. */
#define SOM_LST_MODULE_LIMIT 1024
/* SOM allows any one of the four previous relocations to be reused
with a "R_PREV_FIXUP" relocation entry. Since R_PREV_FIXUP
@ -108,6 +113,17 @@ struct section_to_type
char type;
};
/* Assorted symbol information that needs to be derived from the BFD symbol
and/or the BFD backend private symbol data. */
struct som_misc_symbol_info
{
unsigned int symbol_type;
unsigned int symbol_scope;
unsigned int arg_reloc;
unsigned int symbol_info;
unsigned int symbol_value;
};
/* Forward declarations */
static boolean som_mkobject PARAMS ((bfd *));
@ -199,6 +215,14 @@ static boolean som_bfd_fill_in_ar_symbols PARAMS ((bfd *, struct lst_header *,
static boolean som_slurp_armap PARAMS ((bfd *));
static boolean som_write_armap PARAMS ((bfd *));
static boolean som_slurp_extended_name_table PARAMS ((bfd *));
static void som_bfd_derive_misc_symbol_info PARAMS ((bfd *, asymbol *,
struct som_misc_symbol_info *));
static boolean som_bfd_prep_for_ar_write PARAMS ((bfd *, unsigned int *,
unsigned int *));
static unsigned int som_bfd_ar_symbol_hash PARAMS ((asymbol *));
static boolean som_bfd_ar_write_symbol_stuff PARAMS ((bfd *, unsigned int,
unsigned int,
struct lst_header));
/* Map SOM section names to POSIX/BSD single-character symbol types.
@ -1659,7 +1683,7 @@ setup_sections (abfd, file_hdr)
/* Initialize save_subspace so we can reliably determine if this
loop placed any useful values into it. */
bzero (&save_subspace, sizeof (struct subspace_dictionary_record));
memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record));
/* Loop over the rest of the subspaces, building up more sections */
for (subspace_index = 0; subspace_index < space.subspace_quantity;
@ -1829,7 +1853,7 @@ som_object_p (abfd)
/* If the aux_header_size field in the file header is zero, then this
object is an incomplete executable (a .o file). Do not try to read
a non-existant auxiliary header. */
bzero (&aux_hdr, sizeof (struct som_exec_auxhdr));
memset (&aux_hdr, 0, sizeof (struct som_exec_auxhdr));
if (file_hdr.aux_header_size != 0)
{
if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
@ -2143,7 +2167,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
/* 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);
memset (tmp_space, 0, SOM_TMP_BUFSIZE);
p = tmp_space;
/* All the fixups for a particular subspace are emitted in a single
@ -2432,7 +2456,7 @@ som_write_space_strings (abfd, current_offset, string_sizep)
/* 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);
memset (tmp_space, 0, SOM_TMP_BUFSIZE);
p = tmp_space;
/* Seek to the start of the space strings in preparation for writing
@ -2527,7 +2551,7 @@ som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep)
/* 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);
memset (tmp_space, 0, SOM_TMP_BUFSIZE);
p = tmp_space;
/* Seek to the start of the space strings in preparation for writing
@ -3080,6 +3104,108 @@ som_compute_checksum (abfd)
return checksum;
}
static void
som_bfd_derive_misc_symbol_info (abfd, sym, info)
bfd *abfd;
asymbol *sym;
struct som_misc_symbol_info *info;
{
/* Initialize. */
memset (info, 0, sizeof (struct som_misc_symbol_info));
/* The HP SOM linker requires detailed type information about
all symbols (including undefined symbols!). Unfortunately,
the type specified in an import/export statement does not
always match what the linker wants. Severe braindamage. */
/* Section symbols will not have a SOM symbol type assigned to
them yet. Assign all section symbols type ST_DATA. */
if (sym->flags & BSF_SECTION_SYM)
info->symbol_type = ST_DATA;
else
{
/* Common symbols must have scope SS_UNSAT and type
ST_STORAGE or the linker will choke. */
if (sym->section == &bfd_com_section)
{
info->symbol_scope = SS_UNSAT;
info->symbol_type = ST_STORAGE;
}
/* It is possible to have a symbol without an associated
type. This happens if the user imported the symbol
without a type and the symbol was never defined
locally. If BSF_FUNCTION is set for this symbol, then
assign it type ST_CODE (the HP linker requires undefined
external functions to have type ST_CODE rather than ST_ENTRY). */
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
&& sym->section == &bfd_und_section
&& sym->flags & BSF_FUNCTION)
info->symbol_type = ST_CODE;
/* Handle function symbols which were defined in this file.
They should have type ST_ENTRY. Also retrieve the argument
relocation bits from the SOM backend information. */
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY
|| (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE
&& (sym->flags & BSF_FUNCTION))
|| (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
&& (sym->flags & BSF_FUNCTION)))
{
info->symbol_type = ST_ENTRY;
info->arg_reloc = som_symbol_data (sym)->tc_data.hppa_arg_reloc;
}
/* If the type is unknown at this point, it should be
ST_DATA (functions were handled as special cases above). */
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
info->symbol_type = ST_DATA;
/* From now on it's a very simple mapping. */
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
info->symbol_type = ST_ABSOLUTE;
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
info->symbol_type = ST_CODE;
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_DATA)
info->symbol_type = ST_DATA;
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_MILLICODE)
info->symbol_type = ST_MILLICODE;
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PLABEL)
info->symbol_type = ST_PLABEL;
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PRI_PROG)
info->symbol_type = ST_PRI_PROG;
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_SEC_PROG)
info->symbol_type = ST_SEC_PROG;
}
/* Now handle the symbol's scope. Exported data which is not
in the common section has scope SS_UNIVERSAL. Note scope
of common symbols was handled earlier! */
if (sym->flags & BSF_EXPORT && sym->section != &bfd_com_section)
info->symbol_scope = SS_UNIVERSAL;
/* Any undefined symbol at this point has a scope SS_UNSAT. */
else if (sym->section == &bfd_und_section)
info->symbol_scope = SS_UNSAT;
/* Anything else which is not in the common section has scope
SS_LOCAL. */
else if (sym->section != &bfd_com_section)
info->symbol_scope = SS_LOCAL;
/* Now set the symbol_info field. It has no real meaning
for undefined or common symbols, but the HP linker will
choke if it's not set to some "reasonable" value. We
use zero as a reasonable value. */
if (sym->section == &bfd_com_section || sym->section == &bfd_und_section)
info->symbol_info = 0;
/* For all other symbols, the symbol_info field contains the
subspace index of the space this symbol is contained in. */
else
info->symbol_info = som_section_data (sym->section)->subspace_index;
/* Set the symbol's value. */
info->symbol_value = sym->value + sym->section->vma;
}
/* Build and write, in one big chunk, the entire symbol table for
this BFD. */
@ -3097,127 +3223,30 @@ som_build_and_write_symbol_table (abfd)
to hold the symbol table as we build it. */
symtab_size = num_syms * sizeof (struct symbol_dictionary_record);
som_symtab = (struct symbol_dictionary_record *) alloca (symtab_size);
bzero (som_symtab, symtab_size);
memset (som_symtab, 0, symtab_size);
/* Walk over each symbol. */
for (i = 0; i < num_syms; i++)
{
struct som_misc_symbol_info info;
/* This is really an index into the symbol strings table.
By the time we get here, the index has already been
computed and stored into the name field in the BFD symbol. */
som_symtab[i].name.n_strx = (int) bfd_syms[i]->name;
/* The HP SOM linker requires detailed type information about
all symbols (including undefined symbols!). Unfortunately,
the type specified in an import/export statement does not
always match what the linker wants. Severe braindamage. */
/* Derive SOM information from the BFD symbol. */
som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info);
/* Section symbols will not have a SOM symbol type assigned to
them yet. Assign all section symbols type ST_DATA. */
if (bfd_syms[i]->flags & BSF_SECTION_SYM)
som_symtab[i].symbol_type = ST_DATA;
else
{
/* Common symbols must have scope SS_UNSAT and type
ST_STORAGE or the linker will choke. */
if (bfd_syms[i]->section == &bfd_com_section)
{
som_symtab[i].symbol_scope = SS_UNSAT;
som_symtab[i].symbol_type = ST_STORAGE;
/* Now use it. */
som_symtab[i].symbol_type = info.symbol_type;
som_symtab[i].symbol_scope = info.symbol_scope;
som_symtab[i].arg_reloc = info.arg_reloc;
som_symtab[i].symbol_info = info.symbol_info;
som_symtab[i].symbol_value = info.symbol_value;
}
/* It is possible to have a symbol without an associated
type. This happens if the user imported the symbol
without a type and the symbol was never defined
locally. If BSF_FUNCTION is set for this symbol, then
assign it type ST_CODE (the HP linker requires undefined
external functions to have type ST_CODE rather than ST_ENTRY. */
else if ((som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_UNKNOWN)
&& (bfd_syms[i]->section == &bfd_und_section)
&& (bfd_syms[i]->flags & BSF_FUNCTION))
som_symtab[i].symbol_type = ST_CODE;
/* Handle function symbols which were defined in this file.
They should have type ST_ENTRY. Also retrieve the argument
relocation bits from the SOM backend information. */
else if ((som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_ENTRY)
|| ((som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_CODE)
&& (bfd_syms[i]->flags & BSF_FUNCTION))
|| ((som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_UNKNOWN)
&& (bfd_syms[i]->flags & BSF_FUNCTION)))
{
som_symtab[i].symbol_type = ST_ENTRY;
som_symtab[i].arg_reloc
= som_symbol_data (bfd_syms[i])->tc_data.hppa_arg_reloc;
}
/* If the type is unknown at this point, it should be
ST_DATA (functions were handled as special cases above). */
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_UNKNOWN)
som_symtab[i].symbol_type = ST_DATA;
/* From now on it's a very simple mapping. */
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_ABSOLUTE)
som_symtab[i].symbol_type = ST_ABSOLUTE;
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_CODE)
som_symtab[i].symbol_type = ST_CODE;
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_DATA)
som_symtab[i].symbol_type = ST_DATA;
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_MILLICODE)
som_symtab[i].symbol_type = ST_MILLICODE;
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_PLABEL)
som_symtab[i].symbol_type = ST_PLABEL;
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_PRI_PROG)
som_symtab[i].symbol_type = ST_PRI_PROG;
else if (som_symbol_data (bfd_syms[i])->som_type
== SYMBOL_TYPE_SEC_PROG)
som_symtab[i].symbol_type = ST_SEC_PROG;
}
/* Now handle the symbol's scope. Exported data which is not
in the common section has scope SS_UNIVERSAL. Note scope
of common symbols was handled earlier! */
if (bfd_syms[i]->flags & BSF_EXPORT
&& bfd_syms[i]->section != &bfd_com_section)
som_symtab[i].symbol_scope = SS_UNIVERSAL;
/* Any undefined symbol at this point has a scope SS_UNSAT. */
else if (bfd_syms[i]->section == &bfd_und_section)
som_symtab[i].symbol_scope = SS_UNSAT;
/* Anything else which is not in the common section has scope
SS_LOCAL. */
else if (bfd_syms[i]->section != &bfd_com_section)
som_symtab[i].symbol_scope = SS_LOCAL;
/* Now set the symbol_info field. It has no real meaning
for undefined or common symbols, but the HP linker will
choke if it's not set to some "reasonable" value. We
use zero as a reasonable value. */
if (bfd_syms[i]->section == &bfd_com_section
|| bfd_syms[i]->section == &bfd_und_section)
som_symtab[i].symbol_info = 0;
/* For all other symbols, the symbol_info field contains the
subspace index of the space this symbol is contained in. */
else
som_symtab[i].symbol_info
= som_section_data (bfd_syms[i]->section)->subspace_index;
/* Set the symbol's value. */
som_symtab[i].symbol_value
= bfd_syms[i]->value + bfd_syms[i]->section->vma;
}
/* Egad. Everything is ready, seek to the right location and
/* Everything is ready, seek to the right location and
scribble out the symbol table. */
if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0)
{
@ -3396,6 +3425,29 @@ som_slurp_symbol_table (abfd)
|| bufp->symbol_type == ST_ARG_EXT)
continue;
/* Set some private data we care about. */
if (bufp->symbol_type == ST_NULL)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
else if (bufp->symbol_type == ST_ABSOLUTE)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE;
else if (bufp->symbol_type == ST_DATA)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
else if (bufp->symbol_type == ST_CODE)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE;
else if (bufp->symbol_type == ST_PRI_PROG)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG;
else if (bufp->symbol_type == ST_SEC_PROG)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG;
else if (bufp->symbol_type == ST_ENTRY)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY;
else if (bufp->symbol_type == ST_MILLICODE)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE;
else if (bufp->symbol_type == ST_PLABEL)
som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL;
else
som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
som_symbol_data (sym)->tc_data.hppa_arg_reloc = bufp->arg_reloc;
/* Some reasonable defaults. */
sym->symbol.the_bfd = abfd;
sym->symbol.name = bufp->name.n_strx + stringtab;
@ -3584,8 +3636,8 @@ som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
#define emptystack() (sp == stack)
som_initialize_reloc_queue (reloc_queue);
bzero (variables, sizeof (variables));
bzero (stack, sizeof (stack));
memset (variables, 0, sizeof (variables));
memset (stack, 0, sizeof (stack));
count = 0;
prev_fixup = 0;
sp = stack;
@ -3767,8 +3819,8 @@ som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
count++;
/* Now that we've handled a "full" relocation, reset
some state. */
bzero (variables, sizeof (variables));
bzero (stack, sizeof (stack));
memset (variables, 0, sizeof (variables));
memset (stack, 0, sizeof (stack));
}
}
return count;
@ -4545,13 +4597,412 @@ som_slurp_armap (abfd)
return true;
}
/* Write out the LST for the archive. Not supported yet. */
/* Begin preparing to write a SOM library symbol table.
As part of the prep work we need to determine the number of symbols
and the size of the associated string section. */
static boolean
som_bfd_prep_for_ar_write (abfd, num_syms, stringsize)
bfd *abfd;
unsigned int *num_syms, *stringsize;
{
bfd *curr_bfd = abfd->archive_head;
/* Some initialization. */
*num_syms = 0;
*stringsize = 0;
/* Iterate over each BFD within this archive. */
while (curr_bfd != NULL)
{
unsigned int curr_count, i;
asymbol *sym;
/* Make sure the symbol table has been read, then snag a pointer
to it. It's a little slimey to grab the symbols via obj_som_symtab,
but doing so avoids allocating lots of extra memory. */
if (som_slurp_symbol_table (curr_bfd) == false)
return false;
sym = (asymbol *)obj_som_symtab (curr_bfd);
curr_count = bfd_get_symcount (curr_bfd);
/* Examine each symbol to determine if it belongs in the
library symbol table. */
for (i = 0; i < curr_count; i++, sym++)
{
struct som_misc_symbol_info info;
/* Derive SOM information from the BFD symbol. */
som_bfd_derive_misc_symbol_info (curr_bfd, sym, &info);
/* Should we include this symbol? */
if (info.symbol_type == ST_NULL
|| info.symbol_type == ST_SYM_EXT
|| info.symbol_type == ST_ARG_EXT)
continue;
/* Only global symbols and unsatisfied commons. */
if (info.symbol_scope != SS_UNIVERSAL
&& info.symbol_type != ST_STORAGE)
continue;
/* Do no include undefined symbols. */
if (sym->section == &bfd_und_section)
continue;
/* Bump the various counters, being careful to honor
alignment considerations in the string table. */
(*num_syms)++;
*stringsize = *stringsize + strlen (sym->name) + 5;
while (*stringsize % 4)
(*stringsize)++;
}
curr_bfd = curr_bfd->next;
}
return true;
}
/* Hash a symbol name based on the hashing algorithm presented in the
SOM ABI. */
static unsigned int
som_bfd_ar_symbol_hash (symbol)
asymbol *symbol;
{
unsigned int len = strlen (symbol->name);
/* Names with length 1 are special. */
if (len == 1)
return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0];
return ((len & 0x7f) << 24) | (symbol->name[1] << 16)
| (symbol->name[len-2] << 8) | symbol->name[len-1];
}
/* Do the bulk of the work required to write the SOM library
symbol table. */
static boolean
som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst)
bfd *abfd;
unsigned int nsyms, string_size;
struct lst_header lst;
{
file_ptr lst_filepos;
char *strings, *p;
struct lst_symbol_record *lst_syms, *curr_lst_sym;
bfd *curr_bfd = abfd->archive_head;
unsigned int hash_table[lst.hash_size];
struct som_entry som_dict[lst.module_count];
struct lst_symbol_record *last_hash_entry[lst.hash_size];
unsigned int curr_som_offset, som_index;
/* Lots of fields are file positions relative to the start
of the lst record. So save its location. */
lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
/* Some initialization. */
memset (hash_table, 0, 4 * lst.hash_size);
memset (som_dict, 0, lst.module_count * sizeof (struct som_entry));
memset (last_hash_entry, 0,
lst.hash_size * sizeof (struct lst_symbol_record *));
/* Symbols have som_index fields, so we have to keep track of the
index of each SOM in the archive.
The SOM dictionary has (among other things) the absolute file
position for the SOM which a particular dictionary entry
describes. We have to compute that information as we iterate
through the SOMs/symbols. */
som_index = 0;
curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end;
/* FIXME should be done with buffers just like everything else... */
lst_syms = alloca (nsyms * sizeof (struct lst_symbol_record));
strings = alloca (string_size);
p = strings;
curr_lst_sym = lst_syms;
while (curr_bfd != NULL)
{
unsigned int curr_count, i;
asymbol *sym;
/* Make sure the symbol table has been read, then snag a pointer
to it. It's a little slimey to grab the symbols via obj_som_symtab,
but doing so avoids allocating lots of extra memory. */
if (som_slurp_symbol_table (curr_bfd) == false)
return false;
sym = (asymbol *)obj_som_symtab (curr_bfd);
curr_count = bfd_get_symcount (curr_bfd);
for (i = 0; i < curr_count; i++, sym++)
{
struct som_misc_symbol_info info;
/* Derive SOM information from the BFD symbol. */
som_bfd_derive_misc_symbol_info (curr_bfd, sym, &info);
/* Should we include this symbol? */
if (info.symbol_type == ST_NULL
|| info.symbol_type == ST_SYM_EXT
|| info.symbol_type == ST_ARG_EXT)
continue;
/* Only global symbols and unsatisfied commons. */
if (info.symbol_scope != SS_UNIVERSAL
&& info.symbol_type != ST_STORAGE)
continue;
/* Do no include undefined symbols. */
if (sym->section == &bfd_und_section)
continue;
/* If this is the first symbol from this SOM, then update
the SOM dictionary too. */
if (som_dict[som_index].location == 0)
{
som_dict[som_index].location = curr_som_offset;
som_dict[som_index].length = arelt_size (curr_bfd);
}
/* Fill in the lst symbol record. */
curr_lst_sym->hidden = 0;
curr_lst_sym->secondary_def = 0;
curr_lst_sym->symbol_type = info.symbol_type;
curr_lst_sym->symbol_scope = info.symbol_scope;
curr_lst_sym->check_level = 0;
curr_lst_sym->must_qualify = 0;
curr_lst_sym->initially_frozen = 0;
curr_lst_sym->memory_resident = 0;
curr_lst_sym->is_common = (sym->section == &bfd_com_section);
curr_lst_sym->dup_common = 0;
curr_lst_sym->xleast = 0;
curr_lst_sym->arg_reloc = info.arg_reloc;
curr_lst_sym->name.n_strx = p - strings + 4;
curr_lst_sym->qualifier_name.n_strx = 0;
curr_lst_sym->symbol_info = info.symbol_info;
curr_lst_sym->symbol_value = info.symbol_value;
curr_lst_sym->symbol_descriptor = 0;
curr_lst_sym->reserved = 0;
curr_lst_sym->som_index = som_index;
curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (sym);
curr_lst_sym->next_entry = 0;
/* Insert into the hash table. */
if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
{
struct lst_symbol_record *tmp;
/* There is already something at the head of this hash chain,
so tack this symbol onto the end of the chain. */
tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size];
tmp->next_entry
= (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
+ lst.hash_size * 4
+ lst.module_count * sizeof (struct som_entry)
+ sizeof (struct lst_header);
}
else
{
/* First entry in this hash chain. */
hash_table[curr_lst_sym->symbol_key % lst.hash_size]
= (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
+ lst.hash_size * 4
+ lst.module_count * sizeof (struct som_entry)
+ sizeof (struct lst_header);
}
/* Keep track of the last symbol we added to this chain so we can
easily update its next_entry pointer. */
last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]
= curr_lst_sym;
/* Update the string table. */
bfd_put_32 (abfd, strlen (sym->name), p);
p += 4;
strcpy (p, sym->name);
p += strlen (sym->name) + 1;
while ((int)p % 4)
{
bfd_put_8 (abfd, 0, p);
p++;
}
/* Head to the next symbol. */
curr_lst_sym++;
}
/* Keep track of where each SOM will finally reside; then look
at the next BFD. */
curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr);
curr_bfd = curr_bfd->next;
som_index++;
}
/* Now scribble out the hash table. */
if (bfd_write ((PTR) hash_table, lst.hash_size, 4, abfd)
!= lst.hash_size * 4)
{
bfd_error = system_call_error;
return false;
}
/* Then the SOM dictionary. */
if (bfd_write ((PTR) som_dict, lst.module_count,
sizeof (struct som_entry), abfd)
!= lst.module_count * sizeof (struct som_entry))
{
bfd_error = system_call_error;
return false;
}
/* The library symbols. */
if (bfd_write ((PTR) lst_syms, nsyms, sizeof (struct lst_symbol_record), abfd)
!= nsyms * sizeof (struct lst_symbol_record))
{
bfd_error = system_call_error;
return false;
}
/* And finally the strings. */
if (bfd_write ((PTR) strings, string_size, 1, abfd) != string_size)
{
bfd_error = system_call_error;
return false;
}
return true;
}
/* Write out the LST for the archive.
You'll never believe this is really how armaps are handled in SOM... */
static boolean
som_write_armap (abfd)
bfd *abfd;
{
bfd *curr_bfd;
struct stat statbuf;
unsigned int i, lst_size, nsyms, stringsize;
struct ar_hdr hdr;
struct lst_header lst;
int *p;
/* We'll use this for the archive's date and mode later. */
if (stat (abfd->filename, &statbuf) != 0)
{
bfd_error = system_call_error;
return false;
}
/* Fudge factor. */
bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60;
/* Account for the lst header first. */
lst_size = sizeof (struct lst_header);
/* Start building the LST header. */
lst.system_id = HP9000S800_ID;
lst.a_magic = LIBMAGIC;
lst.version_id = VERSION_ID;
lst.file_time.secs = 0;
lst.file_time.nanosecs = 0;
lst.hash_loc = lst_size;
lst.hash_size = SOM_LST_HASH_SIZE;
/* Hash table is a SOM_LST_HASH_SIZE 32bit offsets. */
lst_size += 4 * SOM_LST_HASH_SIZE;
/* We need to count the number of SOMs in this archive. */
curr_bfd = abfd->archive_head;
lst.module_count = 0;
while (curr_bfd != NULL)
{
lst.module_count++;
curr_bfd = curr_bfd->next;
}
lst.module_limit = lst.module_count;
lst.dir_loc = lst_size;
lst_size += sizeof (struct som_entry) * lst.module_count;
/* We don't support import/export tables, auxiliary headers,
or free lists yet. Make the linker work a little harder
to make our life easier. */
lst.export_loc = 0;
lst.export_count = 0;
lst.import_loc = 0;
lst.aux_loc = 0;
lst.aux_size = 0;
/* Count how many symbols we will have on the hash chains and the
size of the associated string table. */
if (som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize) == false)
return false;
lst_size += sizeof (struct lst_symbol_record) * nsyms;
/* For the string table. One day we might actually use this info
to avoid small seeks/reads when reading archives. */
lst.string_loc = lst_size;
lst.string_size = stringsize;
lst_size += stringsize;
/* SOM ABI says this must be zero. */
lst.free_list = 0;
lst.file_end = lst_size;
/* Compute the checksum. Must happen after the entire lst header
has filled in. */
p = (int *)&lst;
for (i = 0; i < sizeof (struct lst_header)/sizeof (int) - 1; i++)
lst.checksum ^= *p++;
sprintf (hdr.ar_name, "/ ");
sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
sprintf (hdr.ar_uid, "%d", getuid ());
sprintf (hdr.ar_gid, "%d", getgid ());
sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode);
sprintf (hdr.ar_size, "%-10d", (int) lst_size);
hdr.ar_fmag[0] = '`';
hdr.ar_fmag[1] = '\012';
/* Turn any nulls into spaces. */
for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *) (&hdr))[i] == '\0')
(((char *) (&hdr))[i]) = ' ';
/* Scribble out the ar header. */
if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd)
!= sizeof (struct ar_hdr))
{
bfd_error = system_call_error;
return false;
}
/* Now scribble out the lst header. */
if (bfd_write ((PTR) &lst, 1, sizeof (struct lst_header), abfd)
!= sizeof (struct lst_header))
{
bfd_error = system_call_error;
return false;
}
/* Build and write the armap. */
if (som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst) == false)
return false;
/* Done. */
return true;
}
/* Apparently the extened names are never used, even though they appear
in the SOM ABI. Hmmm. */
@ -4606,7 +5057,7 @@ bfd_target som_vec =
/* leading_symbol_char: is the first char of a user symbol
predictable, and if so what is it */
0,
' ', /* ar_pad_char */
'/', /* ar_pad_char */
16, /* ar_max_namelen */
3, /* minimum alignment */
bfd_getb64, bfd_getb_signed_64, bfd_putb64,