static struct minimal_symbol * record_minimal_symbol_and_info (char *name, CORE_ADDR address, enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */ asection *bfd_section, struct objfile *objfile) { if (ms_type == mst_text || ms_type == mst_file_text) address = SMASH_TEXT_ADDRESS (address); return prim_record_minimal_symbol_and_info (name, address, ms_type, info, bfd_section->index, bfd_section, objfile); }
static void som_symtab_read (bfd *abfd, struct objfile *objfile, struct section_offsets *section_offsets) { unsigned int number_of_symbols; int val, dynamic; char *stringtab; asection *shlib_info; struct symbol_dictionary_record *buf, *bufp, *endbufp; char *symname; CONST int symsize = sizeof (struct symbol_dictionary_record); CORE_ADDR text_offset, data_offset; text_offset = ANOFFSET (section_offsets, 0); data_offset = ANOFFSET (section_offsets, 1); number_of_symbols = bfd_get_symcount (abfd); /* FIXME (alloca): could be quite large. */ buf = alloca (symsize * number_of_symbols); bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET); val = bfd_bread (buf, symsize * number_of_symbols, abfd); if (val != symsize * number_of_symbols) error ("Couldn't read symbol dictionary!"); /* FIXME (alloca): could be quite large. */ stringtab = alloca (obj_som_stringtab_size (abfd)); bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET); val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd); if (val != obj_som_stringtab_size (abfd)) error ("Can't read in HP string table."); /* We need to determine if objfile is a dynamic executable (so we can do the right thing for ST_ENTRY vs ST_CODE symbols). There's nothing in the header which easily allows us to do this. This code used to rely upon the existence of a $SHLIB_INFO$ section to make this determination. HP claims that it is more accurate to check for a nonzero text offset, but they have not provided any information about why that test is more accurate. */ dynamic = (text_offset != 0); endbufp = buf + number_of_symbols; for (bufp = buf; bufp < endbufp; ++bufp) { enum minimal_symbol_type ms_type; QUIT; switch (bufp->symbol_scope) { case SS_UNIVERSAL: case SS_EXTERNAL: switch (bufp->symbol_type) { case ST_SYM_EXT: case ST_ARG_EXT: continue; case ST_CODE: case ST_PRI_PROG: case ST_SEC_PROG: case ST_MILLICODE: symname = bufp->name.n_strx + stringtab; ms_type = mst_text; bufp->symbol_value += text_offset; bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_ENTRY: symname = bufp->name.n_strx + stringtab; /* For a dynamic executable, ST_ENTRY symbols are the stubs, while the ST_CODE symbol is the real function. */ if (dynamic) ms_type = mst_solib_trampoline; else ms_type = mst_text; bufp->symbol_value += text_offset; bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_DATA: symname = bufp->name.n_strx + stringtab; bufp->symbol_value += data_offset; ms_type = mst_data; break; default: continue; } break; #if 0 /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */ case SS_GLOBAL: #endif case SS_LOCAL: switch (bufp->symbol_type) { case ST_SYM_EXT: case ST_ARG_EXT: continue; case ST_CODE: symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); check_strange_names: /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local label prefixes for stabs, constant data, etc. So we need only filter out L$ symbols which are left in due to limitations in how GAS generates SOM relocations. When linking in the HPUX C-library the HP linker has the nasty habit of placing section symbols from the literal subspaces in the middle of the program's text. Filter those out as best we can. Check for first and last character being '$'. And finally, the newer HP compilers emit crud like $PIC_foo$N in some circumstance (PIC code I guess). It's also claimed that they emit D$ symbols too. What stupidity. */ if ((symname[0] == 'L' && symname[1] == '$') || (symname[0] == '$' && symname[strlen (symname) - 1] == '$') || (symname[0] == 'D' && symname[1] == '$') || (strncmp (symname, "L0\001", 3) == 0) || (strncmp (symname, "$PIC", 4) == 0)) continue; break; case ST_PRI_PROG: case ST_SEC_PROG: case ST_MILLICODE: symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_ENTRY: symname = bufp->name.n_strx + stringtab; /* SS_LOCAL symbols in a shared library do not have export stubs, so we do not have to worry about using mst_file_text vs mst_solib_trampoline here like we do for SS_UNIVERSAL and SS_EXTERNAL symbols above. */ ms_type = mst_file_text; bufp->symbol_value += text_offset; bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_DATA: symname = bufp->name.n_strx + stringtab; bufp->symbol_value += data_offset; ms_type = mst_file_data; goto check_strange_names; default: continue; } break; /* This can happen for common symbols when -E is passed to the final link. No idea _why_ that would make the linker force common symbols to have an SS_UNSAT scope, but it does. This also happens for weak symbols, but their type is ST_DATA. */ case SS_UNSAT: switch (bufp->symbol_type) { case ST_STORAGE: case ST_DATA: symname = bufp->name.n_strx + stringtab; bufp->symbol_value += data_offset; ms_type = mst_data; break; default: continue; } break; default: continue; } if (bufp->name.n_strx > obj_som_stringtab_size (abfd)) error ("Invalid symbol data; bad HP string table offset: %d", bufp->name.n_strx); prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type, objfile); } }