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