]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/somread.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / somread.c
1 /* Read HP PA/Risc object files for GDB.
2 Copyright (C) 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
3 2004, 2007 Free Software Foundation, Inc.
4 Written by Fred Fish at Cygnus Support.
5
6 This file is part of GDB.
7
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.
12
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.
17
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., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
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 #include "solib-som.h"
39
40 /* Prototypes for local functions. */
41 static int init_import_symbols (struct objfile *objfile);
42
43 /* FIXME: These should really be in a common header somewhere */
44
45 extern void hpread_build_psymtabs (struct objfile *, int);
46
47 extern void hpread_symfile_finish (struct objfile *);
48
49 extern void hpread_symfile_init (struct objfile *);
50
51 extern void do_pxdb (bfd *);
52
53 /*
54
55 LOCAL FUNCTION
56
57 som_symtab_read -- read the symbol table of a SOM file
58
59 SYNOPSIS
60
61 void som_symtab_read (bfd *abfd, struct objfile *objfile,
62 struct section_offsets *section_offsets)
63
64 DESCRIPTION
65
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 */
71
72 static void
73 som_symtab_read (bfd *abfd, struct objfile *objfile,
74 struct section_offsets *section_offsets)
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
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);
96 bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET);
97 val = bfd_bread (buf, symsize * number_of_symbols, abfd);
98 if (val != symsize * number_of_symbols)
99 error (_("Couldn't read symbol dictionary!"));
100
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);
107 bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET);
108 val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd);
109 if (val != obj_som_stringtab_size (abfd))
110 error (_("Can't read in HP string table."));
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
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. */
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;
149 bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
150 break;
151
152 case ST_ENTRY:
153 symname = bufp->name.n_strx + stringtab;
154 /* For a dynamic executable, ST_ENTRY symbols are
155 the stubs, while the ST_CODE symbol is the real
156 function. */
157 if (dynamic)
158 ms_type = mst_solib_trampoline;
159 else
160 ms_type = mst_text;
161 bufp->symbol_value += text_offset;
162 bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
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;
169 bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
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;
197 bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
198
199 check_strange_names:
200 /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
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. */
214 if ((symname[0] == 'L' && symname[1] == '$')
215 || (symname[0] == '$' && symname[strlen (symname) - 1] == '$')
216 || (symname[0] == 'D' && symname[1] == '$')
217 || (strncmp (symname, "L0\001", 3) == 0)
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;
228 bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
229 break;
230
231 case ST_ENTRY:
232 symname = bufp->name.n_strx + stringtab;
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;
238 bufp->symbol_value += text_offset;
239 bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
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;
246 bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
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
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.
264
265 This also happens for weak symbols, but their type is
266 ST_DATA. */
267 case SS_UNSAT:
268 switch (bufp->symbol_type)
269 {
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;
279 }
280 break;
281
282 default:
283 continue;
284 }
285
286 if (bufp->name.n_strx > obj_som_stringtab_size (abfd))
287 error (_("Invalid symbol data; bad HP string table offset: %d"),
288 bufp->name.n_strx);
289
290 prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type,
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
324 static void
325 som_symfile_read (struct objfile *objfile, int mainline)
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 ();
333 back_to = make_cleanup_discard_minimal_symbols ();
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);
340 #if 0 /* Export symbols not used today 1997-08-05 */
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". */
351
352 som_symtab_read (abfd, objfile, objfile->section_offsets);
353
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
362 /* Now read information from the stabs debug sections.
363 This is emitted by gcc. */
364 stabsect_build_psymtabs (objfile, mainline,
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. */
371 hpread_build_psymtabs (objfile, mainline);
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
380 static void
381 som_new_init (struct objfile *ignore)
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
392 static void
393 som_symfile_finish (struct objfile *objfile)
394 {
395 if (objfile->deprecated_sym_stab_info != NULL)
396 {
397 xfree (objfile->deprecated_sym_stab_info);
398 }
399 hpread_symfile_finish (objfile);
400 }
401
402 /* SOM specific initialization routine for reading symbols. */
403
404 static void
405 som_symfile_init (struct objfile *objfile)
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
418 static void
419 som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
420 {
421 int i;
422 CORE_ADDR text_addr;
423
424 objfile->num_sections = bfd_count_sections (objfile->obfd);
425 objfile->section_offsets = (struct section_offsets *)
426 obstack_alloc (&objfile->objfile_obstack,
427 SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
428
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
440 /* First see if we're a shared library. If so, get the section
441 offsets from the library, else get them from addrs. */
442 if (!som_solib_section_offsets (objfile, objfile->section_offsets))
443 {
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. */
447 for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
448 if (strcmp (addrs->other[i].name, ".text") == 0)
449 break;
450 text_addr = addrs->other[i].addr;
451
452 for (i = 0; i < objfile->num_sections; i++)
453 (objfile->section_offsets)->offsets[i] = text_addr;
454 }
455 }
456
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. */
463 static int
464 init_import_symbols (struct objfile *objfile)
465 {
466 unsigned int import_list;
467 unsigned int import_list_size;
468 unsigned int string_table;
469 unsigned int string_table_size;
470 char *string_buffer;
471 int i;
472 int j;
473 int k;
474 asection *text_section; /* section handle */
475 unsigned int dl_header[12]; /* SOM executable header */
476
477 /* A struct for an entry in the SOM import list */
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)
490 SomImportEntry buffer[SOM_READ_IMPORTS_NUM];
491
492 /* Initialize in case we error out */
493 objfile->import_list = NULL;
494 objfile->import_list_size = 0;
495
496 /* It doesn't work, for some reason, to read in space $TEXT$;
497 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
498 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
499 if (!text_section)
500 return 0;
501 /* Get the SOM executable header */
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.
506 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
507 if (dl_header[0] != 93092112)
508 return 0;
509
510 import_list = dl_header[4];
511 import_list_size = dl_header[5];
512 if (!import_list_size)
513 return 0;
514 string_table = dl_header[10];
515 string_table_size = dl_header[11];
516 if (!string_table_size)
517 return 0;
518
519 /* Suck in SOM string table */
520 string_buffer = (char *) xmalloc (string_table_size);
521 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
522 string_table, string_table_size);
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
526 import list to be freed when the objfile is deallocated */
527 objfile->import_list
528 = (ImportEntry *) obstack_alloc (&objfile->objfile_obstack,
529 import_list_size * sizeof (ImportEntry));
530
531 /* Read in the import entries, a bunch at a time */
532 for (j = 0, k = 0;
533 j < (import_list_size / SOM_READ_IMPORTS_NUM);
534 j++)
535 {
536 bfd_get_section_contents (objfile->obfd, text_section, buffer,
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]
544 = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1);
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 }
552 }
553
554 /* Get the leftovers */
555 if (k < import_list_size)
556 bfd_get_section_contents (objfile->obfd, text_section, buffer,
557 import_list + k * sizeof (SomImportEntry),
558 (import_list_size - k) * sizeof (SomImportEntry));
559 for (i = 0; k < import_list_size; i++, k++)
560 {
561 if (buffer[i].type != (unsigned char) 0)
562 {
563 objfile->import_list[k]
564 = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1);
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 }
568 else
569 objfile->import_list[k] = NULL;
570 }
571
572 objfile->import_list_size = import_list_size;
573 xfree (string_buffer);
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. */
583 int
584 init_export_symbols (struct objfile *objfile)
585 {
586 unsigned int export_list;
587 unsigned int export_list_size;
588 unsigned int string_table;
589 unsigned int string_table_size;
590 char *string_buffer;
591 int i;
592 int j;
593 int k;
594 asection *text_section; /* section handle */
595 unsigned int dl_header[12]; /* SOM executable header */
596
597 /* A struct for an entry in the SOM export list */
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)
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
619 /* It doesn't work, for some reason, to read in space $TEXT$;
620 the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
621 text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
622 if (!text_section)
623 return 0;
624 /* Get the SOM executable header */
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.
629 FIXME: Change for future HP-UX releases and mods to the SOM executable format */
630 if (dl_header[0] != 93092112)
631 return 0;
632
633 export_list = dl_header[8];
634 export_list_size = dl_header[9];
635 if (!export_list_size)
636 return 0;
637 string_table = dl_header[10];
638 string_table_size = dl_header[11];
639 if (!string_table_size)
640 return 0;
641
642 /* Suck in SOM string table */
643 string_buffer = (char *) xmalloc (string_table_size);
644 bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
645 string_table, string_table_size);
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
649 export list to be freed when the objfile is deallocated */
650 objfile->export_list
651 = (ExportEntry *) obstack_alloc (&objfile->objfile_obstack,
652 export_list_size * sizeof (ExportEntry));
653
654 /* Read in the export entries, a bunch at a time */
655 for (j = 0, k = 0;
656 j < (export_list_size / SOM_READ_EXPORTS_NUM);
657 j++)
658 {
659 bfd_get_section_contents (objfile->obfd, text_section, buffer,
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
667 = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1);
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 }
679 }
680
681 /* Get the leftovers */
682 if (k < export_list_size)
683 bfd_get_section_contents (objfile->obfd, text_section, buffer,
684 export_list + k * sizeof (SomExportEntry),
685 (export_list_size - k) * sizeof (SomExportEntry));
686 for (i = 0; k < export_list_size; i++, k++)
687 {
688 if (buffer[i].type != (unsigned char) 0)
689 {
690 objfile->export_list[k].name
691 = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1);
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 }
696 else
697 {
698 objfile->export_list[k].name = NULL;
699 objfile->export_list[k].address = 0;
700 }
701 }
702
703 objfile->export_list_size = export_list_size;
704 xfree (string_buffer);
705 return export_list_size;
706 }
707 \f
708
709
710 /* Register that we are able to handle SOM object file formats. */
711
712 static struct sym_fns som_sym_fns =
713 {
714 bfd_target_som_flavour,
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 */
721 };
722
723 void
724 _initialize_somread (void)
725 {
726 add_symtab_fns (&som_sym_fns);
727 }