~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/hp300hpux.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* BFD backend for hp-ux 9000/300
 
2
   Copyright 1990, 1991, 1993, 1994, 1995, 1997, 2000, 2001
 
3
   Free Software Foundation, Inc.
 
4
   Written by Glenn Engel.
 
5
 
 
6
This file is part of BFD, the Binary File Descriptor library.
 
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, Boston, MA 02111-1307, USA.  */
 
21
 
 
22
/*
 
23
    hpux native  ------------> |               |
 
24
                               | hp300hpux bfd | ----------> hpux w/gnu ext
 
25
    hpux w/gnu extension ----> |               |
 
26
 
 
27
    Support for the 9000/[34]00 has several limitations.
 
28
      1. Shared libraries are not supported.
 
29
      2. The output format from this bfd is not usable by native tools.
 
30
 
 
31
    The primary motivation for writing this bfd was to allow use of
 
32
    gdb and gcc for host based debugging and not to mimic the hp-ux tools
 
33
    in every detail.  This leads to a significant simplification of the
 
34
    code and a leap in performance.  The decision to not output hp native
 
35
    compatible objects was further strengthened by the fact that the richness
 
36
    of the gcc compiled objects could not be represented without loss of
 
37
    information.  For example, while the hp format supports the concept of
 
38
    secondary symbols, it does not support indirect symbols.  Another
 
39
    reason is to maintain backwards compatibility with older implementations
 
40
    of gcc on hpux which used 'hpxt' to translate .a and .o files into a
 
41
    format which could be readily understood by the gnu linker and gdb.
 
42
    This allows reading hp secondary symbols and converting them into
 
43
    indirect symbols but the reverse it not always possible.
 
44
 
 
45
    Another example of differences is that the hp format stores symbol offsets
 
46
    in the object code while the gnu utilities use a field in the
 
47
    relocation record for this.  To support the hp native format, the object
 
48
    code would need to be patched with the offsets when producing .o files.
 
49
 
 
50
    The basic technique taken in this implementation is to #include the code
 
51
    from aoutx.h and aout-target.h with appropriate #defines to override
 
52
    code where a unique implementation is needed:
 
53
 
 
54
    {
 
55
        #define a bunch of stuff
 
56
        #include <aoutx.h>
 
57
 
 
58
        implement a bunch of functions
 
59
 
 
60
        #include "aout-target.h"
 
61
    }
 
62
 
 
63
    The hp symbol table is a bit different than other a.out targets.  Instead
 
64
    of having an array of nlist items and an array of strings, hp's format
 
65
    has them mixed together in one structure.  In addition, the strings are
 
66
    not null terminated.  It looks something like this:
 
67
 
 
68
    nlist element 1
 
69
    string1
 
70
    nlist element 2
 
71
    string2
 
72
    ...
 
73
 
 
74
    The whole symbol table is read as one chunk and then we march thru it
 
75
    and convert it to canonical form.  As we march thru the table, we copy
 
76
    the nlist data into the internal form and we compact the strings and null
 
77
    terminate them, using storage from the already allocated symbol table:
 
78
 
 
79
    string1
 
80
    null
 
81
    string2
 
82
    null
 
83
 */
 
84
 
 
85
/* @@ Is this really so different from normal a.out that it needs to include
 
86
   aoutx.h?  We should go through this file sometime and see what can be made
 
87
   more dependent on aout32.o and what might need to be broken off and accessed
 
88
   through the backend_data field.  Or, maybe we really do need such a
 
89
   completely separate implementation.  I don't have time to investigate this
 
90
   much further right now.  [raeburn:19930428.2124EST] */
 
91
/* @@ Also, note that there wind up being two versions of some routines, with
 
92
   different names, only one of which actually gets used.  For example:
 
93
        slurp_symbol_table
 
94
        swap_std_reloc_in
 
95
        slurp_reloc_table
 
96
        get_symtab
 
97
        get_symtab_upper_bound
 
98
        canonicalize_reloc
 
99
        mkobject
 
100
   This should also be fixed.  */
 
101
 
 
102
#define TARGETNAME "a.out-hp300hpux"
 
103
 
 
104
/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
 
105
   remove whitespace added here, and thus will fail to concatenate
 
106
   the tokens.  */
 
107
#define MY(OP) CONCAT2 (hp300hpux_,OP)
 
108
 
 
109
#define external_exec hp300hpux_exec_bytes
 
110
#define external_nlist hp300hpux_nlist_bytes
 
111
 
 
112
#include "aout/hp300hpux.h"
 
113
 
 
114
/* define these so we can compile unused routines in aoutx.h */
 
115
#define e_strx  e_shlib
 
116
#define e_other e_length
 
117
#define e_desc  e_almod
 
118
 
 
119
#define AR_PAD_CHAR '/'
 
120
#define TARGET_IS_BIG_ENDIAN_P
 
121
#define DEFAULT_ARCH bfd_arch_m68k
 
122
 
 
123
#define MY_get_section_contents aout_32_get_section_contents
 
124
#define MY_slurp_armap bfd_slurp_bsd_armap_f2
 
125
 
 
126
/***********************************************/
 
127
/* provide overrides for routines in this file */
 
128
/***********************************************/
 
129
/* these don't use MY because that causes problems within JUMP_TABLE
 
130
   (CONCAT2 winds up being expanded recursively, which ANSI C compilers
 
131
   will not do).  */
 
132
#define MY_get_symtab hp300hpux_get_symtab
 
133
#define MY_get_symtab_upper_bound hp300hpux_get_symtab_upper_bound
 
134
#define MY_canonicalize_reloc hp300hpux_canonicalize_reloc
 
135
#define MY_write_object_contents hp300hpux_write_object_contents
 
136
 
 
137
#define MY_read_minisymbols _bfd_generic_read_minisymbols
 
138
#define MY_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
 
139
 
 
140
#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
 
141
#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
 
142
#define MY_final_link_callback unused
 
143
#define MY_bfd_final_link _bfd_generic_final_link
 
144
 
 
145
/* Until and unless we convert the slurp_reloc and slurp_symtab
 
146
   routines in this file, we can not use the default aout
 
147
   free_cached_info routine which assumes that the relocs and symtabs
 
148
   were allocated using malloc.  */
 
149
#define MY_bfd_free_cached_info bfd_true
 
150
 
 
151
#define hp300hpux_write_syms aout_32_write_syms
 
152
 
 
153
#define MY_callback MY(callback)
 
154
 
 
155
#define MY_exec_hdr_flags 0x2
 
156
 
 
157
#define NAME_swap_exec_header_in NAME(hp300hpux_32_,swap_exec_header_in)
 
158
 
 
159
#define HP_SYMTYPE_UNDEFINED    0x00
 
160
#define HP_SYMTYPE_ABSOLUTE     0x01
 
161
#define HP_SYMTYPE_TEXT         0x02
 
162
#define HP_SYMTYPE_DATA         0x03
 
163
#define HP_SYMTYPE_BSS          0x04
 
164
#define HP_SYMTYPE_COMMON       0x05
 
165
 
 
166
#define HP_SYMTYPE_TYPE         0x0F
 
167
#define HP_SYMTYPE_FILENAME     0x1F
 
168
 
 
169
#define HP_SYMTYPE_ALIGN        0x10
 
170
#define HP_SYMTYPE_EXTERNAL     0x20
 
171
#define HP_SECONDARY_SYMBOL     0x40
 
172
 
 
173
/* RELOCATION DEFINITIONS */
 
174
#define HP_RSEGMENT_TEXT        0x00
 
175
#define HP_RSEGMENT_DATA        0x01
 
176
#define HP_RSEGMENT_BSS         0x02
 
177
#define HP_RSEGMENT_EXTERNAL    0x03
 
178
#define HP_RSEGMENT_PCREL       0x04
 
179
#define HP_RSEGMENT_RDLT        0x05
 
180
#define HP_RSEGMENT_RPLT        0x06
 
181
#define HP_RSEGMENT_NOOP        0x3F
 
182
 
 
183
#define HP_RLENGTH_BYTE         0x00
 
184
#define HP_RLENGTH_WORD         0x01
 
185
#define HP_RLENGTH_LONG         0x02
 
186
#define HP_RLENGTH_ALIGN        0x03
 
187
 
 
188
#define NAME(x,y) CONCAT3 (hp300hpux,_32_,y)
 
189
#define ARCH_SIZE 32
 
190
 
 
191
/* aoutx.h requires definitions for BMAGIC and QMAGIC.  */
 
192
#define BMAGIC HPUX_DOT_O_MAGIC
 
193
#define QMAGIC 0314
 
194
 
 
195
#include "aoutx.h"
 
196
 
 
197
static const bfd_target * MY (callback) PARAMS ((bfd *));
 
198
static boolean            MY (write_object_contents) PARAMS ((bfd *));
 
199
static void               convert_sym_type PARAMS ((struct external_nlist *, aout_symbol_type *, bfd *));
 
200
 
 
201
boolean                   MY (slurp_symbol_table) PARAMS ((bfd *));
 
202
void                      MY (swap_std_reloc_in) PARAMS ((bfd *, struct hp300hpux_reloc *, arelent *, asymbol **, bfd_size_type));
 
203
boolean                   MY (slurp_reloc_table) PARAMS ((bfd *, sec_ptr, asymbol **));
 
204
long                      MY (get_symtab) PARAMS ((bfd *, asymbol **));
 
205
long                      MY (get_symtab_upper_bound) PARAMS ((bfd *));
 
206
long                      MY (canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
 
207
 
 
208
/* Since the hpux symbol table has nlist elements interspersed with
 
209
   strings and we need to insert som strings for secondary symbols, we
 
210
   give ourselves a little extra padding up front to account for
 
211
   this.  Note that for each non-secondary symbol we process, we gain
 
212
   9 bytes of space for the discarded nlist element (one byte used for
 
213
   null).  SYM_EXTRA_BYTES is the extra space.  */
 
214
#define SYM_EXTRA_BYTES   1024
 
215
 
 
216
/* Set parameters about this a.out file that are machine-dependent.
 
217
   This routine is called from some_aout_object_p just before it returns.  */
 
218
static const bfd_target *
 
219
MY (callback) (abfd)
 
220
     bfd *abfd;
 
221
{
 
222
  struct internal_exec *execp = exec_hdr (abfd);
 
223
 
 
224
  /* Calculate the file positions of the parts of a newly read aout header */
 
225
  obj_textsec (abfd)->_raw_size = N_TXTSIZE (*execp);
 
226
 
 
227
  /* The virtual memory addresses of the sections */
 
228
  obj_textsec (abfd)->vma = N_TXTADDR (*execp);
 
229
  obj_datasec (abfd)->vma = N_DATADDR (*execp);
 
230
  obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
 
231
 
 
232
  obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
 
233
  obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
 
234
  obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
 
235
 
 
236
  /* The file offsets of the sections */
 
237
  obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
 
238
  obj_datasec (abfd)->filepos = N_DATOFF (*execp);
 
239
 
 
240
  /* The file offsets of the relocation info */
 
241
  obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
 
242
  obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
 
243
 
 
244
  /* The file offsets of the string table and symbol table.  */
 
245
  obj_sym_filepos (abfd) = N_SYMOFF (*execp);
 
246
  obj_str_filepos (abfd) = N_STROFF (*execp);
 
247
 
 
248
  /* Determine the architecture and machine type of the object file.  */
 
249
#ifdef SET_ARCH_MACH
 
250
  SET_ARCH_MACH (abfd, *execp);
 
251
#else
 
252
  bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0);
 
253
#endif
 
254
 
 
255
  if (obj_aout_subformat (abfd) == gnu_encap_format)
 
256
    {
 
257
      /* The file offsets of the relocation info */
 
258
      obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp);
 
259
      obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp);
 
260
 
 
261
      /* The file offsets of the string table and symbol table.  */
 
262
      obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp);
 
263
      obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms);
 
264
 
 
265
      abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
 
266
      bfd_get_symcount (abfd) = execp->a_syms / 12;
 
267
      obj_symbol_entry_size (abfd) = 12;
 
268
      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
 
269
    }
 
270
 
 
271
  return abfd->xvec;
 
272
}
 
273
 
 
274
extern boolean aout_32_write_syms PARAMS ((bfd * abfd));
 
275
 
 
276
static boolean
 
277
MY (write_object_contents) (abfd)
 
278
     bfd *abfd;
 
279
{
 
280
  struct external_exec exec_bytes;
 
281
  struct internal_exec *execp = exec_hdr (abfd);
 
282
  bfd_size_type text_size;      /* dummy vars */
 
283
  file_ptr text_end;
 
284
 
 
285
  memset (&exec_bytes, 0, sizeof (exec_bytes));
 
286
 
 
287
  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
 
288
 
 
289
  if (adata (abfd).magic == undecided_magic)
 
290
    NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
 
291
  execp->a_syms = 0;
 
292
 
 
293
  execp->a_entry = bfd_get_start_address (abfd);
 
294
 
 
295
  execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
 
296
                     obj_reloc_entry_size (abfd));
 
297
  execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
 
298
                     obj_reloc_entry_size (abfd));
 
299
 
 
300
  N_SET_MACHTYPE (*execp, 0xc);
 
301
  N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
 
302
 
 
303
  NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes);
 
304
 
 
305
  /* update fields not covered by default swap_exec_header_out */
 
306
 
 
307
  /* this is really the sym table size but we store it in drelocs */
 
308
  H_PUT_32 (abfd, (bfd_get_symcount (abfd) * 12), exec_bytes.e_drelocs);
 
309
 
 
310
  if (bfd_seek (abfd, (file_ptr) 0, false) != 0
 
311
      || (bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
 
312
          != EXEC_BYTES_SIZE))
 
313
    return false;
 
314
 
 
315
  /* Write out the symbols, and then the relocs.  We must write out
 
316
       the symbols first so that we know the symbol indices.  */
 
317
 
 
318
  if (bfd_get_symcount (abfd) != 0)
 
319
    {
 
320
      /* Skip the relocs to where we want to put the symbols.  */
 
321
      if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp) + execp->a_drsize),
 
322
                    SEEK_SET) != 0)
 
323
        return false;
 
324
    }
 
325
 
 
326
  if (!MY (write_syms) (abfd))
 
327
    return false;
 
328
 
 
329
  if (bfd_get_symcount (abfd) != 0)
 
330
    {
 
331
      if (bfd_seek (abfd, (file_ptr) N_TRELOFF (*execp), SEEK_CUR) != 0)
 
332
        return false;
 
333
      if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd)))
 
334
        return false;
 
335
      if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp), SEEK_CUR) != 0)
 
336
        return false;
 
337
      if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))
 
338
        return false;
 
339
    }
 
340
 
 
341
  return true;
 
342
}
 
343
 
 
344
/* convert the hp symbol type to be the same as aout64.h usage so we */
 
345
/* can piggyback routines in aoutx.h.                                */
 
346
 
 
347
static void
 
348
convert_sym_type (sym_pointer, cache_ptr, abfd)
 
349
     struct external_nlist *sym_pointer ATTRIBUTE_UNUSED;
 
350
     aout_symbol_type *cache_ptr;
 
351
     bfd *abfd ATTRIBUTE_UNUSED;
 
352
{
 
353
  int name_type;
 
354
  int new_type;
 
355
 
 
356
  name_type = (cache_ptr->type);
 
357
  new_type = 0;
 
358
 
 
359
  if ((name_type & HP_SYMTYPE_ALIGN) != 0)
 
360
    {
 
361
      /* iou_error ("aligned symbol encountered: %s", name);*/
 
362
      name_type = 0;
 
363
    }
 
364
 
 
365
  if (name_type == HP_SYMTYPE_FILENAME)
 
366
    new_type = N_FN;
 
367
  else
 
368
    {
 
369
      switch (name_type & HP_SYMTYPE_TYPE)
 
370
        {
 
371
        case HP_SYMTYPE_UNDEFINED:
 
372
          new_type = N_UNDF;
 
373
          break;
 
374
 
 
375
        case HP_SYMTYPE_ABSOLUTE:
 
376
          new_type = N_ABS;
 
377
          break;
 
378
 
 
379
        case HP_SYMTYPE_TEXT:
 
380
          new_type = N_TEXT;
 
381
          break;
 
382
 
 
383
        case HP_SYMTYPE_DATA:
 
384
          new_type = N_DATA;
 
385
          break;
 
386
 
 
387
        case HP_SYMTYPE_BSS:
 
388
          new_type = N_BSS;
 
389
          break;
 
390
 
 
391
        case HP_SYMTYPE_COMMON:
 
392
          new_type = N_COMM;
 
393
          break;
 
394
 
 
395
        default:
 
396
          abort ();
 
397
          break;
 
398
        }
 
399
      if (name_type & HP_SYMTYPE_EXTERNAL)
 
400
        new_type |= N_EXT;
 
401
 
 
402
      if (name_type & HP_SECONDARY_SYMBOL)
 
403
        {
 
404
          switch (new_type)
 
405
            {
 
406
            default:
 
407
              abort ();
 
408
            case N_UNDF | N_EXT:
 
409
              /* If the value is nonzero, then just treat this as a
 
410
                 common symbol.  I don't know if this is correct in
 
411
                 all cases, but it is more correct than treating it as
 
412
                 a weak undefined symbol.  */
 
413
              if (cache_ptr->symbol.value == 0)
 
414
                new_type = N_WEAKU;
 
415
              break;
 
416
            case N_ABS | N_EXT:
 
417
              new_type = N_WEAKA;
 
418
              break;
 
419
            case N_TEXT | N_EXT:
 
420
              new_type = N_WEAKT;
 
421
              break;
 
422
            case N_DATA | N_EXT:
 
423
              new_type = N_WEAKD;
 
424
              break;
 
425
            case N_BSS | N_EXT:
 
426
              new_type = N_WEAKB;
 
427
              break;
 
428
            }
 
429
        }
 
430
    }
 
431
  cache_ptr->type = new_type;
 
432
 
 
433
}
 
434
 
 
435
/*
 
436
DESCRIPTION
 
437
        Swaps the information in an executable header taken from a raw
 
438
        byte stream memory image, into the internal exec_header
 
439
        structure.
 
440
*/
 
441
 
 
442
void
 
443
NAME (aout,swap_exec_header_in) (abfd, raw_bytes, execp)
 
444
     bfd *abfd;
 
445
     struct external_exec *raw_bytes;
 
446
     struct internal_exec *execp;
 
447
{
 
448
  struct external_exec *bytes = (struct external_exec *) raw_bytes;
 
449
 
 
450
  /* The internal_exec structure has some fields that are unused in this
 
451
     configuration (IE for i960), so ensure that all such uninitialized
 
452
     fields are zero'd out.  There are places where two of these structs
 
453
     are memcmp'd, and thus the contents do matter. */
 
454
  memset (execp, 0, sizeof (struct internal_exec));
 
455
  /* Now fill in fields in the execp, from the bytes in the raw data.  */
 
456
  execp->a_info = H_GET_32 (abfd, bytes->e_info);
 
457
  execp->a_text = GET_WORD (abfd, bytes->e_text);
 
458
  execp->a_data = GET_WORD (abfd, bytes->e_data);
 
459
  execp->a_bss = GET_WORD (abfd, bytes->e_bss);
 
460
  execp->a_syms = GET_WORD (abfd, bytes->e_syms);
 
461
  execp->a_entry = GET_WORD (abfd, bytes->e_entry);
 
462
  execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
 
463
  execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
 
464
 
 
465
  /***************************************************************/
 
466
  /* check the header to see if it was generated by a bfd output */
 
467
  /* this is detected rather bizarely by requiring a bunch of    */
 
468
  /* header fields to be zero and an old unused field (now used) */
 
469
  /* to be set.                                                  */
 
470
  /***************************************************************/
 
471
  do
 
472
    {
 
473
      long syms;
 
474
      struct aout_data_struct *rawptr;
 
475
      bfd_size_type amt;
 
476
 
 
477
      if (H_GET_32 (abfd, bytes->e_passize) != 0)
 
478
        break;
 
479
      if (H_GET_32 (abfd, bytes->e_syms) != 0)
 
480
        break;
 
481
      if (H_GET_32 (abfd, bytes->e_supsize) != 0)
 
482
        break;
 
483
 
 
484
      syms = H_GET_32 (abfd, bytes->e_drelocs);
 
485
      if (syms == 0)
 
486
        break;
 
487
 
 
488
      /* OK, we've passed the test as best as we can determine */
 
489
      execp->a_syms = syms;
 
490
 
 
491
      /* allocate storage for where we will store this result */
 
492
      amt = sizeof (*rawptr);
 
493
      rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
 
494
 
 
495
      if (rawptr == NULL)
 
496
        return;
 
497
      abfd->tdata.aout_data = rawptr;
 
498
      obj_aout_subformat (abfd) = gnu_encap_format;
 
499
    }
 
500
  while (0);
 
501
}
 
502
 
 
503
/* The hp symbol table is a bit different than other a.out targets.  Instead
 
504
   of having an array of nlist items and an array of strings, hp's format
 
505
   has them mixed together in one structure.  In addition, the strings are
 
506
   not null terminated.  It looks something like this:
 
507
 
 
508
   nlist element 1
 
509
   string1
 
510
   nlist element 2
 
511
   string2
 
512
   ...
 
513
 
 
514
   The whole symbol table is read as one chunk and then we march thru it
 
515
   and convert it to canonical form.  As we march thru the table, we copy
 
516
   the nlist data into the internal form and we compact the strings and null
 
517
   terminate them, using storage from the already allocated symbol table:
 
518
 
 
519
   string1
 
520
   null
 
521
   string2
 
522
   null
 
523
   ...
 
524
*/
 
525
 
 
526
boolean
 
527
MY (slurp_symbol_table) (abfd)
 
528
     bfd *abfd;
 
529
{
 
530
  bfd_size_type symbol_bytes;
 
531
  struct external_nlist *syms;
 
532
  struct external_nlist *sym_pointer;
 
533
  struct external_nlist *sym_end;
 
534
  char *strings;
 
535
  aout_symbol_type *cached;
 
536
  unsigned num_syms = 0;
 
537
  bfd_size_type amt;
 
538
 
 
539
  /* If there's no work to be done, don't do any */
 
540
  if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
 
541
    return true;
 
542
  symbol_bytes = exec_hdr (abfd)->a_syms;
 
543
 
 
544
  amt = symbol_bytes + SYM_EXTRA_BYTES;
 
545
  strings = (char *) bfd_alloc (abfd, amt);
 
546
  if (!strings)
 
547
    return false;
 
548
  syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES);
 
549
  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
 
550
      || bfd_bread ((PTR) syms, symbol_bytes, abfd) != symbol_bytes)
 
551
    {
 
552
      bfd_release (abfd, syms);
 
553
      return false;
 
554
    }
 
555
 
 
556
  sym_end = (struct external_nlist *) (((char *) syms) + symbol_bytes);
 
557
 
 
558
  /* first, march thru the table and figure out how many symbols there are */
 
559
  for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++, num_syms++)
 
560
    {
 
561
      /* skip over the embedded symbol. */
 
562
      sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
 
563
                                               sym_pointer->e_length[0]);
 
564
    }
 
565
 
 
566
  /* now that we know the symbol count, update the bfd header */
 
567
  bfd_get_symcount (abfd) = num_syms;
 
568
 
 
569
  amt = num_syms;
 
570
  amt *= sizeof (aout_symbol_type);
 
571
  cached = (aout_symbol_type *) bfd_zalloc (abfd, amt);
 
572
  if (cached == NULL && num_syms != 0)
 
573
    return false;
 
574
 
 
575
  /* as we march thru the hp symbol table, convert it into a list of
 
576
     null terminated strings to hold the symbol names.  Make sure any
 
577
     assignment to the strings pointer is done after we're thru using
 
578
     the nlist so we don't overwrite anything important. */
 
579
 
 
580
  /* OK, now walk the new symtable, cacheing symbol properties */
 
581
  {
 
582
    aout_symbol_type *cache_ptr = cached;
 
583
    aout_symbol_type cache_save;
 
584
    /* Run through table and copy values */
 
585
    for (sym_pointer = syms, cache_ptr = cached;
 
586
         sym_pointer < sym_end; sym_pointer++, cache_ptr++)
 
587
      {
 
588
        unsigned int length;
 
589
        cache_ptr->symbol.the_bfd = abfd;
 
590
        cache_ptr->symbol.value = GET_SWORD (abfd, sym_pointer->e_value);
 
591
        cache_ptr->desc = bfd_get_16 (abfd, sym_pointer->e_almod);
 
592
        cache_ptr->type = bfd_get_8 (abfd, sym_pointer->e_type);
 
593
        cache_ptr->symbol.udata.p = NULL;
 
594
        length = bfd_get_8 (abfd, sym_pointer->e_length);
 
595
        cache_ptr->other = length;      /* other not used, save length here */
 
596
 
 
597
        cache_save = *cache_ptr;
 
598
        convert_sym_type (sym_pointer, cache_ptr, abfd);
 
599
        if (!translate_from_native_sym_flags (abfd, cache_ptr))
 
600
          return false;
 
601
 
 
602
        /********************************************************/
 
603
        /* for hpux, the 'lenght' value indicates the length of */
 
604
        /* the symbol name which follows the nlist entry.       */
 
605
        /********************************************************/
 
606
        if (length)
 
607
          {
 
608
            /**************************************************************/
 
609
            /* the hp string is not null terminated so we create a new one*/
 
610
            /* by copying the string to overlap the just vacated nlist    */
 
611
            /* structure before it in memory.                             */
 
612
            /**************************************************************/
 
613
            cache_ptr->symbol.name = strings;
 
614
            memcpy (strings, sym_pointer + 1, length);
 
615
            strings[length] = '\0';
 
616
            strings += length + 1;
 
617
          }
 
618
        else
 
619
          cache_ptr->symbol.name = (char *) NULL;
 
620
 
 
621
        /* skip over the embedded symbol. */
 
622
        sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
 
623
                                                 length);
 
624
      }
 
625
  }
 
626
 
 
627
  obj_aout_symbols (abfd) = cached;
 
628
 
 
629
  return true;
 
630
}
 
631
 
 
632
void
 
633
MY (swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
 
634
     bfd *abfd;
 
635
     struct hp300hpux_reloc *bytes;
 
636
     arelent *cache_ptr;
 
637
     asymbol **symbols;
 
638
     bfd_size_type symcount ATTRIBUTE_UNUSED;
 
639
{
 
640
  int r_index;
 
641
  int r_extern = 0;
 
642
  unsigned int r_length;
 
643
  int r_pcrel = 0;
 
644
  struct aoutdata *su = &(abfd->tdata.aout_data->a);
 
645
 
 
646
  cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
 
647
  r_index = H_GET_16 (abfd, bytes->r_index);
 
648
 
 
649
  switch (bytes->r_type[0])
 
650
    {
 
651
    case HP_RSEGMENT_TEXT:
 
652
      r_index = N_TEXT;
 
653
      break;
 
654
    case HP_RSEGMENT_DATA:
 
655
      r_index = N_DATA;
 
656
      break;
 
657
    case HP_RSEGMENT_BSS:
 
658
      r_index = N_BSS;
 
659
      break;
 
660
    case HP_RSEGMENT_EXTERNAL:
 
661
      r_extern = 1;
 
662
      break;
 
663
    case HP_RSEGMENT_PCREL:
 
664
      r_extern = 1;
 
665
      r_pcrel = 1;
 
666
      break;
 
667
    case HP_RSEGMENT_RDLT:
 
668
      break;
 
669
    case HP_RSEGMENT_RPLT:
 
670
      break;
 
671
    case HP_RSEGMENT_NOOP:
 
672
      break;
 
673
    default:
 
674
      abort ();
 
675
      break;
 
676
    }
 
677
 
 
678
  switch (bytes->r_length[0])
 
679
    {
 
680
    case HP_RLENGTH_BYTE:
 
681
      r_length = 0;
 
682
      break;
 
683
    case HP_RLENGTH_WORD:
 
684
      r_length = 1;
 
685
      break;
 
686
    case HP_RLENGTH_LONG:
 
687
      r_length = 2;
 
688
      break;
 
689
    default:
 
690
      abort ();
 
691
      break;
 
692
    }
 
693
 
 
694
  cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
 
695
  /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
 
696
 
 
697
  /* This macro uses the r_index value computed above */
 
698
  if (r_pcrel && r_extern)
 
699
    {
 
700
      /* The GNU linker assumes any offset from beginning of section */
 
701
      /* is already incorporated into the image while the HP linker  */
 
702
      /* adds this in later.  Add it in now...                       */
 
703
      MOVE_ADDRESS (-cache_ptr->address);
 
704
    }
 
705
  else
 
706
    {
 
707
      MOVE_ADDRESS (0);
 
708
    }
 
709
}
 
710
 
 
711
boolean
 
712
MY (slurp_reloc_table) (abfd, asect, symbols)
 
713
     bfd *abfd;
 
714
     sec_ptr asect;
 
715
     asymbol **symbols;
 
716
{
 
717
  bfd_size_type count;
 
718
  bfd_size_type reloc_size;
 
719
  PTR relocs;
 
720
  arelent *reloc_cache;
 
721
  size_t each_size;
 
722
  struct hp300hpux_reloc *rptr;
 
723
  unsigned int counter;
 
724
  arelent *cache_ptr;
 
725
 
 
726
  if (asect->relocation)
 
727
    return true;
 
728
 
 
729
  if (asect->flags & SEC_CONSTRUCTOR)
 
730
    return true;
 
731
 
 
732
  if (asect == obj_datasec (abfd))
 
733
    {
 
734
      reloc_size = exec_hdr (abfd)->a_drsize;
 
735
      goto doit;
 
736
    }
 
737
 
 
738
  if (asect == obj_textsec (abfd))
 
739
    {
 
740
      reloc_size = exec_hdr (abfd)->a_trsize;
 
741
      goto doit;
 
742
    }
 
743
 
 
744
  bfd_set_error (bfd_error_invalid_operation);
 
745
  return false;
 
746
 
 
747
doit:
 
748
  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
 
749
    return false;
 
750
  each_size = obj_reloc_entry_size (abfd);
 
751
 
 
752
  count = reloc_size / each_size;
 
753
 
 
754
  reloc_cache = (arelent *) bfd_zalloc (abfd, count * sizeof (arelent));
 
755
  if (!reloc_cache && count != 0)
 
756
    return false;
 
757
 
 
758
  relocs = (PTR) bfd_alloc (abfd, reloc_size);
 
759
  if (!relocs && reloc_size != 0)
 
760
    {
 
761
      bfd_release (abfd, reloc_cache);
 
762
      return false;
 
763
    }
 
764
 
 
765
  if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
 
766
    {
 
767
      bfd_release (abfd, relocs);
 
768
      bfd_release (abfd, reloc_cache);
 
769
      return false;
 
770
    }
 
771
 
 
772
  rptr = (struct hp300hpux_reloc *) relocs;
 
773
  counter = 0;
 
774
  cache_ptr = reloc_cache;
 
775
 
 
776
  for (; counter < count; counter++, rptr++, cache_ptr++)
 
777
    {
 
778
      MY (swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
 
779
                              (bfd_size_type) bfd_get_symcount (abfd));
 
780
    }
 
781
 
 
782
  bfd_release (abfd, relocs);
 
783
  asect->relocation = reloc_cache;
 
784
  asect->reloc_count = count;
 
785
  return true;
 
786
}
 
787
 
 
788
/************************************************************************/
 
789
/* The following functions are identical to functions in aoutx.h except */
 
790
/* they refer to MY(func) rather than NAME(aout,func) and they also     */
 
791
/* call aout_32 versions if the input file was generated by gcc         */
 
792
/************************************************************************/
 
793
 
 
794
long aout_32_get_symtab PARAMS ((bfd * abfd, asymbol ** location));
 
795
long aout_32_get_symtab_upper_bound PARAMS ((bfd * abfd));
 
796
 
 
797
long aout_32_canonicalize_reloc PARAMS ((bfd * abfd, sec_ptr section,
 
798
                                         arelent ** relptr,
 
799
                                         asymbol ** symbols));
 
800
 
 
801
long
 
802
MY (get_symtab) (abfd, location)
 
803
     bfd *abfd;
 
804
     asymbol **location;
 
805
{
 
806
  unsigned int counter = 0;
 
807
  aout_symbol_type *symbase;
 
808
 
 
809
  if (obj_aout_subformat (abfd) == gnu_encap_format)
 
810
    return aout_32_get_symtab (abfd, location);
 
811
 
 
812
  if (!MY (slurp_symbol_table) (abfd))
 
813
    return -1;
 
814
 
 
815
  for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
 
816
    *(location++) = (asymbol *) (symbase++);
 
817
  *location++ = 0;
 
818
  return bfd_get_symcount (abfd);
 
819
}
 
820
 
 
821
long
 
822
MY (get_symtab_upper_bound) (abfd)
 
823
     bfd *abfd;
 
824
{
 
825
  if (obj_aout_subformat (abfd) == gnu_encap_format)
 
826
    return aout_32_get_symtab_upper_bound (abfd);
 
827
  if (!MY (slurp_symbol_table) (abfd))
 
828
    return -1;
 
829
 
 
830
  return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
 
831
}
 
832
 
 
833
long
 
834
MY (canonicalize_reloc) (abfd, section, relptr, symbols)
 
835
     bfd *abfd;
 
836
     sec_ptr section;
 
837
     arelent **relptr;
 
838
     asymbol **symbols;
 
839
{
 
840
  arelent *tblptr = section->relocation;
 
841
  unsigned int count;
 
842
  if (obj_aout_subformat (abfd) == gnu_encap_format)
 
843
    return aout_32_canonicalize_reloc (abfd, section, relptr, symbols);
 
844
 
 
845
  if (!(tblptr || MY (slurp_reloc_table) (abfd, section, symbols)))
 
846
    return -1;
 
847
 
 
848
  if (section->flags & SEC_CONSTRUCTOR)
 
849
    {
 
850
      arelent_chain *chain = section->constructor_chain;
 
851
      for (count = 0; count < section->reloc_count; count++)
 
852
        {
 
853
          *relptr++ = &chain->relent;
 
854
          chain = chain->next;
 
855
        }
 
856
    }
 
857
  else
 
858
    {
 
859
      tblptr = section->relocation;
 
860
 
 
861
      for (count = 0; count++ < section->reloc_count;)
 
862
        {
 
863
          *relptr++ = tblptr++;
 
864
        }
 
865
    }
 
866
  *relptr = 0;
 
867
 
 
868
  return section->reloc_count;
 
869
}
 
870
 
 
871
#include "aout-target.h"