1 /* Read HP PA/Risc object files for GDB.
2 Copyright 1991, 1992 Free Software Foundation, Inc.
3 Written by Fred Fish at Cygnus Support.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include <time.h> /* For time_t in libbfd.h. */
24 #include <sys/types.h> /* For time_t, if not in time.h. */
33 #include "stabsread.h"
34 #include "gdb-stabs.h"
35 #include "complaints.h"
40 /* Size of n_value and n_strx fields in a stab symbol. */
41 #define BYTES_IN_WORD 4
44 #include "aout/aout64.h"
47 /* Various things we might complain about... */
50 som_symfile_init
PARAMS ((struct objfile
*));
53 som_new_init
PARAMS ((struct objfile
*));
56 som_symfile_read
PARAMS ((struct objfile
*, struct section_offsets
*, int));
59 som_symfile_finish
PARAMS ((struct objfile
*));
62 som_symtab_read
PARAMS ((bfd
*, CORE_ADDR
, struct objfile
*));
64 static struct section_offsets
*
65 som_symfile_offsets
PARAMS ((struct objfile
*, CORE_ADDR
));
68 record_minimal_symbol
PARAMS ((char *, CORE_ADDR
,
69 enum minimal_symbol_type
,
73 record_minimal_symbol (name
, address
, ms_type
, objfile
)
76 enum minimal_symbol_type ms_type
;
77 struct objfile
*objfile
;
79 name
= obsavestring (name
, strlen (name
), &objfile
-> symbol_obstack
);
80 prim_record_minimal_symbol (name
, address
, ms_type
, objfile
);
87 som_symtab_read -- read the symbol table of a SOM file
91 void som_symtab_read (bfd *abfd, CORE_ADDR addr,
92 struct objfile *objfile)
96 Given an open bfd, a base address to relocate symbols to, and a
97 flag that specifies whether or not this bfd is for an executable
98 or not (may be shared library for example), add all the global
99 function and data symbols to the minimal symbol table.
103 som_symtab_read (abfd
, addr
, objfile
)
106 struct objfile
*objfile
;
108 unsigned int number_of_symbols
;
111 asection
*shlib_info
;
112 struct symbol_dictionary_record
*buf
, *bufp
, *endbufp
;
114 CONST
int symsize
= sizeof (struct symbol_dictionary_record
);
116 number_of_symbols
= bfd_get_symcount (abfd
);
118 buf
= alloca (symsize
* number_of_symbols
);
119 bfd_seek (abfd
, obj_som_sym_filepos (abfd
), L_SET
);
120 val
= bfd_read (buf
, symsize
* number_of_symbols
, 1, abfd
);
121 if (val
!= symsize
* number_of_symbols
)
122 error ("Couldn't read symbol dictionary!");
124 stringtab
= alloca (obj_som_stringtab_size (abfd
));
125 bfd_seek (abfd
, obj_som_str_filepos (abfd
), L_SET
);
126 val
= bfd_read (stringtab
, obj_som_stringtab_size (abfd
), 1, abfd
);
127 if (val
!= obj_som_stringtab_size (abfd
))
128 error ("Can't read in HP string table.");
130 /* We need to determine if objfile is a dynamic executable (so we
131 can do the right thing for ST_ENTRY vs ST_CODE symbols).
133 There's nothing in the header which easily allows us to do
134 this. The only reliable way I know of is to check for the
135 existance of a $SHLIB_INFO$ section with a non-zero size. */
136 shlib_info
= bfd_get_section_by_name (objfile
->obfd
, "$SHLIB_INFO$");
138 dynamic
= (bfd_section_size (objfile
->obfd
, shlib_info
) != 0);
142 endbufp
= buf
+ number_of_symbols
;
143 for (bufp
= buf
; bufp
< endbufp
; ++bufp
)
145 enum minimal_symbol_type ms_type
;
149 switch (bufp
->symbol_scope
)
153 switch (bufp
->symbol_type
)
163 symname
= bufp
->name
.n_strx
+ stringtab
;
165 #ifdef SMASH_TEXT_ADDRESS
166 SMASH_TEXT_ADDRESS (bufp
->symbol_value
);
171 symname
= bufp
->name
.n_strx
+ stringtab
;
172 /* For a dynamic executable, ST_ENTRY symbols are
173 the stubs, while the ST_CODE symbol is the real
176 ms_type
= mst_solib_trampoline
;
179 #ifdef SMASH_TEXT_ADDRESS
180 SMASH_TEXT_ADDRESS (bufp
->symbol_value
);
185 symname
= bufp
->name
.n_strx
+ stringtab
;
186 ms_type
= mst_solib_trampoline
;
187 #ifdef SMASH_TEXT_ADDRESS
188 SMASH_TEXT_ADDRESS (bufp
->symbol_value
);
193 symname
= bufp
->name
.n_strx
+ stringtab
;
202 /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */
206 switch (bufp
->symbol_type
)
213 symname
= bufp
->name
.n_strx
+ stringtab
;
214 ms_type
= mst_file_text
;
215 #ifdef SMASH_TEXT_ADDRESS
216 SMASH_TEXT_ADDRESS (bufp
->symbol_value
);
220 /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
221 label prefixes for stabs, constant data, etc. So we need
222 only filter out L$ symbols which are left in due to
223 limitations in how GAS generates SOM relocations.
225 When linking in the HPUX C-library the HP linker has
226 the nasty habit of placing section symbols from the literal
227 subspaces in the middle of the program's text. Filter
228 those out as best we can. Check for first and last character
230 if ((symname
[0] == 'L' && symname
[1] == '$')
231 || (symname
[0] == '$' && symname
[strlen(symname
) - 1] == '$'))
238 symname
= bufp
->name
.n_strx
+ stringtab
;
239 ms_type
= mst_file_text
;
240 #ifdef SMASH_TEXT_ADDRESS
241 SMASH_TEXT_ADDRESS (bufp
->symbol_value
);
246 symname
= bufp
->name
.n_strx
+ stringtab
;
247 /* For a dynamic executable, ST_ENTRY symbols are
248 the stubs, while the ST_CODE symbol is the real
251 ms_type
= mst_solib_trampoline
;
253 ms_type
= mst_file_text
;
254 #ifdef SMASH_TEXT_ADDRESS
255 SMASH_TEXT_ADDRESS (bufp
->symbol_value
);
260 symname
= bufp
->name
.n_strx
+ stringtab
;
261 ms_type
= mst_solib_trampoline
;
262 #ifdef SMASH_TEXT_ADDRESS
263 SMASH_TEXT_ADDRESS (bufp
->symbol_value
);
269 symname
= bufp
->name
.n_strx
+ stringtab
;
270 ms_type
= mst_file_data
;
271 goto check_strange_names
;
282 if (bufp
->name
.n_strx
> obj_som_stringtab_size (abfd
))
283 error ("Invalid symbol data; bad HP string table offset: %d",
286 record_minimal_symbol (symname
,
287 bufp
->symbol_value
, ms_type
,
292 /* Scan and build partial symbols for a symbol file.
293 We have been initialized by a call to som_symfile_init, which
294 currently does nothing.
296 SECTION_OFFSETS is a set of offsets to apply to relocate the symbols
297 in each section. This is ignored, as it isn't needed for SOM.
299 MAINLINE is true if we are reading the main symbol
300 table (as opposed to a shared lib or dynamically loaded file).
302 This function only does the minimum work necessary for letting the
303 user "name" things symbolically; it does not read the entire symtab.
304 Instead, it reads the external and static symbols and puts them in partial
305 symbol tables. When more extensive information is requested of a
306 file, the corresponding partial symbol table is mutated into a full
307 fledged symbol table by going back and reading the symbols
310 We look for sections with specific names, to tell us what debug
311 format to look for: FIXME!!!
313 somstab_build_psymtabs() handles STABS symbols.
315 Note that SOM files have a "minimal" symbol table, which is vaguely
316 reminiscent of a COFF symbol table, but has only the minimal information
317 necessary for linking. We process this also, and use the information to
318 build gdb's minimal symbol table. This gives us some minimal debugging
319 capability even for files compiled without -g. */
322 som_symfile_read (objfile
, section_offsets
, mainline
)
323 struct objfile
*objfile
;
324 struct section_offsets
*section_offsets
;
327 bfd
*abfd
= objfile
->obfd
;
328 struct cleanup
*back_to
;
331 init_minimal_symbol_collection ();
332 back_to
= make_cleanup (discard_minimal_symbols
, 0);
334 /* FIXME, should take a section_offsets param, not just an offset. */
336 offset
= ANOFFSET (section_offsets
, 0);
338 /* Process the normal SOM symbol table first. */
340 som_symtab_read (abfd
, offset
, objfile
);
342 /* Now read information from the debugging sections. */
343 stabsect_build_psymtabs (objfile
, section_offsets
, mainline
,
344 "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$");
346 /* Install any minimal symbols that have been collected as the current
347 minimal symbols for this objfile. */
348 install_minimal_symbols (objfile
);
350 do_cleanups (back_to
);
353 /* Initialize anything that needs initializing when a completely new symbol
354 file is specified (not just adding some symbols from another file, e.g. a
357 We reinitialize buildsym, since we may be reading stabs from a SOM file. */
360 som_new_init (ignore
)
361 struct objfile
*ignore
;
363 stabsread_new_init ();
364 buildsym_new_init ();
367 /* Perform any local cleanups required when we are done with a particular
368 objfile. I.E, we are in the process of discarding all symbol information
369 for an objfile, freeing up all memory held for it, and unlinking the
370 objfile struct from the global list of known objfiles. */
373 som_symfile_finish (objfile
)
374 struct objfile
*objfile
;
376 if (objfile
-> sym_stab_info
!= NULL
)
378 mfree (objfile
-> md
, objfile
-> sym_stab_info
);
382 /* SOM specific initialization routine for reading symbols.
384 Nothing SOM specific left to do anymore. */
386 som_symfile_init (ignore
)
387 struct objfile
*ignore
;
391 /* SOM specific parsing routine for section offsets.
393 Plain and simple for now. */
395 static struct section_offsets
*
396 som_symfile_offsets (objfile
, addr
)
397 struct objfile
*objfile
;
400 struct section_offsets
*section_offsets
;
403 objfile
->num_sections
= SECT_OFF_MAX
;
404 section_offsets
= (struct section_offsets
*)
405 obstack_alloc (&objfile
-> psymbol_obstack
,
406 sizeof (struct section_offsets
)
407 + sizeof (section_offsets
->offsets
) * (SECT_OFF_MAX
-1));
409 for (i
= 0; i
< SECT_OFF_MAX
; i
++)
410 ANOFFSET (section_offsets
, i
) = addr
;
412 return section_offsets
;
415 /* Register that we are able to handle SOM object file formats. */
417 static struct sym_fns som_sym_fns
=
419 bfd_target_som_flavour
,
420 som_new_init
, /* sym_new_init: init anything gbl to entire symtab */
421 som_symfile_init
, /* sym_init: read initial info, setup for sym_read() */
422 som_symfile_read
, /* sym_read: read a symbol file into symtab */
423 som_symfile_finish
, /* sym_finish: finished with file, cleanup */
424 som_symfile_offsets
, /* sym_offsets: Translate ext. to int. relocation */
425 NULL
/* next: pointer to next struct sym_fns */
429 _initialize_somread ()
431 add_symtab_fns (&som_sym_fns
);