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