OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [somread.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.