]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/somread.c
PARAMS removal.
[thirdparty/binutils-gdb.git] / gdb / somread.c
1 /* Read HP PA/Risc object files for GDB.
2 Copyright 1991, 1992, 1996, 1999 Free Software Foundation, Inc.
3 Written by Fred Fish at Cygnus Support.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
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
39 static void som_symfile_init (struct objfile *);
40
41 static void som_new_init (struct objfile *);
42
43 static void som_symfile_read (struct objfile *, int);
44
45 static void som_symfile_finish (struct objfile *);
46
47 static void
48 som_symtab_read (bfd *, struct objfile *, struct section_offsets *);
49
50 static void
51 som_symfile_offsets (struct objfile *, struct section_addr_info *);
52
53 /* FIXME: These should really be in a common header somewhere */
54
55 extern void hpread_build_psymtabs (struct objfile *, int);
56
57 extern void hpread_symfile_finish (struct objfile *);
58
59 extern void hpread_symfile_init (struct objfile *);
60
61 extern void do_pxdb (bfd *);
62
63 /*
64
65 LOCAL FUNCTION
66
67 som_symtab_read -- read the symbol table of a SOM file
68
69 SYNOPSIS
70
71 void som_symtab_read (bfd *abfd, struct objfile *objfile,
72 struct section_offsets *section_offsets)
73
74 DESCRIPTION
75
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 */
81
82 static void
83 som_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
167 the stubs, while the ST_CODE symbol is the real
168 function. */
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
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. */
232 if ((symname[0] == 'L' && symname[1] == '$')
233 || (symname[0] == '$' && symname[strlen (symname) - 1] == '$')
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
253 the stubs, while the ST_CODE symbol is the real
254 function. */
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
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.
289
290 This also happens for weak symbols, but their type is
291 ST_DATA. */
292 case SS_UNSAT:
293 switch (bufp->symbol_type)
294 {
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;
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
315 prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type,
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
349 static void
350 som_symfile_read (objfile, mainline)
351 struct objfile *objfile;
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 ();
360 back_to = make_cleanup_discard_minimal_symbols ();
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);
367 #if 0 /* Export symbols not used today 1997-08-05 */
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". */
378
379 som_symtab_read (abfd, objfile, objfile->section_offsets);
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
384 situation? */
385 stabsect_build_psymtabs (objfile, mainline,
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. */
392 hpread_build_psymtabs (objfile, mainline);
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
412 static void
413 som_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
425 static void
426 som_symfile_finish (objfile)
427 struct objfile *objfile;
428 {
429 if (objfile->sym_stab_info != NULL)
430 {
431 mfree (objfile->md, objfile->sym_stab_info);
432 }
433 hpread_symfile_finish (objfile);
434 }
435
436 /* SOM specific initialization routine for reading symbols. */
437
438 static void
439 som_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
453 static void
454 som_symfile_offsets (objfile, addrs)
455 struct objfile *objfile;
456 struct section_addr_info *addrs;
457 {
458 int i;
459 CORE_ADDR text_addr;
460
461 objfile->num_sections = SECT_OFF_MAX;
462 objfile->section_offsets = (struct section_offsets *)
463 obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
464
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
476 /* First see if we're a shared library. If so, get the section
477 offsets from the library, else get them from addrs. */
478 if (!som_solib_section_offsets (objfile, objfile->section_offsets))
479 {
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. */
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
488 for (i = 0; i < SECT_OFF_MAX; i++)
489 ANOFFSET (objfile->section_offsets, i) = text_addr;
490 }
491 }
492
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. */
499 int
500 init_import_symbols (objfile)
501 struct objfile *objfile;
502 {
503 unsigned int import_list;
504 unsigned int import_list_size;
505 unsigned int string_table;
506 unsigned int string_table_size;
507 char *string_buffer;
508 register int i;
509 register int j;
510 register int k;
511 asection *text_section; /* section handle */
512 unsigned int dl_header[12]; /* SOM executable header */
513
514 /* A struct for an entry in the SOM import list */
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)
527 SomImportEntry buffer[SOM_READ_IMPORTS_NUM];
528
529 /* Initialize in case we error out */
530 objfile->import_list = NULL;
531 objfile->import_list_size = 0;
532
533 /* It doesn't work, for some reason, to read in space $TEXT$;
534 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
535 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
536 if (!text_section)
537 return 0;
538 /* Get the SOM executable header */
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.
543 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
544 if (dl_header[0] != 93092112)
545 return 0;
546
547 import_list = dl_header[4];
548 import_list_size = dl_header[5];
549 if (!import_list_size)
550 return 0;
551 string_table = dl_header[10];
552 string_table_size = dl_header[11];
553 if (!string_table_size)
554 return 0;
555
556 /* Suck in SOM string table */
557 string_buffer = (char *) xmalloc (string_table_size);
558 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
559 string_table, string_table_size);
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
563 import list to be freed when the objfile is deallocated */
564 objfile->import_list
565 = (ImportEntry *) obstack_alloc (&objfile->psymbol_obstack,
566 import_list_size * sizeof (ImportEntry));
567
568 /* Read in the import entries, a bunch at a time */
569 for (j = 0, k = 0;
570 j < (import_list_size / SOM_READ_IMPORTS_NUM);
571 j++)
572 {
573 bfd_get_section_contents (objfile->obfd, text_section, buffer,
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 }
589 }
590
591 /* Get the leftovers */
592 if (k < import_list_size)
593 bfd_get_section_contents (objfile->obfd, text_section, buffer,
594 import_list + k * sizeof (SomImportEntry),
595 (import_list_size - k) * sizeof (SomImportEntry));
596 for (i = 0; k < import_list_size; i++, k++)
597 {
598 if (buffer[i].type != (unsigned char) 0)
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 }
605 else
606 objfile->import_list[k] = NULL;
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. */
620 int
621 init_export_symbols (objfile)
622 struct objfile *objfile;
623 {
624 unsigned int export_list;
625 unsigned int export_list_size;
626 unsigned int string_table;
627 unsigned int string_table_size;
628 char *string_buffer;
629 register int i;
630 register int j;
631 register int k;
632 asection *text_section; /* section handle */
633 unsigned int dl_header[12]; /* SOM executable header */
634
635 /* A struct for an entry in the SOM export list */
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)
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
657 /* It doesn't work, for some reason, to read in space $TEXT$;
658 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
659 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
660 if (!text_section)
661 return 0;
662 /* Get the SOM executable header */
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.
667 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
668 if (dl_header[0] != 93092112)
669 return 0;
670
671 export_list = dl_header[8];
672 export_list_size = dl_header[9];
673 if (!export_list_size)
674 return 0;
675 string_table = dl_header[10];
676 string_table_size = dl_header[11];
677 if (!string_table_size)
678 return 0;
679
680 /* Suck in SOM string table */
681 string_buffer = (char *) xmalloc (string_table_size);
682 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
683 string_table, string_table_size);
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
687 export list to be freed when the objfile is deallocated */
688 objfile->export_list
689 = (ExportEntry *) obstack_alloc (&objfile->psymbol_obstack,
690 export_list_size * sizeof (ExportEntry));
691
692 /* Read in the export entries, a bunch at a time */
693 for (j = 0, k = 0;
694 j < (export_list_size / SOM_READ_EXPORTS_NUM);
695 j++)
696 {
697 bfd_get_section_contents (objfile->obfd, text_section, buffer,
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 }
717 }
718
719 /* Get the leftovers */
720 if (k < export_list_size)
721 bfd_get_section_contents (objfile->obfd, text_section, buffer,
722 export_list + k * sizeof (SomExportEntry),
723 (export_list_size - k) * sizeof (SomExportEntry));
724 for (i = 0; k < export_list_size; i++, k++)
725 {
726 if (buffer[i].type != (unsigned char) 0)
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 }
734 else
735 {
736 objfile->export_list[k].name = NULL;
737 objfile->export_list[k].address = 0;
738 }
739 }
740
741 objfile->export_list_size = export_list_size;
742 free (string_buffer);
743 return export_list_size;
744 }
745 \f
746
747
748 /* Register that we are able to handle SOM object file formats. */
749
750 static struct sym_fns som_sym_fns =
751 {
752 bfd_target_som_flavour,
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 */
759 };
760
761 void
762 _initialize_somread ()
763 {
764 add_symtab_fns (&som_sym_fns);
765 }