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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [somread.c] - Blame information for rev 104

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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