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