daily update
[deliverable/binutils-gdb.git] / gdb / somread.c
CommitLineData
c906108c 1/* Read HP PA/Risc object files for GDB.
3a42e9d0 2 Copyright 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001
b6ba6518 3 Free Software Foundation, Inc.
c906108c
SS
4 Written by Fred Fish at Cygnus Support.
5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "bfd.h"
25#include <syms.h>
26#include "symtab.h"
27#include "symfile.h"
28#include "objfiles.h"
29#include "buildsym.h"
30#include "stabsread.h"
31#include "gdb-stabs.h"
32#include "complaints.h"
33#include "gdb_string.h"
34#include "demangle.h"
35#include "som.h"
36#include "libhppa.h"
37
38/* Various things we might complain about... */
39
a14ed312 40static void som_symfile_init (struct objfile *);
c906108c 41
a14ed312 42static void som_new_init (struct objfile *);
c906108c 43
a14ed312 44static void som_symfile_read (struct objfile *, int);
c906108c 45
a14ed312 46static void som_symfile_finish (struct objfile *);
c906108c
SS
47
48static void
a14ed312 49som_symtab_read (bfd *, struct objfile *, struct section_offsets *);
c906108c 50
d4f3574e 51static void
a14ed312 52som_symfile_offsets (struct objfile *, struct section_addr_info *);
c906108c
SS
53
54/* FIXME: These should really be in a common header somewhere */
55
a14ed312 56extern void hpread_build_psymtabs (struct objfile *, int);
c906108c 57
a14ed312 58extern void hpread_symfile_finish (struct objfile *);
c906108c 59
a14ed312 60extern void hpread_symfile_init (struct objfile *);
c906108c 61
a14ed312 62extern void do_pxdb (bfd *);
c906108c
SS
63
64/*
65
c5aa993b 66 LOCAL FUNCTION
c906108c 67
c5aa993b 68 som_symtab_read -- read the symbol table of a SOM file
c906108c 69
c5aa993b 70 SYNOPSIS
c906108c 71
c5aa993b
JM
72 void som_symtab_read (bfd *abfd, struct objfile *objfile,
73 struct section_offsets *section_offsets)
c906108c 74
c5aa993b 75 DESCRIPTION
c906108c 76
c5aa993b
JM
77 Given an open bfd, a base address to relocate symbols to, and a
78 flag that specifies whether or not this bfd is for an executable
79 or not (may be shared library for example), add all the global
80 function and data symbols to the minimal symbol table.
81 */
c906108c
SS
82
83static void
fba45db2
KB
84som_symtab_read (bfd *abfd, struct objfile *objfile,
85 struct section_offsets *section_offsets)
c906108c
SS
86{
87 unsigned int number_of_symbols;
88 int val, dynamic;
89 char *stringtab;
90 asection *shlib_info;
91 struct symbol_dictionary_record *buf, *bufp, *endbufp;
92 char *symname;
93 CONST int symsize = sizeof (struct symbol_dictionary_record);
94 CORE_ADDR text_offset, data_offset;
95
96
97 text_offset = ANOFFSET (section_offsets, 0);
98 data_offset = ANOFFSET (section_offsets, 1);
99
100 number_of_symbols = bfd_get_symcount (abfd);
101
34c0bd93 102 /* FIXME (alloca): could be quite large. */
c906108c
SS
103 buf = alloca (symsize * number_of_symbols);
104 bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET);
3a42e9d0 105 val = bfd_bread (buf, symsize * number_of_symbols, abfd);
c906108c
SS
106 if (val != symsize * number_of_symbols)
107 error ("Couldn't read symbol dictionary!");
108
34c0bd93 109 /* FIXME (alloca): could be quite large. */
c906108c
SS
110 stringtab = alloca (obj_som_stringtab_size (abfd));
111 bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET);
3a42e9d0 112 val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd);
c906108c
SS
113 if (val != obj_som_stringtab_size (abfd))
114 error ("Can't read in HP string table.");
115
116 /* We need to determine if objfile is a dynamic executable (so we
117 can do the right thing for ST_ENTRY vs ST_CODE symbols).
118
119 There's nothing in the header which easily allows us to do
120 this. The only reliable way I know of is to check for the
8e1a459b 121 existence of a $SHLIB_INFO$ section with a non-zero size. */
c906108c
SS
122 /* The code below is not a reliable way to check whether an
123 * executable is dynamic, so I commented it out - RT
124 * shlib_info = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
125 * if (shlib_info)
126 * dynamic = (bfd_section_size (objfile->obfd, shlib_info) != 0);
127 * else
128 * dynamic = 0;
129 */
130 /* I replaced the code with a simple check for text offset not being
131 * zero. Still not 100% reliable, but a more reliable way of asking
132 * "is this a dynamic executable?" than the above. RT
133 */
134 dynamic = (text_offset != 0);
135
136 endbufp = buf + number_of_symbols;
137 for (bufp = buf; bufp < endbufp; ++bufp)
138 {
139 enum minimal_symbol_type ms_type;
140
141 QUIT;
142
143 switch (bufp->symbol_scope)
144 {
145 case SS_UNIVERSAL:
146 case SS_EXTERNAL:
147 switch (bufp->symbol_type)
148 {
149 case ST_SYM_EXT:
150 case ST_ARG_EXT:
151 continue;
152
153 case ST_CODE:
154 case ST_PRI_PROG:
155 case ST_SEC_PROG:
156 case ST_MILLICODE:
157 symname = bufp->name.n_strx + stringtab;
158 ms_type = mst_text;
159 bufp->symbol_value += text_offset;
160#ifdef SMASH_TEXT_ADDRESS
161 SMASH_TEXT_ADDRESS (bufp->symbol_value);
162#endif
163 break;
164
165 case ST_ENTRY:
166 symname = bufp->name.n_strx + stringtab;
167 /* For a dynamic executable, ST_ENTRY symbols are
c5aa993b
JM
168 the stubs, while the ST_CODE symbol is the real
169 function. */
c906108c
SS
170 if (dynamic)
171 ms_type = mst_solib_trampoline;
172 else
173 ms_type = mst_text;
174 bufp->symbol_value += text_offset;
175#ifdef SMASH_TEXT_ADDRESS
176 SMASH_TEXT_ADDRESS (bufp->symbol_value);
177#endif
178 break;
179
180 case ST_STUB:
181 symname = bufp->name.n_strx + stringtab;
182 ms_type = mst_solib_trampoline;
183 bufp->symbol_value += text_offset;
184#ifdef SMASH_TEXT_ADDRESS
185 SMASH_TEXT_ADDRESS (bufp->symbol_value);
186#endif
187 break;
188
189 case ST_DATA:
190 symname = bufp->name.n_strx + stringtab;
191 bufp->symbol_value += data_offset;
192 ms_type = mst_data;
193 break;
194 default:
195 continue;
196 }
197 break;
198
199#if 0
200 /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */
201 case SS_GLOBAL:
202#endif
203 case SS_LOCAL:
204 switch (bufp->symbol_type)
205 {
206 case ST_SYM_EXT:
207 case ST_ARG_EXT:
208 continue;
209
210 case ST_CODE:
211 symname = bufp->name.n_strx + stringtab;
212 ms_type = mst_file_text;
213 bufp->symbol_value += text_offset;
214#ifdef SMASH_TEXT_ADDRESS
215 SMASH_TEXT_ADDRESS (bufp->symbol_value);
216#endif
217
218 check_strange_names:
219 /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
c5aa993b
JM
220 label prefixes for stabs, constant data, etc. So we need
221 only filter out L$ symbols which are left in due to
222 limitations in how GAS generates SOM relocations.
223
224 When linking in the HPUX C-library the HP linker has
225 the nasty habit of placing section symbols from the literal
226 subspaces in the middle of the program's text. Filter
227 those out as best we can. Check for first and last character
228 being '$'.
229
230 And finally, the newer HP compilers emit crud like $PIC_foo$N
231 in some circumstance (PIC code I guess). It's also claimed
232 that they emit D$ symbols too. What stupidity. */
c906108c 233 if ((symname[0] == 'L' && symname[1] == '$')
c5aa993b 234 || (symname[0] == '$' && symname[strlen (symname) - 1] == '$')
c906108c
SS
235 || (symname[0] == 'D' && symname[1] == '$')
236 || (strncmp (symname, "$PIC", 4) == 0))
237 continue;
238 break;
239
240 case ST_PRI_PROG:
241 case ST_SEC_PROG:
242 case ST_MILLICODE:
243 symname = bufp->name.n_strx + stringtab;
244 ms_type = mst_file_text;
245 bufp->symbol_value += text_offset;
246#ifdef SMASH_TEXT_ADDRESS
247 SMASH_TEXT_ADDRESS (bufp->symbol_value);
248#endif
249 break;
250
251 case ST_ENTRY:
252 symname = bufp->name.n_strx + stringtab;
253 /* For a dynamic executable, ST_ENTRY symbols are
c5aa993b
JM
254 the stubs, while the ST_CODE symbol is the real
255 function. */
c906108c
SS
256 if (dynamic)
257 ms_type = mst_solib_trampoline;
258 else
259 ms_type = mst_file_text;
260 bufp->symbol_value += text_offset;
261#ifdef SMASH_TEXT_ADDRESS
262 SMASH_TEXT_ADDRESS (bufp->symbol_value);
263#endif
264 break;
265
266 case ST_STUB:
267 symname = bufp->name.n_strx + stringtab;
268 ms_type = mst_solib_trampoline;
269 bufp->symbol_value += text_offset;
270#ifdef SMASH_TEXT_ADDRESS
271 SMASH_TEXT_ADDRESS (bufp->symbol_value);
272#endif
273 break;
274
275
276 case ST_DATA:
277 symname = bufp->name.n_strx + stringtab;
278 bufp->symbol_value += data_offset;
279 ms_type = mst_file_data;
280 goto check_strange_names;
281
282 default:
283 continue;
284 }
285 break;
286
c5aa993b
JM
287 /* This can happen for common symbols when -E is passed to the
288 final link. No idea _why_ that would make the linker force
289 common symbols to have an SS_UNSAT scope, but it does.
c906108c 290
c5aa993b
JM
291 This also happens for weak symbols, but their type is
292 ST_DATA. */
c906108c
SS
293 case SS_UNSAT:
294 switch (bufp->symbol_type)
295 {
c5aa993b
JM
296 case ST_STORAGE:
297 case ST_DATA:
298 symname = bufp->name.n_strx + stringtab;
299 bufp->symbol_value += data_offset;
300 ms_type = mst_data;
301 break;
302
303 default:
304 continue;
c906108c
SS
305 }
306 break;
307
308 default:
309 continue;
310 }
311
312 if (bufp->name.n_strx > obj_som_stringtab_size (abfd))
313 error ("Invalid symbol data; bad HP string table offset: %d",
314 bufp->name.n_strx);
315
c5aa993b 316 prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type,
c906108c
SS
317 objfile);
318 }
319}
320
321/* Scan and build partial symbols for a symbol file.
322 We have been initialized by a call to som_symfile_init, which
323 currently does nothing.
324
325 SECTION_OFFSETS is a set of offsets to apply to relocate the symbols
326 in each section. This is ignored, as it isn't needed for SOM.
327
328 MAINLINE is true if we are reading the main symbol
329 table (as opposed to a shared lib or dynamically loaded file).
330
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
337 for real.
338
339 We look for sections with specific names, to tell us what debug
340 format to look for: FIXME!!!
341
342 somstab_build_psymtabs() handles STABS symbols.
343
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. */
349
350static void
fba45db2 351som_symfile_read (struct objfile *objfile, int mainline)
c906108c
SS
352{
353 bfd *abfd = objfile->obfd;
354 struct cleanup *back_to;
355
356 do_pxdb (symfile_bfd_open (objfile->name));
357
358 init_minimal_symbol_collection ();
56e290f4 359 back_to = make_cleanup_discard_minimal_symbols ();
c906108c
SS
360
361 /* Read in the import list and the export list. Currently
362 the export list isn't used; the import list is used in
363 hp-symtab-read.c to handle static vars declared in other
364 shared libraries. */
365 init_import_symbols (objfile);
c5aa993b 366#if 0 /* Export symbols not used today 1997-08-05 */
c906108c
SS
367 init_export_symbols (objfile);
368#else
369 objfile->export_list = NULL;
370 objfile->export_list_size = 0;
371#endif
372
373 /* Process the normal SOM symbol table first.
374 This reads in the DNTT and string table, but doesn't
375 actually scan the DNTT. It does scan the linker symbol
376 table and thus build up a "minimal symbol table". */
c5aa993b 377
96baa820 378 som_symtab_read (abfd, objfile, objfile->section_offsets);
c906108c
SS
379
380 /* Now read information from the stabs debug sections.
381 This is a no-op for SOM.
382 Perhaps it is intended for some kind of mixed STABS/SOM
c5aa993b 383 situation? */
96baa820 384 stabsect_build_psymtabs (objfile, mainline,
c906108c
SS
385 "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$");
386
387 /* Now read the native debug information.
388 This builds the psymtab. This used to be done via a scan of
389 the DNTT, but is now done via the PXDB-built quick-lookup tables
390 together with a scan of the GNTT. See hp-psymtab-read.c. */
d4f3574e 391 hpread_build_psymtabs (objfile, mainline);
c906108c
SS
392
393 /* Install any minimal symbols that have been collected as the current
394 minimal symbols for this objfile.
395 Further symbol-reading is done incrementally, file-by-file,
396 in a step known as "psymtab-to-symtab" expansion. hp-symtab-read.c
397 contains the code to do the actual DNTT scanning and symtab building. */
398 install_minimal_symbols (objfile);
399
400 /* Force hppa-tdep.c to re-read the unwind descriptors. */
401 objfile->obj_private = NULL;
402 do_cleanups (back_to);
403}
404
405/* Initialize anything that needs initializing when a completely new symbol
406 file is specified (not just adding some symbols from another file, e.g. a
407 shared library).
408
409 We reinitialize buildsym, since we may be reading stabs from a SOM file. */
410
411static void
fba45db2 412som_new_init (struct objfile *ignore)
c906108c
SS
413{
414 stabsread_new_init ();
415 buildsym_new_init ();
416}
417
418/* Perform any local cleanups required when we are done with a particular
419 objfile. I.E, we are in the process of discarding all symbol information
420 for an objfile, freeing up all memory held for it, and unlinking the
421 objfile struct from the global list of known objfiles. */
422
423static void
fba45db2 424som_symfile_finish (struct objfile *objfile)
c906108c 425{
c5aa993b 426 if (objfile->sym_stab_info != NULL)
c906108c 427 {
aac7f4ea 428 xmfree (objfile->md, objfile->sym_stab_info);
c906108c
SS
429 }
430 hpread_symfile_finish (objfile);
431}
432
433/* SOM specific initialization routine for reading symbols. */
434
435static void
fba45db2 436som_symfile_init (struct objfile *objfile)
c906108c
SS
437{
438 /* SOM objects may be reordered, so set OBJF_REORDERED. If we
439 find this causes a significant slowdown in gdb then we could
440 set it in the debug symbol readers only when necessary. */
441 objfile->flags |= OBJF_REORDERED;
442 hpread_symfile_init (objfile);
443}
444
445/* SOM specific parsing routine for section offsets.
446
447 Plain and simple for now. */
448
d4f3574e 449static void
fba45db2 450som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
c906108c 451{
c906108c 452 int i;
0aa9cf96 453 CORE_ADDR text_addr;
c906108c
SS
454
455 objfile->num_sections = SECT_OFF_MAX;
d4f3574e 456 objfile->section_offsets = (struct section_offsets *)
c5aa993b 457 obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
c906108c 458
b8fbeb18
EZ
459 /* FIXME: ezannoni 2000-04-20 The section names in SOM are not
460 .text, .data, etc, but $TEXT$, $DATA$,... We should initialize
461 SET_OFF_* from bfd. (See default_symfile_offsets()). But I don't
462 know the correspondence between SOM sections and GDB's idea of
463 section names. So for now we default to what is was before these
464 changes.*/
465 objfile->sect_index_text = 0;
466 objfile->sect_index_data = 1;
467 objfile->sect_index_bss = 2;
468 objfile->sect_index_rodata = 3;
469
c906108c 470 /* First see if we're a shared library. If so, get the section
2acceee2 471 offsets from the library, else get them from addrs. */
d4f3574e 472 if (!som_solib_section_offsets (objfile, objfile->section_offsets))
c906108c 473 {
b8fbeb18
EZ
474 /* Note: Here is OK to compare with ".text" because this is the
475 name that gdb itself gives to that section, not the SOM
476 name. */
0aa9cf96
EZ
477 for (i = 0; i < SECT_OFF_MAX && addrs->other[i].name; i++)
478 if (strcmp (addrs->other[i].name, ".text") == 0)
479 break;
480 text_addr = addrs->other[i].addr;
481
c906108c 482 for (i = 0; i < SECT_OFF_MAX; i++)
f0a58b0b 483 (objfile->section_offsets)->offsets[i] = text_addr;
c906108c 484 }
c906108c
SS
485}
486
c906108c
SS
487/* Read in and initialize the SOM import list which is present
488 for all executables and shared libraries. The import list
489 consists of the symbols that are referenced in OBJFILE but
490 not defined there. (Variables that are imported are dealt
491 with as "loc_indirect" vars.)
492 Return value = number of import symbols read in. */
493int
fba45db2 494init_import_symbols (struct objfile *objfile)
c906108c
SS
495{
496 unsigned int import_list;
497 unsigned int import_list_size;
498 unsigned int string_table;
499 unsigned int string_table_size;
c5aa993b 500 char *string_buffer;
c906108c
SS
501 register int i;
502 register int j;
503 register int k;
c5aa993b
JM
504 asection *text_section; /* section handle */
505 unsigned int dl_header[12]; /* SOM executable header */
c906108c
SS
506
507 /* A struct for an entry in the SOM import list */
c5aa993b
JM
508 typedef struct
509 {
510 int name; /* index into the string table */
511 short dont_care1; /* we don't use this */
512 unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */
513 unsigned int reserved2:8; /* not used */
514 }
515 SomImportEntry;
516
517 /* We read 100 entries in at a time from the disk file. */
518#define SOM_READ_IMPORTS_NUM 100
519#define SOM_READ_IMPORTS_CHUNK_SIZE (sizeof (SomImportEntry) * SOM_READ_IMPORTS_NUM)
c906108c 520 SomImportEntry buffer[SOM_READ_IMPORTS_NUM];
c5aa993b 521
c906108c
SS
522 /* Initialize in case we error out */
523 objfile->import_list = NULL;
524 objfile->import_list_size = 0;
525
c906108c 526 /* It doesn't work, for some reason, to read in space $TEXT$;
c5aa993b 527 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
c906108c
SS
528 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
529 if (!text_section)
530 return 0;
c5aa993b 531 /* Get the SOM executable header */
c906108c
SS
532 bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int));
533
534 /* Check header version number for 10.x HP-UX */
535 /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912.
c5aa993b 536 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
c906108c
SS
537 if (dl_header[0] != 93092112)
538 return 0;
c5aa993b
JM
539
540 import_list = dl_header[4];
c906108c
SS
541 import_list_size = dl_header[5];
542 if (!import_list_size)
543 return 0;
c5aa993b 544 string_table = dl_header[10];
c906108c
SS
545 string_table_size = dl_header[11];
546 if (!string_table_size)
547 return 0;
548
c5aa993b 549 /* Suck in SOM string table */
c906108c
SS
550 string_buffer = (char *) xmalloc (string_table_size);
551 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
c5aa993b 552 string_table, string_table_size);
c906108c
SS
553
554 /* Allocate import list in the psymbol obstack; this has nothing
555 to do with psymbols, just a matter of convenience. We want the
c5aa993b 556 import list to be freed when the objfile is deallocated */
c906108c
SS
557 objfile->import_list
558 = (ImportEntry *) obstack_alloc (&objfile->psymbol_obstack,
c5aa993b 559 import_list_size * sizeof (ImportEntry));
c906108c 560
c5aa993b
JM
561 /* Read in the import entries, a bunch at a time */
562 for (j = 0, k = 0;
c906108c
SS
563 j < (import_list_size / SOM_READ_IMPORTS_NUM);
564 j++)
565 {
566 bfd_get_section_contents (objfile->obfd, text_section, buffer,
c5aa993b
JM
567 import_list + j * SOM_READ_IMPORTS_CHUNK_SIZE,
568 SOM_READ_IMPORTS_CHUNK_SIZE);
569 for (i = 0; i < SOM_READ_IMPORTS_NUM; i++, k++)
570 {
571 if (buffer[i].type != (unsigned char) 0)
572 {
573 objfile->import_list[k]
574 = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
575 strcpy (objfile->import_list[k], string_buffer + buffer[i].name);
576 /* Some day we might want to record the type and other information too */
577 }
578 else /* null type */
579 objfile->import_list[k] = NULL;
580
581 }
c906108c
SS
582 }
583
c5aa993b 584 /* Get the leftovers */
c906108c
SS
585 if (k < import_list_size)
586 bfd_get_section_contents (objfile->obfd, text_section, buffer,
c5aa993b
JM
587 import_list + k * sizeof (SomImportEntry),
588 (import_list_size - k) * sizeof (SomImportEntry));
589 for (i = 0; k < import_list_size; i++, k++)
c906108c
SS
590 {
591 if (buffer[i].type != (unsigned char) 0)
c5aa993b
JM
592 {
593 objfile->import_list[k]
594 = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
595 strcpy (objfile->import_list[k], string_buffer + buffer[i].name);
596 /* Some day we might want to record the type and other information too */
597 }
c906108c 598 else
c5aa993b 599 objfile->import_list[k] = NULL;
c906108c
SS
600 }
601
602 objfile->import_list_size = import_list_size;
b8c9b27d 603 xfree (string_buffer);
c906108c
SS
604 return import_list_size;
605}
606
607/* Read in and initialize the SOM export list which is present
608 for all executables and shared libraries. The import list
609 consists of the symbols that are referenced in OBJFILE but
610 not defined there. (Variables that are imported are dealt
611 with as "loc_indirect" vars.)
612 Return value = number of import symbols read in. */
613int
fba45db2 614init_export_symbols (struct objfile *objfile)
c906108c
SS
615{
616 unsigned int export_list;
617 unsigned int export_list_size;
618 unsigned int string_table;
619 unsigned int string_table_size;
c5aa993b 620 char *string_buffer;
c906108c
SS
621 register int i;
622 register int j;
623 register int k;
c5aa993b
JM
624 asection *text_section; /* section handle */
625 unsigned int dl_header[12]; /* SOM executable header */
c906108c
SS
626
627 /* A struct for an entry in the SOM export list */
c5aa993b
JM
628 typedef struct
629 {
630 int next; /* for hash table use -- we don't use this */
631 int name; /* index into string table */
632 int value; /* offset or plabel */
633 int dont_care1; /* not used */
634 unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */
635 char dont_care2; /* not used */
636 short dont_care3; /* not used */
637 }
638 SomExportEntry;
639
640 /* We read 100 entries in at a time from the disk file. */
641#define SOM_READ_EXPORTS_NUM 100
642#define SOM_READ_EXPORTS_CHUNK_SIZE (sizeof (SomExportEntry) * SOM_READ_EXPORTS_NUM)
c906108c
SS
643 SomExportEntry buffer[SOM_READ_EXPORTS_NUM];
644
645 /* Initialize in case we error out */
646 objfile->export_list = NULL;
647 objfile->export_list_size = 0;
648
c906108c 649 /* It doesn't work, for some reason, to read in space $TEXT$;
c5aa993b 650 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
c906108c
SS
651 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
652 if (!text_section)
653 return 0;
c5aa993b 654 /* Get the SOM executable header */
c906108c
SS
655 bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int));
656
657 /* Check header version number for 10.x HP-UX */
658 /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912.
c5aa993b 659 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
c906108c
SS
660 if (dl_header[0] != 93092112)
661 return 0;
c5aa993b
JM
662
663 export_list = dl_header[8];
664 export_list_size = dl_header[9];
c906108c
SS
665 if (!export_list_size)
666 return 0;
c5aa993b 667 string_table = dl_header[10];
c906108c
SS
668 string_table_size = dl_header[11];
669 if (!string_table_size)
670 return 0;
671
c5aa993b 672 /* Suck in SOM string table */
c906108c
SS
673 string_buffer = (char *) xmalloc (string_table_size);
674 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
c5aa993b 675 string_table, string_table_size);
c906108c
SS
676
677 /* Allocate export list in the psymbol obstack; this has nothing
678 to do with psymbols, just a matter of convenience. We want the
c5aa993b 679 export list to be freed when the objfile is deallocated */
c906108c 680 objfile->export_list
c5aa993b
JM
681 = (ExportEntry *) obstack_alloc (&objfile->psymbol_obstack,
682 export_list_size * sizeof (ExportEntry));
c906108c 683
c5aa993b
JM
684 /* Read in the export entries, a bunch at a time */
685 for (j = 0, k = 0;
c906108c
SS
686 j < (export_list_size / SOM_READ_EXPORTS_NUM);
687 j++)
688 {
689 bfd_get_section_contents (objfile->obfd, text_section, buffer,
c5aa993b
JM
690 export_list + j * SOM_READ_EXPORTS_CHUNK_SIZE,
691 SOM_READ_EXPORTS_CHUNK_SIZE);
692 for (i = 0; i < SOM_READ_EXPORTS_NUM; i++, k++)
693 {
694 if (buffer[i].type != (unsigned char) 0)
695 {
696 objfile->export_list[k].name
697 = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
698 strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name);
699 objfile->export_list[k].address = buffer[i].value;
700 /* Some day we might want to record the type and other information too */
701 }
702 else
703 /* null type */
704 {
705 objfile->export_list[k].name = NULL;
706 objfile->export_list[k].address = 0;
707 }
708 }
c906108c
SS
709 }
710
c5aa993b 711 /* Get the leftovers */
c906108c
SS
712 if (k < export_list_size)
713 bfd_get_section_contents (objfile->obfd, text_section, buffer,
c5aa993b
JM
714 export_list + k * sizeof (SomExportEntry),
715 (export_list_size - k) * sizeof (SomExportEntry));
716 for (i = 0; k < export_list_size; i++, k++)
c906108c
SS
717 {
718 if (buffer[i].type != (unsigned char) 0)
c5aa993b
JM
719 {
720 objfile->export_list[k].name
721 = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
722 strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name);
723 /* Some day we might want to record the type and other information too */
724 objfile->export_list[k].address = buffer[i].value;
725 }
c906108c 726 else
c5aa993b
JM
727 {
728 objfile->export_list[k].name = NULL;
729 objfile->export_list[k].address = 0;
730 }
c906108c
SS
731 }
732
733 objfile->export_list_size = export_list_size;
b8c9b27d 734 xfree (string_buffer);
c906108c
SS
735 return export_list_size;
736}
c5aa993b 737\f
c906108c
SS
738
739
c906108c
SS
740/* Register that we are able to handle SOM object file formats. */
741
742static struct sym_fns som_sym_fns =
743{
744 bfd_target_som_flavour,
c5aa993b
JM
745 som_new_init, /* sym_new_init: init anything gbl to entire symtab */
746 som_symfile_init, /* sym_init: read initial info, setup for sym_read() */
747 som_symfile_read, /* sym_read: read a symbol file into symtab */
748 som_symfile_finish, /* sym_finish: finished with file, cleanup */
749 som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
750 NULL /* next: pointer to next struct sym_fns */
c906108c
SS
751};
752
753void
fba45db2 754_initialize_somread (void)
c906108c
SS
755{
756 add_symtab_fns (&som_sym_fns);
757}
This page took 0.209266 seconds and 4 git commands to generate.