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