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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [hp300hpux.c] - Blame information for rev 1776

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

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

powered by: WebSVN 2.1.0

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