2002-01-07 Michael Snyder <msnyder@redhat.com>
[deliverable/binutils-gdb.git] / gdb / somread.c
1 /* Read HP PA/Risc object files for GDB.
2 Copyright 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Written by Fred Fish at Cygnus Support.
5
6 This file is part of GDB.
7
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.
12
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.
17
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. */
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
40 static void som_symfile_init (struct objfile *);
41
42 static void som_new_init (struct objfile *);
43
44 static void som_symfile_read (struct objfile *, int);
45
46 static void som_symfile_finish (struct objfile *);
47
48 static void
49 som_symtab_read (bfd *, struct objfile *, struct section_offsets *);
50
51 static void
52 som_symfile_offsets (struct objfile *, struct section_addr_info *);
53
54 /* FIXME: These should really be in a common header somewhere */
55
56 extern void hpread_build_psymtabs (struct objfile *, int);
57
58 extern void hpread_symfile_finish (struct objfile *);
59
60 extern void hpread_symfile_init (struct objfile *);
61
62 extern void do_pxdb (bfd *);
63
64 /*
65
66 LOCAL FUNCTION
67
68 som_symtab_read -- read the symbol table of a SOM file
69
70 SYNOPSIS
71
72 void som_symtab_read (bfd *abfd, struct objfile *objfile,
73 struct section_offsets *section_offsets)
74
75 DESCRIPTION
76
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 */
82
83 static void
84 som_symtab_read (bfd *abfd, struct objfile *objfile,
85 struct section_offsets *section_offsets)
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
102 /* FIXME (alloca): could be quite large. */
103 buf = alloca (symsize * number_of_symbols);
104 bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET);
105 val = bfd_bread (buf, symsize * number_of_symbols, abfd);
106 if (val != symsize * number_of_symbols)
107 error ("Couldn't read symbol dictionary!");
108
109 /* FIXME (alloca): could be quite large. */
110 stringtab = alloca (obj_som_stringtab_size (abfd));
111 bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET);
112 val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd);
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
121 existence of a $SHLIB_INFO$ section with a non-zero size. */
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
168 the stubs, while the ST_CODE symbol is the real
169 function. */
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
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. */
233 if ((symname[0] == 'L' && symname[1] == '$')
234 || (symname[0] == '$' && symname[strlen (symname) - 1] == '$')
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
254 the stubs, while the ST_CODE symbol is the real
255 function. */
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
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.
290
291 This also happens for weak symbols, but their type is
292 ST_DATA. */
293 case SS_UNSAT:
294 switch (bufp->symbol_type)
295 {
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;
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
316 prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type,
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
350 static void
351 som_symfile_read (struct objfile *objfile, int mainline)
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 ();
359 back_to = make_cleanup_discard_minimal_symbols ();
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);
366 #if 0 /* Export symbols not used today 1997-08-05 */
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". */
377
378 som_symtab_read (abfd, objfile, objfile->section_offsets);
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
383 situation? */
384 stabsect_build_psymtabs (objfile, mainline,
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. */
391 hpread_build_psymtabs (objfile, mainline);
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
411 static void
412 som_new_init (struct objfile *ignore)
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
423 static void
424 som_symfile_finish (struct objfile *objfile)
425 {
426 if (objfile->sym_stab_info != NULL)
427 {
428 xmfree (objfile->md, objfile->sym_stab_info);
429 }
430 hpread_symfile_finish (objfile);
431 }
432
433 /* SOM specific initialization routine for reading symbols. */
434
435 static void
436 som_symfile_init (struct objfile *objfile)
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
449 static void
450 som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
451 {
452 int i;
453 CORE_ADDR text_addr;
454
455 objfile->num_sections = SECT_OFF_MAX;
456 objfile->section_offsets = (struct section_offsets *)
457 obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
458
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
470 /* First see if we're a shared library. If so, get the section
471 offsets from the library, else get them from addrs. */
472 if (!som_solib_section_offsets (objfile, objfile->section_offsets))
473 {
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. */
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
482 for (i = 0; i < SECT_OFF_MAX; i++)
483 (objfile->section_offsets)->offsets[i] = text_addr;
484 }
485 }
486
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. */
493 int
494 init_import_symbols (struct objfile *objfile)
495 {
496 unsigned int import_list;
497 unsigned int import_list_size;
498 unsigned int string_table;
499 unsigned int string_table_size;
500 char *string_buffer;
501 register int i;
502 register int j;
503 register int k;
504 asection *text_section; /* section handle */
505 unsigned int dl_header[12]; /* SOM executable header */
506
507 /* A struct for an entry in the SOM import list */
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)
520 SomImportEntry buffer[SOM_READ_IMPORTS_NUM];
521
522 /* Initialize in case we error out */
523 objfile->import_list = NULL;
524 objfile->import_list_size = 0;
525
526 /* It doesn't work, for some reason, to read in space $TEXT$;
527 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
528 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
529 if (!text_section)
530 return 0;
531 /* Get the SOM executable header */
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.
536 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
537 if (dl_header[0] != 93092112)
538 return 0;
539
540 import_list = dl_header[4];
541 import_list_size = dl_header[5];
542 if (!import_list_size)
543 return 0;
544 string_table = dl_header[10];
545 string_table_size = dl_header[11];
546 if (!string_table_size)
547 return 0;
548
549 /* Suck in SOM string table */
550 string_buffer = (char *) xmalloc (string_table_size);
551 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
552 string_table, string_table_size);
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
556 import list to be freed when the objfile is deallocated */
557 objfile->import_list
558 = (ImportEntry *) obstack_alloc (&objfile->psymbol_obstack,
559 import_list_size * sizeof (ImportEntry));
560
561 /* Read in the import entries, a bunch at a time */
562 for (j = 0, k = 0;
563 j < (import_list_size / SOM_READ_IMPORTS_NUM);
564 j++)
565 {
566 bfd_get_section_contents (objfile->obfd, text_section, buffer,
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 }
582 }
583
584 /* Get the leftovers */
585 if (k < import_list_size)
586 bfd_get_section_contents (objfile->obfd, text_section, buffer,
587 import_list + k * sizeof (SomImportEntry),
588 (import_list_size - k) * sizeof (SomImportEntry));
589 for (i = 0; k < import_list_size; i++, k++)
590 {
591 if (buffer[i].type != (unsigned char) 0)
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 }
598 else
599 objfile->import_list[k] = NULL;
600 }
601
602 objfile->import_list_size = import_list_size;
603 xfree (string_buffer);
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. */
613 int
614 init_export_symbols (struct objfile *objfile)
615 {
616 unsigned int export_list;
617 unsigned int export_list_size;
618 unsigned int string_table;
619 unsigned int string_table_size;
620 char *string_buffer;
621 register int i;
622 register int j;
623 register int k;
624 asection *text_section; /* section handle */
625 unsigned int dl_header[12]; /* SOM executable header */
626
627 /* A struct for an entry in the SOM export list */
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)
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
649 /* It doesn't work, for some reason, to read in space $TEXT$;
650 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
651 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
652 if (!text_section)
653 return 0;
654 /* Get the SOM executable header */
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.
659 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
660 if (dl_header[0] != 93092112)
661 return 0;
662
663 export_list = dl_header[8];
664 export_list_size = dl_header[9];
665 if (!export_list_size)
666 return 0;
667 string_table = dl_header[10];
668 string_table_size = dl_header[11];
669 if (!string_table_size)
670 return 0;
671
672 /* Suck in SOM string table */
673 string_buffer = (char *) xmalloc (string_table_size);
674 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
675 string_table, string_table_size);
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
679 export list to be freed when the objfile is deallocated */
680 objfile->export_list
681 = (ExportEntry *) obstack_alloc (&objfile->psymbol_obstack,
682 export_list_size * sizeof (ExportEntry));
683
684 /* Read in the export entries, a bunch at a time */
685 for (j = 0, k = 0;
686 j < (export_list_size / SOM_READ_EXPORTS_NUM);
687 j++)
688 {
689 bfd_get_section_contents (objfile->obfd, text_section, buffer,
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 }
709 }
710
711 /* Get the leftovers */
712 if (k < export_list_size)
713 bfd_get_section_contents (objfile->obfd, text_section, buffer,
714 export_list + k * sizeof (SomExportEntry),
715 (export_list_size - k) * sizeof (SomExportEntry));
716 for (i = 0; k < export_list_size; i++, k++)
717 {
718 if (buffer[i].type != (unsigned char) 0)
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 }
726 else
727 {
728 objfile->export_list[k].name = NULL;
729 objfile->export_list[k].address = 0;
730 }
731 }
732
733 objfile->export_list_size = export_list_size;
734 xfree (string_buffer);
735 return export_list_size;
736 }
737 \f
738
739
740 /* Register that we are able to handle SOM object file formats. */
741
742 static struct sym_fns som_sym_fns =
743 {
744 bfd_target_som_flavour,
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 */
751 };
752
753 void
754 _initialize_somread (void)
755 {
756 add_symtab_fns (&som_sym_fns);
757 }
This page took 0.045734 seconds and 4 git commands to generate.