1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / somread.c
CommitLineData
bfe2f12b 1/* Read HP PA/Risc object files for GDB.
436d4143 2 Copyright 1991, 1992, 1996 Free Software Foundation, Inc.
bfe2f12b
JL
3 Written by Fred Fish at Cygnus Support.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
6c9638b4 19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
bfe2f12b
JL
20
21#include "defs.h"
22#include "bfd.h"
bfe2f12b
JL
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"
2b576293 31#include "gdb_string.h"
bfe2f12b 32#include "demangle.h"
e618c70e
SG
33#include "som.h"
34#include "libhppa.h"
bfe2f12b 35
bfe2f12b
JL
36/* Various things we might complain about... */
37
38static void
6a86fa48 39som_symfile_init PARAMS ((struct objfile *));
bfe2f12b
JL
40
41static void
42som_new_init PARAMS ((struct objfile *));
43
44static void
45som_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
46
47static void
48som_symfile_finish PARAMS ((struct objfile *));
49
50static void
bb140953
JL
51som_symtab_read PARAMS ((bfd *, struct objfile *,
52 struct section_offsets *));
bfe2f12b 53
bfe2f12b
JL
54static struct section_offsets *
55som_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
56
3f550b59
FF
57/* FIXME: These should really be in a common header somewhere */
58
59extern void
60hpread_build_psymtabs PARAMS ((struct objfile *, struct section_offsets *, int));
61
62extern void
63hpread_symfile_finish PARAMS ((struct objfile *));
64
65extern void
66hpread_symfile_init PARAMS ((struct objfile *));
67
bfe2f12b
JL
68/*
69
70LOCAL FUNCTION
71
72 som_symtab_read -- read the symbol table of a SOM file
73
74SYNOPSIS
75
bb140953
JL
76 void som_symtab_read (bfd *abfd, struct objfile *objfile,
77 struct section_offsets *section_offsets)
bfe2f12b
JL
78
79DESCRIPTION
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
87static void
bb140953 88som_symtab_read (abfd, objfile, section_offsets)
bfe2f12b 89 bfd *abfd;
bfe2f12b 90 struct objfile *objfile;
bb140953 91 struct section_offsets *section_offsets;
bfe2f12b
JL
92{
93 unsigned int number_of_symbols;
bfe2f12b
JL
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);
506af7a7 100 CORE_ADDR text_offset, data_offset;
bb140953
JL
101
102
bb140953 103 text_offset = ANOFFSET (section_offsets, 0);
506af7a7 104 data_offset = ANOFFSET (section_offsets, 1);
bfe2f12b
JL
105
106 number_of_symbols = bfd_get_symcount (abfd);
107
108 buf = alloca (symsize * number_of_symbols);
987622b5 109 bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET);
bfe2f12b
JL
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));
987622b5 115 bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET);
bfe2f12b
JL
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. */
65b07ddc
DT
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);
bfe2f12b
JL
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;
bb140953 163 bufp->symbol_value += text_offset;
bfe2f12b
JL
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;
bb140953 178 bufp->symbol_value += text_offset;
bfe2f12b
JL
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;
bb140953 187 bufp->symbol_value += text_offset;
bfe2f12b
JL
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;
506af7a7 195 bufp->symbol_value += data_offset;
bfe2f12b
JL
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;
bb140953 217 bufp->symbol_value += text_offset;
bfe2f12b
JL
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
2097152a
JL
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. */
bfe2f12b 237 if ((symname[0] == 'L' && symname[1] == '$')
2097152a
JL
238 || (symname[0] == '$' && symname[strlen(symname) - 1] == '$')
239 || (symname[0] == 'D' && symname[1] == '$')
240 || (strncmp (symname, "$PIC", 4) == 0))
bfe2f12b
JL
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;
bb140953 249 bufp->symbol_value += text_offset;
bfe2f12b
JL
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;
bb140953 264 bufp->symbol_value += text_offset;
bfe2f12b
JL
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;
bb140953 273 bufp->symbol_value += text_offset;
bfe2f12b
JL
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;
506af7a7 282 bufp->symbol_value += data_offset;
bfe2f12b
JL
283 ms_type = mst_file_data;
284 goto check_strange_names;
285
286 default:
287 continue;
288 }
289 break;
290
5dc74605
JL
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
c149559f
JL
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. */
5dc74605
JL
297 case SS_UNSAT:
298 switch (bufp->symbol_type)
299 {
300 case ST_STORAGE:
c149559f 301 case ST_DATA:
5dc74605
JL
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
bfe2f12b
JL
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
ace4b8d7
FF
320 prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type,
321 objfile);
bfe2f12b 322 }
bfe2f12b
JL
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
354static void
355som_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;
bfe2f12b
JL
362
363 init_minimal_symbol_collection ();
364 back_to = make_cleanup (discard_minimal_symbols, 0);
365
65b07ddc
DT
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
bfe2f12b 377
65b07ddc
DT
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
bb140953 383 som_symtab_read (abfd, objfile, section_offsets);
bfe2f12b 384
65b07ddc
DT
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? */
6a86fa48
JL
389 stabsect_build_psymtabs (objfile, section_offsets, mainline,
390 "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$");
bfe2f12b 391
65b07ddc
DT
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. */
98c0e047 396 hpread_build_psymtabs (objfile, section_offsets, mainline);
98c0e047 397
6a86fa48 398 /* Install any minimal symbols that have been collected as the current
65b07ddc
DT
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. */
6a86fa48 403 install_minimal_symbols (objfile);
bfe2f12b 404
31b2518a 405 /* Force hppa-tdep.c to re-read the unwind descriptors. */
c676d827 406 objfile->obj_private = NULL;
6a86fa48 407 do_cleanups (back_to);
bfe2f12b
JL
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
416static void
417som_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
429static void
430som_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 }
98c0e047 437 hpread_symfile_finish (objfile);
bfe2f12b
JL
438}
439
436d4143 440/* SOM specific initialization routine for reading symbols. */
bfe2f12b 441
bfe2f12b 442static void
98c0e047
JL
443som_symfile_init (objfile)
444 struct objfile *objfile;
bfe2f12b 445{
436d4143
JL
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;
98c0e047 450 hpread_symfile_init (objfile);
bfe2f12b
JL
451}
452
453/* SOM specific parsing routine for section offsets.
454
455 Plain and simple for now. */
456
457static struct section_offsets *
458som_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 *)
e74acce4 467 obstack_alloc (&objfile -> psymbol_obstack, SIZEOF_SECTION_OFFSETS);
bfe2f12b 468
506af7a7
JL
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 }
bfe2f12b
JL
476
477 return section_offsets;
478}
65b07ddc
DT
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
489int 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. */
513int
514init_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. */
644int
645init_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
bfe2f12b
JL
780\f
781/* Register that we are able to handle SOM object file formats. */
782
783static 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
794void
795_initialize_somread ()
796{
797 add_symtab_fns (&som_sym_fns);
798}
This page took 0.256124 seconds and 4 git commands to generate.