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