[BACK]Return to hp300hpux.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Annotation of src/external/gpl3/binutils.old/dist/bfd/hp300hpux.c, Revision 1.3

1.1       christos    1: /* BFD backend for hp-ux 9000/300
1.3     ! christos    2:    Copyright (C) 1990-2015 Free Software Foundation, Inc.
1.1       christos    3:    Written by Glenn Engel.
                      4:
                      5:    This file is part of BFD, the Binary File Descriptor library.
                      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 3 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., 51 Franklin Street - Fifth Floor, Boston,
                     20:    MA 02110-1301, 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:        canonicalize_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.  */
1.3     ! christos  107: #define MY(OP) CONCAT2 (m68k_aout_hp300hpux_,OP)
1.1       christos  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).  */
1.3     ! christos  132: #define MY_canonicalize_symtab m68k_aout_hp300hpux_canonicalize_symtab
        !           133: #define MY_get_symtab_upper_bound m68k_aout_hp300hpux_get_symtab_upper_bound
        !           134: #define MY_canonicalize_reloc m68k_aout_hp300hpux_canonicalize_reloc
        !           135: #define MY_write_object_contents m68k_aout_hp300hpux_write_object_contents
1.1       christos  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:
1.3     ! christos  151: #define m68k_aout_hp300hpux_write_syms aout_32_write_syms
1.1       christos  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) (bfd *);
                    198: static bfd_boolean MY (write_object_contents) (bfd *);
                    199: static void convert_sym_type
                    200:   (struct external_nlist *, aout_symbol_type *, bfd *);
                    201:
                    202: bfd_boolean MY (slurp_symbol_table) (bfd *);
                    203: void MY (swap_std_reloc_in)
                    204:   (bfd *, struct hp300hpux_reloc *, arelent *, asymbol **, bfd_size_type);
                    205: bfd_boolean MY (slurp_reloc_table)
                    206:   (bfd *, sec_ptr, asymbol **);
                    207: long MY (canonicalize_symtab)  (bfd *, asymbol **);
                    208: long MY (get_symtab_upper_bound)  (bfd *);
                    209: long MY (canonicalize_reloc)  (bfd *, sec_ptr, arelent **, asymbol **);
                    210:
                    211: /* Since the hpux symbol table has nlist elements interspersed with
                    212:    strings and we need to insert som strings for secondary symbols, we
                    213:    give ourselves a little extra padding up front to account for
                    214:    this.  Note that for each non-secondary symbol we process, we gain
                    215:    9 bytes of space for the discarded nlist element (one byte used for
                    216:    null).  SYM_EXTRA_BYTES is the extra space.  */
                    217: #define SYM_EXTRA_BYTES   1024
                    218:
                    219: /* Set parameters about this a.out file that are machine-dependent.
                    220:    This routine is called from some_aout_object_p just before it returns.  */
                    221: static const bfd_target *
                    222: MY (callback) (bfd *abfd)
                    223: {
                    224:   struct internal_exec *execp = exec_hdr (abfd);
                    225:
                    226:   /* Calculate the file positions of the parts of a newly read aout header */
                    227:   obj_textsec (abfd)->size = N_TXTSIZE (*execp);
                    228:
                    229:   /* The virtual memory addresses of the sections */
                    230:   obj_textsec (abfd)->vma = N_TXTADDR (*execp);
                    231:   obj_datasec (abfd)->vma = N_DATADDR (*execp);
                    232:   obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
                    233:
                    234:   obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
                    235:   obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
                    236:   obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
                    237:
                    238:   /* The file offsets of the sections */
                    239:   obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
                    240:   obj_datasec (abfd)->filepos = N_DATOFF (*execp);
                    241:
                    242:   /* The file offsets of the relocation info */
                    243:   obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
                    244:   obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
                    245:
                    246:   /* The file offsets of the string table and symbol table.  */
                    247:   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
                    248:   obj_str_filepos (abfd) = N_STROFF (*execp);
                    249:
                    250:   /* Determine the architecture and machine type of the object file.  */
                    251: #ifdef SET_ARCH_MACH
                    252:   SET_ARCH_MACH (abfd, *execp);
                    253: #else
                    254:   bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0);
                    255: #endif
                    256:
                    257:   if (obj_aout_subformat (abfd) == gnu_encap_format)
                    258:     {
                    259:       /* The file offsets of the relocation info */
                    260:       obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp);
                    261:       obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp);
                    262:
                    263:       /* The file offsets of the string table and symbol table.  */
                    264:       obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp);
                    265:       obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms);
                    266:
                    267:       abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
                    268:       bfd_get_symcount (abfd) = execp->a_syms / 12;
                    269:       obj_symbol_entry_size (abfd) = 12;
                    270:       obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
                    271:     }
                    272:
                    273:   return abfd->xvec;
                    274: }
                    275:
                    276: extern bfd_boolean aout_32_write_syms (bfd *);
                    277:
                    278: static bfd_boolean
                    279: MY (write_object_contents) (bfd * abfd)
                    280: {
                    281:   struct external_exec exec_bytes;
                    282:   struct internal_exec *execp = exec_hdr (abfd);
                    283:   bfd_size_type text_size;     /* dummy vars */
                    284:   file_ptr text_end;
                    285:
                    286:   memset (&exec_bytes, 0, sizeof (exec_bytes));
                    287:
                    288:   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
                    289:
                    290:   if (adata (abfd).magic == undecided_magic)
                    291:     NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
                    292:   execp->a_syms = 0;
                    293:
                    294:   execp->a_entry = bfd_get_start_address (abfd);
                    295:
                    296:   execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
                    297:                     obj_reloc_entry_size (abfd));
                    298:   execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
                    299:                     obj_reloc_entry_size (abfd));
                    300:
                    301:   N_SET_MACHTYPE (*execp, 0xc);
                    302:   N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
                    303:
                    304:   NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes);
                    305:
                    306:   /* update fields not covered by default swap_exec_header_out */
                    307:
                    308:   /* this is really the sym table size but we store it in drelocs */
                    309:   H_PUT_32 (abfd, (bfd_get_symcount (abfd) * 12), exec_bytes.e_drelocs);
                    310:
                    311:   if (bfd_seek (abfd, (file_ptr) 0, FALSE) != 0
                    312:       || (bfd_bwrite (&exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
                    313:          != EXEC_BYTES_SIZE))
                    314:     return FALSE;
                    315:
                    316:   /* Write out the symbols, and then the relocs.  We must write out
                    317:        the symbols first so that we know the symbol indices.  */
                    318:
                    319:   if (bfd_get_symcount (abfd) != 0)
                    320:     {
                    321:       /* Skip the relocs to where we want to put the symbols.  */
                    322:       if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp) + execp->a_drsize),
                    323:                    SEEK_SET) != 0)
                    324:        return FALSE;
                    325:     }
                    326:
                    327:   if (!MY (write_syms) (abfd))
                    328:     return FALSE;
                    329:
                    330:   if (bfd_get_symcount (abfd) != 0)
                    331:     {
                    332:       if (bfd_seek (abfd, (file_ptr) N_TRELOFF (*execp), SEEK_CUR) != 0)
                    333:        return FALSE;
                    334:       if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd)))
                    335:        return FALSE;
                    336:       if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp), SEEK_CUR) != 0)
                    337:        return FALSE;
                    338:       if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))
                    339:        return FALSE;
                    340:     }
                    341:
                    342:   return TRUE;
                    343: }
                    344:
                    345: /* Convert the hp symbol type to be the same as aout64.h usage so we
                    346:    can piggyback routines in aoutx.h.  */
                    347:
                    348: static void
                    349: convert_sym_type (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) (bfd *abfd,
                    444:                                 struct external_exec *raw_bytes,
                    445:                                 struct internal_exec *execp)
                    446: {
                    447:   struct external_exec *bytes = (struct external_exec *) raw_bytes;
                    448:
                    449:   /* The internal_exec structure has some fields that are unused in this
                    450:      configuration (IE for i960), so ensure that all such uninitialized
                    451:      fields are zero'd out.  There are places where two of these structs
                    452:      are memcmp'd, and thus the contents do matter. */
                    453:   memset (execp, 0, sizeof (struct internal_exec));
                    454:   /* Now fill in fields in the execp, from the bytes in the raw data.  */
                    455:   execp->a_info = H_GET_32 (abfd, bytes->e_info);
                    456:   execp->a_text = GET_WORD (abfd, bytes->e_text);
                    457:   execp->a_data = GET_WORD (abfd, bytes->e_data);
                    458:   execp->a_bss = GET_WORD (abfd, bytes->e_bss);
                    459:   execp->a_syms = GET_WORD (abfd, bytes->e_syms);
                    460:   execp->a_entry = GET_WORD (abfd, bytes->e_entry);
                    461:   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
                    462:   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
                    463:
                    464:   /***************************************************************/
                    465:   /* check the header to see if it was generated by a bfd output */
                    466:   /* this is detected rather bizarrely by requiring a bunch of   */
                    467:   /* header fields to be zero and an old unused field (now used) */
                    468:   /* to be set.                                                  */
                    469:   /***************************************************************/
                    470:   do
                    471:     {
                    472:       long syms;
                    473:       struct aout_data_struct *rawptr;
                    474:       bfd_size_type amt;
                    475:
                    476:       if (H_GET_32 (abfd, bytes->e_passize) != 0)
                    477:        break;
                    478:       if (H_GET_32 (abfd, bytes->e_syms) != 0)
                    479:        break;
                    480:       if (H_GET_32 (abfd, bytes->e_supsize) != 0)
                    481:        break;
                    482:
                    483:       syms = H_GET_32 (abfd, bytes->e_drelocs);
                    484:       if (syms == 0)
                    485:        break;
                    486:
                    487:       /* OK, we've passed the test as best as we can determine */
                    488:       execp->a_syms = syms;
                    489:
                    490:       /* allocate storage for where we will store this result */
                    491:       amt = sizeof (*rawptr);
                    492:       rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
                    493:
                    494:       if (rawptr == NULL)
                    495:        return;
                    496:       abfd->tdata.aout_data = rawptr;
                    497:       obj_aout_subformat (abfd) = gnu_encap_format;
                    498:     }
                    499:   while (0);
                    500: }
                    501:
                    502: /* The hp symbol table is a bit different than other a.out targets.  Instead
                    503:    of having an array of nlist items and an array of strings, hp's format
                    504:    has them mixed together in one structure.  In addition, the strings are
                    505:    not null terminated.  It looks something like this:
                    506:
                    507:    nlist element 1
                    508:    string1
                    509:    nlist element 2
                    510:    string2
                    511:    ...
                    512:
                    513:    The whole symbol table is read as one chunk and then we march thru it
                    514:    and convert it to canonical form.  As we march thru the table, we copy
                    515:    the nlist data into the internal form and we compact the strings and null
                    516:    terminate them, using storage from the already allocated symbol table:
                    517:
                    518:    string1
                    519:    null
                    520:    string2
                    521:    null
                    522:    ...
                    523: */
                    524:
                    525: bfd_boolean
                    526: MY (slurp_symbol_table) (bfd *abfd)
                    527: {
                    528:   bfd_size_type symbol_bytes;
                    529:   struct external_nlist *syms;
                    530:   struct external_nlist *sym_pointer;
                    531:   struct external_nlist *sym_end;
                    532:   char *strings;
                    533:   aout_symbol_type *cached;
                    534:   unsigned num_syms = 0;
                    535:   bfd_size_type amt;
                    536:
                    537:   /* If there's no work to be done, don't do any */
                    538:   if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
                    539:     return TRUE;
                    540:   symbol_bytes = exec_hdr (abfd)->a_syms;
                    541:
                    542:   amt = symbol_bytes + SYM_EXTRA_BYTES;
                    543:   strings = (char *) bfd_alloc (abfd, amt);
                    544:   if (!strings)
                    545:     return FALSE;
                    546:   syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES);
                    547:   if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
                    548:       || bfd_bread (syms, symbol_bytes, abfd) != symbol_bytes)
                    549:     {
                    550:       bfd_release (abfd, syms);
                    551:       return FALSE;
                    552:     }
                    553:
                    554:   sym_end = (struct external_nlist *) (((char *) syms) + symbol_bytes);
                    555:
                    556:   /* first, march thru the table and figure out how many symbols there are */
                    557:   for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++, num_syms++)
                    558:     {
                    559:       /* skip over the embedded symbol. */
                    560:       sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
                    561:                                               sym_pointer->e_length[0]);
                    562:     }
                    563:
                    564:   /* now that we know the symbol count, update the bfd header */
                    565:   bfd_get_symcount (abfd) = num_syms;
                    566:
                    567:   amt = num_syms;
                    568:   amt *= sizeof (aout_symbol_type);
                    569:   cached = (aout_symbol_type *) bfd_zalloc (abfd, amt);
                    570:   if (cached == NULL && num_syms != 0)
                    571:     return FALSE;
                    572:
                    573:   /* as we march thru the hp symbol table, convert it into a list of
                    574:      null terminated strings to hold the symbol names.  Make sure any
                    575:      assignment to the strings pointer is done after we're thru using
                    576:      the nlist so we don't overwrite anything important. */
                    577:
                    578:   /* OK, now walk the new symtable, caching symbol properties */
                    579:   {
                    580:     aout_symbol_type *cache_ptr = cached;
                    581:     /* Run through table and copy values */
                    582:     for (sym_pointer = syms, cache_ptr = cached;
                    583:         sym_pointer < sym_end; sym_pointer++, cache_ptr++)
                    584:       {
                    585:        unsigned int length;
                    586:        cache_ptr->symbol.the_bfd = abfd;
                    587:        cache_ptr->symbol.value = GET_SWORD (abfd, sym_pointer->e_value);
                    588:        cache_ptr->desc = bfd_get_16 (abfd, sym_pointer->e_almod);
                    589:        cache_ptr->type = bfd_get_8 (abfd, sym_pointer->e_type);
                    590:        cache_ptr->symbol.udata.p = NULL;
                    591:        length = bfd_get_8 (abfd, sym_pointer->e_length);
                    592:        cache_ptr->other = length;      /* other not used, save length here */
                    593:
                    594:        convert_sym_type (sym_pointer, cache_ptr, abfd);
                    595:        if (!translate_from_native_sym_flags (abfd, cache_ptr))
                    596:          return FALSE;
                    597:
                    598:        /********************************************************/
                    599:        /* for hpux, the 'length' value indicates the length of */
                    600:        /* the symbol name which follows the nlist entry.       */
                    601:        /********************************************************/
                    602:        if (length)
                    603:          {
                    604:            /**************************************************************/
                    605:            /* the hp string is not null terminated so we create a new one*/
                    606:            /* by copying the string to overlap the just vacated nlist    */
                    607:            /* structure before it in memory.                             */
                    608:            /**************************************************************/
                    609:            cache_ptr->symbol.name = strings;
                    610:            memcpy (strings, sym_pointer + 1, length);
                    611:            strings[length] = '\0';
                    612:            strings += length + 1;
                    613:          }
                    614:        else
                    615:          cache_ptr->symbol.name = (char *) NULL;
                    616:
                    617:        /* skip over the embedded symbol. */
                    618:        sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
                    619:                                                 length);
                    620:       }
                    621:   }
                    622:
                    623:   obj_aout_symbols (abfd) = cached;
                    624:
                    625:   return TRUE;
                    626: }
                    627:
                    628: void
                    629: MY (swap_std_reloc_in) (bfd *abfd,
                    630:                        struct hp300hpux_reloc *bytes,
                    631:                        arelent *cache_ptr,
                    632:                        asymbol **symbols,
                    633:                        bfd_size_type symcount ATTRIBUTE_UNUSED)
                    634: {
                    635:   int r_index;
                    636:   int r_extern = 0;
                    637:   unsigned int r_length;
                    638:   int r_pcrel = 0;
                    639:   struct aoutdata *su = &(abfd->tdata.aout_data->a);
                    640:
                    641:   cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
                    642:   r_index = H_GET_16 (abfd, bytes->r_index);
                    643:
                    644:   switch (bytes->r_type[0])
                    645:     {
                    646:     case HP_RSEGMENT_TEXT:
                    647:       r_index = N_TEXT;
                    648:       break;
                    649:     case HP_RSEGMENT_DATA:
                    650:       r_index = N_DATA;
                    651:       break;
                    652:     case HP_RSEGMENT_BSS:
                    653:       r_index = N_BSS;
                    654:       break;
                    655:     case HP_RSEGMENT_EXTERNAL:
                    656:       r_extern = 1;
                    657:       break;
                    658:     case HP_RSEGMENT_PCREL:
                    659:       r_extern = 1;
                    660:       r_pcrel = 1;
                    661:       break;
                    662:     case HP_RSEGMENT_RDLT:
                    663:       break;
                    664:     case HP_RSEGMENT_RPLT:
                    665:       break;
                    666:     case HP_RSEGMENT_NOOP:
                    667:       break;
                    668:     default:
                    669:       abort ();
                    670:       break;
                    671:     }
                    672:
                    673:   switch (bytes->r_length[0])
                    674:     {
                    675:     case HP_RLENGTH_BYTE:
                    676:       r_length = 0;
                    677:       break;
                    678:     case HP_RLENGTH_WORD:
                    679:       r_length = 1;
                    680:       break;
                    681:     case HP_RLENGTH_LONG:
                    682:       r_length = 2;
                    683:       break;
                    684:     default:
                    685:       abort ();
                    686:       break;
                    687:     }
                    688:
                    689:   cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
                    690:   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
                    691:
                    692:   /* This macro uses the r_index value computed above */
                    693:   if (r_pcrel && r_extern)
                    694:     {
                    695:       /* The GNU linker assumes any offset from beginning of section */
                    696:       /* is already incorporated into the image while the HP linker  */
                    697:       /* adds this in later.  Add it in now...                       */
                    698:       MOVE_ADDRESS (-cache_ptr->address);
                    699:     }
                    700:   else
                    701:     {
                    702:       MOVE_ADDRESS (0);
                    703:     }
                    704: }
                    705:
                    706: bfd_boolean
                    707: MY (slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
                    708: {
                    709:   bfd_size_type count;
                    710:   bfd_size_type reloc_size;
                    711:   void * relocs;
                    712:   arelent *reloc_cache;
                    713:   size_t each_size;
                    714:   struct hp300hpux_reloc *rptr;
                    715:   unsigned int counter;
                    716:   arelent *cache_ptr;
                    717:
                    718:   if (asect->relocation)
                    719:     return TRUE;
                    720:
                    721:   if (asect->flags & SEC_CONSTRUCTOR)
                    722:     return TRUE;
                    723:
                    724:   if (asect == obj_datasec (abfd))
                    725:     {
                    726:       reloc_size = exec_hdr (abfd)->a_drsize;
                    727:       goto doit;
                    728:     }
                    729:
                    730:   if (asect == obj_textsec (abfd))
                    731:     {
                    732:       reloc_size = exec_hdr (abfd)->a_trsize;
                    733:       goto doit;
                    734:     }
                    735:
                    736:   bfd_set_error (bfd_error_invalid_operation);
                    737:   return FALSE;
                    738:
                    739: doit:
                    740:   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
                    741:     return FALSE;
                    742:   each_size = obj_reloc_entry_size (abfd);
                    743:
                    744:   count = reloc_size / each_size;
                    745:
                    746:   reloc_cache = (arelent *) bfd_zalloc (abfd, count * sizeof (arelent));
                    747:   if (!reloc_cache && count != 0)
                    748:     return FALSE;
                    749:
                    750:   relocs = bfd_alloc (abfd, reloc_size);
                    751:   if (!relocs && reloc_size != 0)
                    752:     {
                    753:       bfd_release (abfd, reloc_cache);
                    754:       return FALSE;
                    755:     }
                    756:
                    757:   if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
                    758:     {
                    759:       bfd_release (abfd, relocs);
                    760:       bfd_release (abfd, reloc_cache);
                    761:       return FALSE;
                    762:     }
                    763:
                    764:   rptr = (struct hp300hpux_reloc *) relocs;
                    765:   counter = 0;
                    766:   cache_ptr = reloc_cache;
                    767:
                    768:   for (; counter < count; counter++, rptr++, cache_ptr++)
                    769:     {
                    770:       MY (swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
                    771:                              (bfd_size_type) bfd_get_symcount (abfd));
                    772:     }
                    773:
                    774:   bfd_release (abfd, relocs);
                    775:   asect->relocation = reloc_cache;
                    776:   asect->reloc_count = count;
                    777:   return TRUE;
                    778: }
                    779:
                    780: /************************************************************************/
                    781: /* The following functions are identical to functions in aoutx.h except */
                    782: /* they refer to MY(func) rather than NAME(aout,func) and they also     */
                    783: /* call aout_32 versions if the input file was generated by gcc         */
                    784: /************************************************************************/
                    785:
                    786: long aout_32_canonicalize_symtab  (bfd *, asymbol **);
                    787: long aout_32_get_symtab_upper_bound  (bfd *);
                    788: long aout_32_canonicalize_reloc  (bfd *, sec_ptr, arelent **, asymbol **);
                    789:
                    790: long
                    791: MY (canonicalize_symtab) (bfd *abfd, asymbol **location)
                    792: {
                    793:   unsigned int counter = 0;
                    794:   aout_symbol_type *symbase;
                    795:
                    796:   if (obj_aout_subformat (abfd) == gnu_encap_format)
                    797:     return aout_32_canonicalize_symtab (abfd, location);
                    798:
                    799:   if (!MY (slurp_symbol_table) (abfd))
                    800:     return -1;
                    801:
                    802:   for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
                    803:     *(location++) = (asymbol *) (symbase++);
                    804:   *location++ = 0;
                    805:   return bfd_get_symcount (abfd);
                    806: }
                    807:
                    808: long
                    809: MY (get_symtab_upper_bound) (bfd *abfd)
                    810: {
                    811:   if (obj_aout_subformat (abfd) == gnu_encap_format)
                    812:     return aout_32_get_symtab_upper_bound (abfd);
                    813:   if (!MY (slurp_symbol_table) (abfd))
                    814:     return -1;
                    815:
                    816:   return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
                    817: }
                    818:
                    819: long
                    820: MY (canonicalize_reloc) (bfd *abfd,
                    821:                         sec_ptr section,
                    822:                         arelent **relptr,
                    823:                         asymbol **symbols)
                    824: {
                    825:   arelent *tblptr = section->relocation;
                    826:   unsigned int count;
                    827:
                    828:   if (obj_aout_subformat (abfd) == gnu_encap_format)
                    829:     return aout_32_canonicalize_reloc (abfd, section, relptr, symbols);
                    830:
                    831:   if (!(tblptr || MY (slurp_reloc_table) (abfd, section, symbols)))
                    832:     return -1;
                    833:
                    834:   if (section->flags & SEC_CONSTRUCTOR)
                    835:     {
                    836:       arelent_chain *chain = section->constructor_chain;
                    837:       for (count = 0; count < section->reloc_count; count++)
                    838:        {
                    839:          *relptr++ = &chain->relent;
                    840:          chain = chain->next;
                    841:        }
                    842:     }
                    843:   else
                    844:     {
                    845:       tblptr = section->relocation;
                    846:
                    847:       for (count = 0; count++ < section->reloc_count;)
                    848:        {
                    849:          *relptr++ = tblptr++;
                    850:        }
                    851:     }
                    852:   *relptr = 0;
                    853:
                    854:   return section->reloc_count;
                    855: }
                    856:
                    857: #include "aout-target.h"

CVSweb <webmaster@jp.NetBSD.org>