1 /* Read HP PA/Risc object files for GDB.
2 Copyright (C) 1991-2013 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 3 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, see <http://www.gnu.org/licenses/>. */
27 #include "stabsread.h"
28 #include "gdb-stabs.h"
29 #include "complaints.h"
30 #include "gdb_string.h"
36 #include "solib-som.h"
38 /* Read the symbol table of a SOM file.
40 Given an open bfd, a base address to relocate symbols to, and a
41 flag that specifies whether or not this bfd is for an executable
42 or not (may be shared library for example), add all the global
43 function and data symbols to the minimal symbol table. */
46 som_symtab_read (bfd
*abfd
, struct objfile
*objfile
,
47 struct section_offsets
*section_offsets
)
49 struct cleanup
*cleanup
;
50 struct gdbarch
*gdbarch
= get_objfile_arch (objfile
);
51 unsigned int number_of_symbols
;
55 struct som_external_symbol_dictionary_record
*buf
, *bufp
, *endbufp
;
57 CONST
int symsize
= sizeof (struct som_external_symbol_dictionary_record
);
60 #define text_offset ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile))
61 #define data_offset ANOFFSET (section_offsets, SECT_OFF_DATA (objfile))
63 number_of_symbols
= bfd_get_symcount (abfd
);
65 /* Allocate a buffer to read in the debug info.
66 We avoid using alloca because the memory size could be so large
67 that we could hit the stack size limit. */
68 buf
= xmalloc (symsize
* number_of_symbols
);
69 cleanup
= make_cleanup (xfree
, buf
);
70 bfd_seek (abfd
, obj_som_sym_filepos (abfd
), SEEK_SET
);
71 val
= bfd_bread (buf
, symsize
* number_of_symbols
, abfd
);
72 if (val
!= symsize
* number_of_symbols
)
73 error (_("Couldn't read symbol dictionary!"));
75 /* Allocate a buffer to read in the som stringtab section of
76 the debugging info. Again, we avoid using alloca because
77 the data could be so large that we could potentially hit
78 the stack size limitat. */
79 stringtab
= xmalloc (obj_som_stringtab_size (abfd
));
80 make_cleanup (xfree
, stringtab
);
81 bfd_seek (abfd
, obj_som_str_filepos (abfd
), SEEK_SET
);
82 val
= bfd_bread (stringtab
, obj_som_stringtab_size (abfd
), abfd
);
83 if (val
!= obj_som_stringtab_size (abfd
))
84 error (_("Can't read in HP string table."));
86 /* We need to determine if objfile is a dynamic executable (so we
87 can do the right thing for ST_ENTRY vs ST_CODE symbols).
89 There's nothing in the header which easily allows us to do
92 This code used to rely upon the existence of a $SHLIB_INFO$
93 section to make this determination. HP claims that it is
94 more accurate to check for a nonzero text offset, but they
95 have not provided any information about why that test is
97 dynamic
= (text_offset
!= 0);
99 endbufp
= buf
+ number_of_symbols
;
100 for (bufp
= buf
; bufp
< endbufp
; ++bufp
)
102 enum minimal_symbol_type ms_type
;
103 unsigned int flags
= bfd_getb32 (bufp
->flags
);
104 unsigned int symbol_type
105 = (flags
>> SOM_SYMBOL_TYPE_SH
) & SOM_SYMBOL_TYPE_MASK
;
106 unsigned int symbol_scope
107 = (flags
>> SOM_SYMBOL_SCOPE_SH
) & SOM_SYMBOL_SCOPE_MASK
;
108 CORE_ADDR symbol_value
= bfd_getb32 (bufp
->symbol_value
);
109 asection
*section
= NULL
;
113 /* Compute the section. */
114 switch (symbol_scope
)
117 if (symbol_type
!= ST_STORAGE
)
118 section
= bfd_und_section_ptr
;
120 section
= bfd_com_section_ptr
;
124 if (symbol_type
!= ST_STORAGE
)
125 section
= bfd_und_section_ptr
;
127 section
= bfd_com_section_ptr
;
131 section
= bfd_section_from_som_symbol (abfd
, bufp
);
135 section
= bfd_section_from_som_symbol (abfd
, bufp
);
139 switch (symbol_scope
)
153 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
155 symbol_value
+= text_offset
;
156 symbol_value
= gdbarch_addr_bits_remove (gdbarch
, symbol_value
);
160 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
161 /* For a dynamic executable, ST_ENTRY symbols are
162 the stubs, while the ST_CODE symbol is the real
165 ms_type
= mst_solib_trampoline
;
168 symbol_value
+= text_offset
;
169 symbol_value
= gdbarch_addr_bits_remove (gdbarch
, symbol_value
);
173 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
174 ms_type
= mst_solib_trampoline
;
175 symbol_value
+= text_offset
;
176 symbol_value
= gdbarch_addr_bits_remove (gdbarch
, symbol_value
);
180 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
181 symbol_value
+= data_offset
;
190 /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */
201 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
202 ms_type
= mst_file_text
;
203 symbol_value
+= text_offset
;
204 symbol_value
= gdbarch_addr_bits_remove (gdbarch
, symbol_value
);
207 /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
208 label prefixes for stabs, constant data, etc. So we need
209 only filter out L$ symbols which are left in due to
210 limitations in how GAS generates SOM relocations.
212 When linking in the HPUX C-library the HP linker has
213 the nasty habit of placing section symbols from the literal
214 subspaces in the middle of the program's text. Filter
215 those out as best we can. Check for first and last character
218 And finally, the newer HP compilers emit crud like $PIC_foo$N
219 in some circumstance (PIC code I guess). It's also claimed
220 that they emit D$ symbols too. What stupidity. */
221 if ((symname
[0] == 'L' && symname
[1] == '$')
222 || (symname
[0] == '$' && symname
[strlen (symname
) - 1] == '$')
223 || (symname
[0] == 'D' && symname
[1] == '$')
224 || (strncmp (symname
, "L0\001", 3) == 0)
225 || (strncmp (symname
, "$PIC", 4) == 0))
232 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
233 ms_type
= mst_file_text
;
234 symbol_value
+= text_offset
;
235 symbol_value
= gdbarch_addr_bits_remove (gdbarch
, symbol_value
);
239 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
240 /* SS_LOCAL symbols in a shared library do not have
241 export stubs, so we do not have to worry about
242 using mst_file_text vs mst_solib_trampoline here like
243 we do for SS_UNIVERSAL and SS_EXTERNAL symbols above. */
244 ms_type
= mst_file_text
;
245 symbol_value
+= text_offset
;
246 symbol_value
= gdbarch_addr_bits_remove (gdbarch
, symbol_value
);
250 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
251 ms_type
= mst_solib_trampoline
;
252 symbol_value
+= text_offset
;
253 symbol_value
= gdbarch_addr_bits_remove (gdbarch
, symbol_value
);
258 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
259 symbol_value
+= data_offset
;
260 ms_type
= mst_file_data
;
261 goto check_strange_names
;
268 /* This can happen for common symbols when -E is passed to the
269 final link. No idea _why_ that would make the linker force
270 common symbols to have an SS_UNSAT scope, but it does.
272 This also happens for weak symbols, but their type is
279 symname
= bfd_getb32 (bufp
->name
) + stringtab
;
280 symbol_value
+= data_offset
;
293 if (bfd_getb32 (bufp
->name
) > obj_som_stringtab_size (abfd
))
294 error (_("Invalid symbol data; bad HP string table offset: %s"),
295 plongest (bfd_getb32 (bufp
->name
)));
297 if (bfd_is_const_section (section
))
299 struct obj_section
*iter
;
301 ALL_OBJFILE_OSECTIONS (objfile
, iter
)
303 if (bfd_is_const_section (iter
->the_bfd_section
))
306 if (obj_section_addr (iter
) <= symbol_value
307 && symbol_value
< obj_section_endaddr (iter
))
309 section
= iter
->the_bfd_section
;
315 prim_record_minimal_symbol_and_info (symname
, symbol_value
, ms_type
,
316 gdb_bfd_section_index (objfile
->obfd
,
321 do_cleanups (cleanup
);
324 /* Scan and build partial symbols for a symbol file.
325 We have been initialized by a call to som_symfile_init, which
326 currently does nothing.
328 SECTION_OFFSETS is a set of offsets to apply to relocate the symbols
329 in each section. This is ignored, as it isn't needed for SOM.
331 This function only does the minimum work necessary for letting the
332 user "name" things symbolically; it does not read the entire symtab.
333 Instead, it reads the external and static symbols and puts them in partial
334 symbol tables. When more extensive information is requested of a
335 file, the corresponding partial symbol table is mutated into a full
336 fledged symbol table by going back and reading the symbols
339 We look for sections with specific names, to tell us what debug
342 somstab_build_psymtabs() handles STABS symbols.
344 Note that SOM files have a "minimal" symbol table, which is vaguely
345 reminiscent of a COFF symbol table, but has only the minimal information
346 necessary for linking. We process this also, and use the information to
347 build gdb's minimal symbol table. This gives us some minimal debugging
348 capability even for files compiled without -g. */
351 som_symfile_read (struct objfile
*objfile
, int symfile_flags
)
353 bfd
*abfd
= objfile
->obfd
;
354 struct cleanup
*back_to
;
356 init_minimal_symbol_collection ();
357 back_to
= make_cleanup_discard_minimal_symbols ();
359 /* Process the normal SOM symbol table first.
360 This reads in the DNTT and string table, but doesn't
361 actually scan the DNTT. It does scan the linker symbol
362 table and thus build up a "minimal symbol table". */
364 som_symtab_read (abfd
, objfile
, objfile
->section_offsets
);
366 /* Install any minimal symbols that have been collected as the current
367 minimal symbols for this objfile.
368 Further symbol-reading is done incrementally, file-by-file,
369 in a step known as "psymtab-to-symtab" expansion. hp-symtab-read.c
370 contains the code to do the actual DNTT scanning and symtab building. */
371 install_minimal_symbols (objfile
);
372 do_cleanups (back_to
);
374 /* Now read information from the stabs debug sections.
375 This is emitted by gcc. */
376 stabsect_build_psymtabs (objfile
,
377 "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$");
380 /* Initialize anything that needs initializing when a completely new symbol
381 file is specified (not just adding some symbols from another file, e.g. a
384 We reinitialize buildsym, since we may be reading stabs from a SOM file. */
387 som_new_init (struct objfile
*ignore
)
389 stabsread_new_init ();
390 buildsym_new_init ();
393 /* Perform any local cleanups required when we are done with a particular
394 objfile. I.e, we are in the process of discarding all symbol information
395 for an objfile, freeing up all memory held for it, and unlinking the
396 objfile struct from the global list of known objfiles. */
399 som_symfile_finish (struct objfile
*objfile
)
403 /* SOM specific initialization routine for reading symbols. */
406 som_symfile_init (struct objfile
*objfile
)
408 /* SOM objects may be reordered, so set OBJF_REORDERED. If we
409 find this causes a significant slowdown in gdb then we could
410 set it in the debug symbol readers only when necessary. */
411 objfile
->flags
|= OBJF_REORDERED
;
414 /* An object of this type is passed to find_section_offset. */
416 struct find_section_offset_arg
420 struct objfile
*objfile
;
422 /* Flags to invert. */
426 /* Flags to look for. */
430 /* A text section with non-zero size, if any. */
432 asection
*best_section
;
434 /* An empty text section, if any. */
436 asection
*empty_section
;
439 /* A callback for bfd_map_over_sections that tries to find a section
440 with particular flags in an objfile. */
443 find_section_offset (bfd
*abfd
, asection
*sect
, void *arg
)
445 struct find_section_offset_arg
*info
= arg
;
448 aflag
= bfd_get_section_flags (abfd
, sect
);
450 aflag
^= info
->invert
;
452 if ((aflag
& info
->flags
) == info
->flags
)
454 if (bfd_section_size (abfd
, sect
) > 0)
456 if (info
->best_section
== NULL
)
457 info
->best_section
= sect
;
461 if (info
->empty_section
== NULL
)
462 info
->empty_section
= sect
;
467 /* Set a section index from a BFD. */
470 set_section_index (struct objfile
*objfile
, flagword invert
, flagword flags
,
473 struct find_section_offset_arg info
;
475 info
.objfile
= objfile
;
476 info
.best_section
= NULL
;
477 info
.empty_section
= NULL
;
478 info
.invert
= invert
;
480 bfd_map_over_sections (objfile
->obfd
, find_section_offset
, &info
);
482 if (info
.best_section
)
483 *index_ptr
= info
.best_section
->index
;
484 else if (info
.empty_section
)
485 *index_ptr
= info
.empty_section
->index
;
488 /* SOM specific parsing routine for section offsets.
490 Plain and simple for now. */
493 som_symfile_offsets (struct objfile
*objfile
,
494 const struct section_addr_info
*addrs
)
500 objfile
->num_sections
= bfd_count_sections (objfile
->obfd
);
501 objfile
->section_offsets
= (struct section_offsets
*)
502 obstack_alloc (&objfile
->objfile_obstack
,
503 SIZEOF_N_SECTION_OFFSETS (objfile
->num_sections
));
505 set_section_index (objfile
, 0, SEC_ALLOC
| SEC_CODE
,
506 &objfile
->sect_index_text
);
507 set_section_index (objfile
, 0, SEC_ALLOC
| SEC_DATA
,
508 &objfile
->sect_index_data
);
509 set_section_index (objfile
, SEC_LOAD
, SEC_ALLOC
| SEC_LOAD
,
510 &objfile
->sect_index_bss
);
511 set_section_index (objfile
, 0, SEC_ALLOC
| SEC_READONLY
,
512 &objfile
->sect_index_rodata
);
514 /* First see if we're a shared library. If so, get the section
515 offsets from the library, else get them from addrs. */
516 if (!som_solib_section_offsets (objfile
, objfile
->section_offsets
))
518 /* Note: Here is OK to compare with ".text" because this is the
519 name that gdb itself gives to that section, not the SOM
521 for (i
= 0; i
< addrs
->num_sections
; i
++)
522 if (strcmp (addrs
->other
[i
].name
, ".text") == 0)
524 text_addr
= addrs
->other
[i
].addr
;
526 for (i
= 0; i
< objfile
->num_sections
; i
++)
527 (objfile
->section_offsets
)->offsets
[i
] = text_addr
;
533 /* Register that we are able to handle SOM object file formats. */
535 static const struct sym_fns som_sym_fns
=
537 bfd_target_som_flavour
,
538 som_new_init
, /* init anything gbl to entire symtab */
539 som_symfile_init
, /* read initial info, setup for sym_read() */
540 som_symfile_read
, /* read a symbol file into symtab */
541 NULL
, /* sym_read_psymbols */
542 som_symfile_finish
, /* finished with file, cleanup */
543 som_symfile_offsets
, /* Translate ext. to int. relocation */
544 default_symfile_segments
, /* Get segment information from a file. */
546 default_symfile_relocate
, /* Relocate a debug section. */
547 NULL
, /* sym_get_probes */
551 initialize_file_ftype _initialize_somread
;
554 _initialize_somread (void)
556 add_symtab_fns (&som_sym_fns
);