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