home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / bfd / versados.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  21KB  |  924 lines

  1. /* BFD back-end for VERSAdos-E objects.
  2.  
  3.    Versados is a Motorola trademark.
  4.  
  5.    Copyright 1995 Free Software Foundation, Inc.
  6.    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
  7.  
  8.    This file is part of BFD, the Binary File Descriptor library.
  9.  
  10.    This program is free software; you can redistribute it and/or modify
  11.    it under the terms of the GNU General Public License as published by
  12.    the Free Software Foundation; either version 2 of the License, or
  13.    (at your option) any later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.    You should have received a copy of the GNU General Public License
  21.    along with this program; if not, write to the Free Software
  22.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  23.  
  24. /*
  25.    SUBSECTION
  26.    VERSAdos-E relocateable object file format
  27.  
  28.    DESCRIPTION
  29.  
  30.    This module supports reading of VERSAdos relocateable
  31.    object files.
  32.  
  33.    A VERSAdos file looks like contains
  34.  
  35.    o Indentification Record
  36.    o External Symbol Definition Record
  37.    o Object Text Recrod
  38.    o End Record
  39.  
  40.  
  41.  */
  42.  
  43. #include "bfd.h"
  44. #include "sysdep.h"
  45. #include "libbfd.h"
  46. #include "libiberty.h"
  47.  
  48.  
  49. static boolean versados_mkobject PARAMS ((bfd *));
  50. static boolean versados_scan PARAMS ((bfd *));
  51. static const bfd_target *versados_object_p PARAMS ((bfd *));
  52.  
  53.  
  54. #define VHEADER '1'
  55. #define VESTDEF '2'
  56. #define VOTR '3'
  57. #define VEND '4'
  58.  
  59.  
  60. #define ES_BASE 17        /* first symbol has esdid 17 */
  61.  
  62. /* Per file target dependent information */
  63.  
  64. /* one for each section */
  65. struct esdid
  66.   {
  67.     asection *section;        /* ptr to bfd version */
  68.     unsigned char *contents;    /* used to build image */
  69.     int pc;
  70.     int relocs;            /* reloc count, valid end of pass 1 */
  71.     int donerel;        /* have relocs been translated */
  72.   };
  73.  
  74. typedef struct versados_data_struct
  75.   {
  76.     int es_done;        /* count of symbol index, starts at ES_BASE */
  77.     asymbol *symbols;        /* pointer to local symbols */
  78.     char *strings;        /* strings of all the above */
  79.     int stringlen;        /* len of string table (valid end of pass1) */
  80.     int nsecsyms;        /* number of sections */
  81.  
  82.     int ndefs;            /* number of exported symbols (they dont get esdids) */
  83.     int nrefs;            /* number of imported symbols  (valid end of pass1) */
  84.  
  85.     int ref_idx;        /* current processed value of the above */
  86.     int def_idx;
  87.  
  88.     int pass_2_done;
  89.  
  90.     struct esdid e[16];        /* per section info */
  91.     int alert;            /* to see if we're trampling */
  92.     asymbol *rest[256 - 16];    /* per symbol info */
  93.  
  94.   }
  95. tdata_type;
  96.  
  97. #define VDATA(abfd)       (abfd->tdata.versados_data)
  98. #define EDATA(abfd, n)    (abfd->tdata.versados_data->e[n])
  99. #define RDATA(abfd, n)    (abfd->tdata.versados_data->rest[n])
  100.  
  101. struct ext_otr
  102.   {
  103.     unsigned char size;
  104.     char type;
  105.     unsigned char map[4];
  106.     unsigned char esdid;
  107.     unsigned char data[200];
  108.   };
  109.  
  110. struct ext_vheader
  111.   {
  112.     unsigned char size;
  113.     char type;            /* record type */
  114.     char name[10];        /* module name */
  115.     char rev;            /* module rev number */
  116.     char lang;
  117.     char vol[4];
  118.     char user[2];
  119.     char cat[8];
  120.     char fname[8];
  121.     char ext[2];
  122.     char time[3];
  123.     char date[3];
  124.     char rest[211];
  125.   };
  126.  
  127. struct ext_esd
  128.   {
  129.     unsigned char size;
  130.     char type;
  131.     unsigned char esd_entries[1];
  132.   };
  133. #define ESD_ABS     0
  134. #define ESD_COMMON     1
  135. #define ESD_STD_REL_SEC 2
  136. #define ESD_SHRT_REL_SEC 3
  137. #define ESD_XDEF_IN_SEC 4
  138. #define ESD_XREF_SYM    7
  139. #define ESD_XREF_SEC    6
  140. #define ESD_XDEF_IN_ABS 5
  141. union ext_any
  142.   {
  143.     unsigned char size;
  144.     struct ext_vheader header;
  145.     struct ext_esd esd;
  146.     struct ext_otr otr;
  147.   };
  148.  
  149. /* Initialize by filling in the hex conversion array. */
  150.  
  151.  
  152.  
  153.  
  154.  
  155. /* Set up the tdata information.  */
  156.  
  157. static boolean
  158. versados_mkobject (abfd)
  159.      bfd *abfd;
  160. {
  161.   if (abfd->tdata.versados_data == NULL)
  162.     {
  163.       tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
  164.       if (tdata == NULL)
  165.     return false;
  166.       abfd->tdata.versados_data = tdata;
  167.       tdata->symbols = NULL;
  168.       VDATA (abfd)->alert = 0x12345678;
  169.     }
  170.  
  171.   bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
  172.   return true;
  173. }
  174.  
  175.  
  176. /* Report a problem in an S record file.  FIXME: This probably should
  177.    not call fprintf, but we really do need some mechanism for printing
  178.    error messages.  */
  179.  
  180.  
  181.  
  182. static asymbol *
  183. versados_new_symbol (abfd, snum, name, val, sec)
  184.      bfd *abfd;
  185.      int snum;
  186.      const char *name;
  187.      bfd_vma val;
  188.      asection *sec;
  189. {
  190.   asymbol *n = VDATA (abfd)->symbols + snum;
  191.   n->name = name;
  192.   n->value = val;
  193.   n->section = sec;
  194.   n->the_bfd = abfd;
  195.   n->flags = 0;
  196.   return n;
  197. }
  198.  
  199.  
  200. static int
  201. get_record (abfd, ptr)
  202.      bfd *abfd;
  203.      union ext_any *ptr;
  204. {
  205.   bfd_read (&ptr->size, 1, 1, abfd);
  206.   if (bfd_read ((char *) ptr + 1, 1, ptr->size, abfd) != ptr->size)
  207.     return 0;
  208.   return 1;
  209. }
  210.  
  211. int
  212. get_4 (pp)
  213.      unsigned char **pp;
  214. {
  215.   unsigned char *p = *pp;
  216.   *pp += 4;
  217.   return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
  218. }
  219.  
  220. void
  221. get_10 (pp, name)
  222.      unsigned char **pp;
  223.      char *name;
  224. {
  225.   char *p = (char *) *pp;
  226.   int len = 10;
  227.   *pp += len;
  228.   while (*p != ' '
  229.      && len)
  230.     {
  231.       *name++ = *p++;
  232.       len--;
  233.     }
  234.   *name = 0;
  235. }
  236.  
  237. static char *
  238. new_symbol_string (abfd, name)
  239.      bfd *abfd;
  240.      char *name;
  241. {
  242.   char *n = VDATA (abfd)->strings;
  243.   strcpy (VDATA (abfd)->strings, name);
  244.   VDATA (abfd)->strings += strlen (VDATA (abfd)->strings) + 1;
  245.   return n;
  246. }
  247.  
  248.  
  249. static void
  250. process_esd (abfd, esd, pass)
  251.      bfd *abfd;
  252.      struct ext_esd *esd;
  253.      int pass;
  254. {
  255.   /* Read through the ext def for the est entries */
  256.   int togo = esd->size - 2;
  257.   bfd_vma size;
  258.   bfd_vma start;
  259.   asection *sec;
  260.   char name[11];
  261.   unsigned char *ptr = esd->esd_entries;
  262.   unsigned char *end = ptr + togo;
  263.   while (ptr < end)
  264.     {
  265.       int scn = *ptr & 0xf;
  266.       int typ = (*ptr >> 4) & 0xf;
  267.  
  268.       /* Declare this section */
  269.       sprintf (name, "%d", scn);
  270.       sec = bfd_make_section_old_way (abfd, strdup (name));
  271.       sec->target_index = scn;
  272.       EDATA (abfd, scn).section = sec;
  273.       ptr++;
  274.       switch (typ)
  275.     {
  276.     default:
  277.       abort ();
  278.     case ESD_XREF_SEC:
  279.     case ESD_XREF_SYM:
  280.       {
  281.         int snum = VDATA (abfd)->ref_idx++;
  282.         get_10 (&ptr, name);
  283.         if (pass == 1)
  284.           {
  285.         VDATA (abfd)->stringlen += strlen (name) + 1;
  286.           }
  287.         else
  288.           {
  289.         int esidx;
  290.         asymbol *s;
  291.         char *n = new_symbol_string (abfd, name);
  292.         s = versados_new_symbol (abfd, snum, n, 0,
  293.                      &bfd_und_section, scn);
  294.         esidx = VDATA (abfd)->es_done++;
  295.         RDATA (abfd, esidx - ES_BASE) = s;
  296.           }
  297.       }
  298.       break;
  299.  
  300.  
  301.     case ESD_ABS:
  302.       size = get_4 (&ptr);
  303.       start = get_4 (&ptr);
  304.       break;
  305.     case ESD_STD_REL_SEC:
  306.     case ESD_SHRT_REL_SEC:
  307.       {
  308.         sec->_raw_size = get_4 (&ptr);
  309.         sec->flags |= SEC_ALLOC;
  310.       }
  311.       break;
  312.     case ESD_XDEF_IN_ABS:
  313.       sec = (asection *) & bfd_abs_section;
  314.     case ESD_XDEF_IN_SEC:
  315.       {
  316.         int snum = VDATA (abfd)->def_idx++;
  317.         long val;
  318.         get_10 (&ptr, name);
  319.         val = get_4 (&ptr);
  320.         if (pass == 1)
  321.           {
  322.         /* Just remember the symbol */
  323.         VDATA (abfd)->stringlen += strlen (name) + 1;
  324.           }
  325.         else
  326.           {
  327.         asymbol *s;
  328.         char *n = new_symbol_string (abfd, name);
  329.         s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n, val, sec, scn);
  330.         s->flags |= BSF_GLOBAL;
  331.           }
  332.       }
  333.       break;
  334.     }
  335.     }
  336. }
  337.  
  338. #define R_RELWORD 1
  339. #define R_RELLONG 2
  340. #define R_RELWORD_NEG 3
  341. #define R_RELLONG_NEG 4
  342.  
  343. reloc_howto_type versados_howto_table[] =
  344. {
  345.   HOWTO (R_RELWORD, 0, 1, 16, false,
  346.      0, complain_overflow_dont, 0,
  347.      "+v16", true, 0x0000ffff, 0x0000ffff, false),
  348.   HOWTO (R_RELLONG, 0, 2, 32, false,
  349.      0, complain_overflow_dont, 0,
  350.      "+v32", true, 0xffffffff, 0xffffffff, false),
  351.  
  352.   HOWTO (R_RELWORD_NEG, 0, -1, 16, false,
  353.      0, complain_overflow_dont, 0,
  354.      "-v16", true, 0x0000ffff, 0x0000ffff, false),
  355.   HOWTO (R_RELLONG_NEG, 0, -2, 32, false,
  356.      0, complain_overflow_dont, 0,
  357.      "-v32", true, 0xffffffff, 0xffffffff, false),
  358. };
  359.  
  360.  
  361. static int
  362. get_offset (len, ptr)
  363.      int len;
  364.      unsigned char *ptr;
  365. {
  366.   int val = 0;
  367.   if (len)
  368.     {
  369.       int i;
  370.       val = *ptr++;
  371.       if (val & 0x80)
  372.     val |= ~0xff;
  373.       for (i = 1; i < len; i++)
  374.     val = (val << 8) | *ptr++;
  375.     }
  376.  
  377.   return val;
  378. }
  379.  
  380. static void
  381. process_otr (abfd, otr, pass)
  382.      bfd *abfd;
  383.      struct ext_otr *otr;
  384.      int pass;
  385. {
  386.   unsigned long shift;
  387.   unsigned char *srcp = otr->data;
  388.   unsigned char *endp = (unsigned char *) otr + otr->size;
  389.   unsigned int bits = (otr->map[0] << 24)
  390.   | (otr->map[1] << 16)
  391.   | (otr->map[2] << 8)
  392.   | (otr->map[3] << 0);
  393.  
  394.   struct esdid *esdid = &EDATA (abfd, otr->esdid - 1);
  395.   unsigned char *contents = esdid->contents;
  396.   int need_contents = 0;
  397.   unsigned int dst_idx = esdid->pc;
  398.  
  399.   for (shift = (1 << 31); shift && srcp < endp; shift >>= 1)
  400.     {
  401.       if (bits & shift)
  402.     {
  403.       int flag = *srcp++;
  404.       int esdids = (flag >> 5) & 0x7;
  405.       int sizeinwords = ((flag >> 3) & 1) ? 2 : 1;
  406.       int offsetlen = flag & 0x7;
  407.       int j;
  408.  
  409.  
  410.       if (esdids == 0)
  411.         {
  412.           /* A zero esdid means the new pc is the offset given */
  413.           dst_idx += get_offset (offsetlen, srcp);
  414.           srcp += offsetlen;
  415.         }
  416.       else
  417.         {
  418.           int val = get_offset (offsetlen, srcp + esdids);
  419.           if (pass == 1)
  420.         need_contents = 1;
  421.           else
  422.         for (j = 0; j < sizeinwords * 2; j++)
  423.           {
  424.             contents[dst_idx + (sizeinwords * 2) - j - 1] = val;
  425.             val >>= 8;
  426.           }
  427.  
  428.           for (j = 0; j < esdids; j++)
  429.         {
  430.           int esdid = *srcp++;
  431.  
  432.           if (esdid)
  433.             {
  434.               int rn = EDATA (abfd, otr->esdid - 1).relocs++;
  435.               if (pass == 1)
  436.             {
  437.               /* this is the first pass over the data, 
  438.                  just remember that we need a reloc */
  439.             }
  440.               else
  441.             {
  442.               arelent *n =
  443.               EDATA (abfd, otr->esdid - 1).section->relocation + rn;
  444.               n->address = dst_idx;
  445.  
  446.               n->sym_ptr_ptr = (asymbol **) esdid;
  447.               n->addend = 0;
  448.               n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1);
  449.             }
  450.             }
  451.         }
  452.           srcp += offsetlen;
  453.           dst_idx += sizeinwords * 2;
  454.         }
  455.     }
  456.       else
  457.     {
  458.       need_contents = 1;
  459.       if (dst_idx < esdid->section->_raw_size)
  460.         if (pass == 2)
  461.           {
  462.         /* absolute code, comes in 16 bit lumps */
  463.         contents[dst_idx] = srcp[0];
  464.         contents[dst_idx + 1] = srcp[1];
  465.           }
  466.       dst_idx += 2;
  467.       srcp += 2;
  468.     }
  469.     }
  470.   EDATA (abfd, otr->esdid - 1).pc = dst_idx;
  471.  
  472.   if (!contents && need_contents)
  473.     esdid->contents = (unsigned char *) bfd_alloc (abfd, esdid->section->_raw_size);
  474.  
  475.  
  476. }
  477.  
  478. static boolean
  479. versados_scan (abfd)
  480.      bfd *abfd;
  481. {
  482.   int loop = 1;
  483.   int i;
  484.   int j;
  485.   int nsecs = 0;
  486.  
  487.   VDATA (abfd)->nrefs = 0;
  488.   VDATA (abfd)->ndefs = 0;
  489.   VDATA (abfd)->ref_idx = 0;
  490.   VDATA (abfd)->def_idx = 0;
  491.  
  492.   while (loop)
  493.     {
  494.       union ext_any any;
  495.       if (!get_record (abfd, &any))
  496.     return true;
  497.       switch (any.header.type)
  498.     {
  499.     case VHEADER:
  500.       break;
  501.     case VEND:
  502.       loop = 0;
  503.       break;
  504.     case VESTDEF:
  505.       process_esd (abfd, &any.esd, 1);
  506.       break;
  507.     case VOTR:
  508.       process_otr (abfd, &any.otr, 1);
  509.       break;
  510.     }
  511.     }
  512.  
  513.   /* Now allocate space for the relocs and sections */
  514.  
  515.   VDATA (abfd)->nrefs = VDATA (abfd)->ref_idx;
  516.   VDATA (abfd)->ndefs = VDATA (abfd)->def_idx;
  517.   VDATA (abfd)->ref_idx = 0;
  518.   VDATA (abfd)->def_idx = 0;
  519.  
  520.   abfd->symcount = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs;
  521.  
  522.   for (i = 0; i < 16; i++)
  523.     {
  524.       struct esdid *esdid = &EDATA (abfd, i);
  525.       if (esdid->section)
  526.     {
  527.       esdid->section->relocation
  528.         = (arelent *) bfd_alloc (abfd, sizeof (arelent) * esdid->relocs);
  529.  
  530.       esdid->pc = 0;
  531.  
  532.       if (esdid->contents)
  533.         esdid->section->flags |= SEC_HAS_CONTENTS | SEC_LOAD;
  534.  
  535.       esdid->section->reloc_count = esdid->relocs;
  536.       if (esdid->relocs)
  537.         esdid->section->flags |= SEC_RELOC;
  538.  
  539.       esdid->relocs = 0;
  540.  
  541.       /* Add an entry into the symbol table for it */
  542.       nsecs++;
  543.       VDATA (abfd)->stringlen += strlen (esdid->section->name) + 1;
  544.     }
  545.     }
  546.  
  547.   abfd->symcount += nsecs;
  548.  
  549.   VDATA (abfd)->symbols = (asymbol *) bfd_alloc (abfd,
  550.                        sizeof (asymbol) * (abfd->symcount));
  551.  
  552.   VDATA (abfd)->strings = bfd_alloc (abfd, VDATA (abfd)->stringlen);
  553.  
  554.   if ((VDATA (abfd)->symbols == NULL && abfd->symcount > 0)
  555.       || (VDATA (abfd)->strings == NULL && VDATA (abfd)->stringlen > 0))
  556.     return false;
  557.  
  558.   /* Actually fill in the section symbols,
  559.      we stick them at the end of the table */
  560.  
  561.   for (j = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs, i = 0; i < 16; i++)
  562.     {
  563.       struct esdid *esdid = &EDATA (abfd, i);
  564.       asection *sec = esdid->section;
  565.       if (sec)
  566.     {
  567.       asymbol *s = VDATA (abfd)->symbols + j;
  568.       s->name = new_symbol_string (abfd, sec->name);
  569.       s->section = sec;
  570.       s->flags = BSF_LOCAL;
  571.       s->value = 0;
  572.       s->the_bfd = abfd;
  573.       j++;
  574.     }
  575.     }
  576.   if (abfd->symcount)
  577.     abfd->flags |= HAS_SYMS;
  578.  
  579.   /* Set this to nsecs - since we've already planted the section
  580.      symbols */
  581.   VDATA (abfd)->nsecsyms = nsecs;
  582.  
  583.   VDATA (abfd)->ref_idx = 0;
  584.  
  585.   return 1;
  586. }
  587.  
  588.  
  589.  
  590. /* Check whether an existing file is a versados  file.  */
  591.  
  592. static const bfd_target *
  593. versados_object_p (abfd)
  594.      bfd *abfd;
  595. {
  596.   struct ext_vheader ext;
  597.   unsigned char len;
  598.  
  599.   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
  600.     return NULL;
  601.  
  602.   if (bfd_read (&len, 1, 1, abfd) != 1)
  603.     {
  604.       if (bfd_get_error () != bfd_error_system_call)
  605.     bfd_set_error (bfd_error_wrong_format);
  606.       return NULL;
  607.     }
  608.  
  609.   if (bfd_read (&ext.type, 1, len, abfd) != len)
  610.     {
  611.       if (bfd_get_error () != bfd_error_system_call)
  612.     bfd_set_error (bfd_error_wrong_format);
  613.       return NULL;
  614.     }
  615.  
  616.   /* We guess that the language field will never be larger than 10.
  617.      In sample files, it is always either 0 or 1.  Checking for this
  618.      prevents confusion with Intel Hex files.  */
  619.   if (ext.type != VHEADER
  620.       || ext.lang > 10)
  621.     {
  622.       bfd_set_error (bfd_error_wrong_format);
  623.       return NULL;
  624.     }
  625.  
  626.   /* OK, looks like a record, build the tdata and read in.  */
  627.  
  628.   if (!versados_mkobject (abfd)
  629.       || !versados_scan (abfd))
  630.     return NULL;
  631.  
  632.   return abfd->xvec;
  633. }
  634.  
  635.  
  636. static boolean
  637. versados_pass_2 (abfd)
  638.      bfd *abfd;
  639. {
  640.   union ext_any any;
  641.  
  642.   if (VDATA (abfd)->pass_2_done)
  643.     return 1;
  644.  
  645.   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
  646.     return 0;
  647.  
  648.   VDATA (abfd)->es_done = ES_BASE;
  649.  
  650.  
  651.   /* read records till we get to where we want to be */
  652.  
  653.   while (1)
  654.     {
  655.       get_record (abfd, &any);
  656.       switch (any.header.type)
  657.     {
  658.     case VEND:
  659.       VDATA (abfd)->pass_2_done = 1;
  660.       return 1;
  661.     case VESTDEF:
  662.       process_esd (abfd, &any.esd, 2);
  663.       break;
  664.     case VOTR:
  665.       process_otr (abfd, &any.otr, 2);
  666.       break;
  667.     }
  668.     }
  669. }
  670.  
  671. static boolean
  672. versados_get_section_contents (abfd, section, location, offset, count)
  673.      bfd *abfd;
  674.      asection *section;
  675.      PTR location;
  676.      file_ptr offset;
  677.      bfd_size_type count;
  678. {
  679.   if (!versados_pass_2 (abfd))
  680.     return false;
  681.  
  682.   memcpy (location,
  683.       EDATA (abfd, section->target_index).contents + offset,
  684.       (size_t) count);
  685.  
  686.   return true;
  687. }
  688.  
  689. #define versados_get_section_contents_in_window \
  690.   _bfd_generic_get_section_contents_in_window
  691.  
  692. static boolean
  693. versados_set_section_contents (abfd, section, location, offset, bytes_to_do)
  694.      bfd *abfd;
  695.      sec_ptr section;
  696.      PTR location;
  697.      file_ptr offset;
  698.      bfd_size_type bytes_to_do;
  699. {
  700.   return false;
  701. }
  702.  
  703.  
  704. /*ARGSUSED */
  705. static int
  706. versados_sizeof_headers (abfd, exec)
  707.      bfd *abfd;
  708.      boolean exec;
  709. {
  710.   return 0;
  711. }
  712.  
  713. static asymbol *
  714. versados_make_empty_symbol (abfd)
  715.      bfd *abfd;
  716. {
  717.   asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
  718.   if (new)
  719.     new->the_bfd = abfd;
  720.   return new;
  721. }
  722.  
  723. /* Return the amount of memory needed to read the symbol table.  */
  724.  
  725. static long
  726. versados_get_symtab_upper_bound (abfd)
  727.      bfd *abfd;
  728. {
  729.   return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
  730. }
  731.  
  732. /* Return the symbol table.  */
  733.  
  734. static long
  735. versados_get_symtab (abfd, alocation)
  736.      bfd *abfd;
  737.      asymbol **alocation;
  738. {
  739.   unsigned int symcount = bfd_get_symcount (abfd);
  740.   unsigned int i;
  741.   asymbol *s;
  742.  
  743.   versados_pass_2 (abfd);
  744.  
  745.   for (i = 0, s = VDATA (abfd)->symbols;
  746.        i < symcount;
  747.        s++, i++)
  748.     {
  749.       *alocation++ = s;
  750.     }
  751.  
  752.   *alocation = NULL;
  753.  
  754.   return symcount;
  755. }
  756.  
  757. /*ARGSUSED */
  758. void
  759. versados_get_symbol_info (ignore_abfd, symbol, ret)
  760.      bfd *ignore_abfd;
  761.      asymbol *symbol;
  762.      symbol_info *ret;
  763. {
  764.   bfd_symbol_info (symbol, ret);
  765. }
  766.  
  767. /*ARGSUSED */
  768. void
  769. versados_print_symbol (ignore_abfd, afile, symbol, how)
  770.      bfd *ignore_abfd;
  771.      PTR afile;
  772.      asymbol *symbol;
  773.      bfd_print_symbol_type how;
  774. {
  775.   FILE *file = (FILE *) afile;
  776.   switch (how)
  777.     {
  778.     case bfd_print_symbol_name:
  779.       fprintf (file, "%s", symbol->name);
  780.       break;
  781.     default:
  782.       bfd_print_symbol_vandf ((PTR) file, symbol);
  783.       fprintf (file, " %-5s %s",
  784.            symbol->section->name,
  785.            symbol->name);
  786.  
  787.     }
  788. }
  789.  
  790. long
  791. versados_get_reloc_upper_bound (abfd, asect)
  792.      bfd *abfd;
  793.      sec_ptr asect;
  794. {
  795.   return (asect->reloc_count + 1) * sizeof (arelent *);
  796. }
  797.  
  798.  
  799. long
  800. versados_canonicalize_reloc (abfd, section, relptr, symbols)
  801.      bfd *abfd;
  802.      sec_ptr section;
  803.      arelent **relptr;
  804.      asymbol **symbols;
  805. {
  806.   unsigned int count;
  807.   arelent *src;
  808.  
  809.   versados_pass_2 (abfd);
  810.   src = section->relocation;
  811.   if (!EDATA (abfd, section->target_index).donerel)
  812.     {
  813.       EDATA (abfd, section->target_index).donerel = 1;
  814.       /* translate from indexes to symptr ptrs */
  815.       for (count = 0; count < section->reloc_count; count++)
  816.     {
  817.       int esdid = (int) src[count].sym_ptr_ptr;
  818.  
  819.       if (esdid == 0)
  820.         {
  821.           src[count].sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
  822.         }
  823.       else if (esdid < ES_BASE)    /* Section relative thing */
  824.         {
  825.           struct esdid *e = &EDATA (abfd, esdid - 1);
  826.           if (!section)
  827.         {
  828.          /** relocation relative to section which was
  829.            never declared ! */
  830.         }
  831.           src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr;
  832.         }
  833.       else
  834.         {
  835.           src[count].sym_ptr_ptr = symbols + esdid - ES_BASE;
  836.         }
  837.  
  838.     }
  839.     }
  840.  
  841.   for (count = 0; count < section->reloc_count; count++)
  842.     {
  843.       *relptr++ = src++;
  844.     }
  845.   *relptr = 0;
  846.   return section->reloc_count;
  847. }
  848.  
  849. #define    versados_close_and_cleanup _bfd_generic_close_and_cleanup
  850. #define versados_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
  851. #define versados_new_section_hook _bfd_generic_new_section_hook
  852.  
  853. #define versados_bfd_is_local_label bfd_generic_is_local_label
  854. #define versados_get_lineno _bfd_nosymbols_get_lineno
  855. #define versados_find_nearest_line _bfd_nosymbols_find_nearest_line
  856. #define versados_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
  857. #define versados_read_minisymbols _bfd_generic_read_minisymbols
  858. #define versados_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
  859.  
  860. #define versados_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
  861.  
  862. #define versados_set_arch_mach bfd_default_set_arch_mach
  863.  
  864. #define versados_bfd_get_relocated_section_contents \
  865.   bfd_generic_get_relocated_section_contents
  866. #define versados_bfd_relax_section bfd_generic_relax_section
  867. #define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
  868. #define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols
  869. #define versados_bfd_final_link _bfd_generic_final_link
  870. #define versados_bfd_link_split_section _bfd_generic_link_split_section
  871.  
  872. const bfd_target versados_vec =
  873. {
  874.   "versados",            /* name */
  875.   bfd_target_versados_flavour,
  876.   BFD_ENDIAN_BIG,        /* target byte order */
  877.   BFD_ENDIAN_BIG,        /* target headers byte order */
  878.   (HAS_RELOC | EXEC_P |        /* object flags */
  879.    HAS_LINENO | HAS_DEBUG |
  880.    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
  881.   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
  882.    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),        /* section flags */
  883.   0,                /* leading underscore */
  884.   ' ',                /* ar_pad_char */
  885.   16,                /* ar_max_namelen */
  886.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  887.   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  888.   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* data */
  889.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  890.   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  891.   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* hdrs */
  892.  
  893.   {
  894.     _bfd_dummy_target,
  895.     versados_object_p,        /* bfd_check_format */
  896.     _bfd_dummy_target,
  897.     _bfd_dummy_target,
  898.   },
  899.   {
  900.     bfd_false,
  901.     versados_mkobject,
  902.     _bfd_generic_mkarchive,
  903.     bfd_false,
  904.   },
  905.   {                /* bfd_write_contents */
  906.     bfd_false,
  907.     bfd_false,
  908.     _bfd_write_archive_contents,
  909.     bfd_false,
  910.   },
  911.  
  912.   BFD_JUMP_TABLE_GENERIC (versados),
  913.   BFD_JUMP_TABLE_COPY (_bfd_generic),
  914.   BFD_JUMP_TABLE_CORE (_bfd_nocore),
  915.   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
  916.   BFD_JUMP_TABLE_SYMBOLS (versados),
  917.   BFD_JUMP_TABLE_RELOCS (versados),
  918.   BFD_JUMP_TABLE_WRITE (versados),
  919.   BFD_JUMP_TABLE_LINK (versados),
  920.   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
  921.  
  922.   (PTR) 0
  923. };
  924.