Back to index

cell-binutils  2.17cvs20070401
versados.c
Go to the documentation of this file.
00001 /* BFD back-end for VERSAdos-E objects.
00002    Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00003    2006, 2007 Free Software Foundation, Inc.
00004    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
00005 
00006    Versados is a Motorola trademark.
00007 
00008    This file is part of BFD, the Binary File Descriptor library.
00009 
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 2 of the License, or
00013    (at your option) any later version.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License
00021    along with this program; if not, write to the Free Software
00022    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00023 
00024 /*
00025    SUBSECTION
00026    VERSAdos-E relocatable object file format
00027 
00028    DESCRIPTION
00029 
00030    This module supports reading of VERSAdos relocatable
00031    object files.
00032 
00033    A VERSAdos file looks like contains
00034 
00035    o Identification Record
00036    o External Symbol Definition Record
00037    o Object Text Record
00038    o End Record.  */
00039 
00040 #include "bfd.h"
00041 #include "sysdep.h"
00042 #include "libbfd.h"
00043 #include "libiberty.h"
00044 
00045 
00046 #define VHEADER '1'
00047 #define VESTDEF '2'
00048 #define VOTR '3'
00049 #define VEND '4'
00050 
00051 #define ES_BASE 17          /* First symbol has esdid 17.  */
00052 
00053 /* Per file target dependent information.  */
00054 
00055 /* One for each section.  */
00056 struct esdid
00057 {
00058   asection *section;        /* Ptr to bfd version.  */
00059   unsigned char *contents;  /* Used to build image.  */
00060   int pc;
00061   int relocs;               /* Reloc count, valid end of pass 1.  */
00062   int donerel;                     /* Have relocs been translated.  */
00063 };
00064 
00065 typedef struct versados_data_struct
00066 {
00067   int es_done;                     /* Count of symbol index, starts at ES_BASE.  */
00068   asymbol *symbols;         /* Pointer to local symbols.  */
00069   char *strings;            /* Strings of all the above.  */
00070   int stringlen;            /* Len of string table (valid end of pass1).  */
00071   int nsecsyms;                    /* Number of sections.  */
00072 
00073   int ndefs;                /* Number of exported symbols (they dont get esdids).  */
00074   int nrefs;                /* Number of imported symbols  (valid end of pass1).  */
00075 
00076   int ref_idx;                     /* Current processed value of the above.  */
00077   int def_idx;
00078 
00079   int pass_2_done;
00080 
00081   struct esdid e[16];              /* Per section info.  */
00082   int alert;                /* To see if we're trampling.  */
00083   asymbol *rest[256 - 16];  /* Per symbol info.  */
00084 }
00085 tdata_type;
00086 
00087 #define VDATA(abfd)       (abfd->tdata.versados_data)
00088 #define EDATA(abfd, n)    (abfd->tdata.versados_data->e[n])
00089 #define RDATA(abfd, n)    (abfd->tdata.versados_data->rest[n])
00090 
00091 struct ext_otr
00092 {
00093   unsigned char size;
00094   char type;
00095   unsigned char map[4];
00096   unsigned char esdid;
00097   unsigned char data[200];
00098 };
00099 
00100 struct ext_vheader
00101 {
00102   unsigned char size;
00103   char type;                /* Record type.  */
00104   char name[10];            /* Module name.  */
00105   char rev;                 /* Module rev number.  */
00106   char lang;
00107   char vol[4];
00108   char user[2];
00109   char cat[8];
00110   char fname[8];
00111   char ext[2];
00112   char time[3];
00113   char date[3];
00114   char rest[211];
00115 };
00116 
00117 struct ext_esd
00118 {
00119   unsigned char size;
00120   char type;
00121   unsigned char esd_entries[1];
00122 };
00123 
00124 #define ESD_ABS        0
00125 #define ESD_COMMON     1
00126 #define ESD_STD_REL_SEC   2
00127 #define ESD_SHRT_REL_SEC  3
00128 #define ESD_XDEF_IN_SEC   4
00129 #define ESD_XDEF_IN_ABS   5
00130 #define ESD_XREF_SEC   6
00131 #define ESD_XREF_SYM      7
00132 
00133 union ext_any
00134 {
00135   unsigned char size;
00136   struct ext_vheader header;
00137   struct ext_esd esd;
00138   struct ext_otr otr;
00139 };
00140 
00141 /* Initialize by filling in the hex conversion array.  */
00142 
00143 /* Set up the tdata information.  */
00144 
00145 static bfd_boolean
00146 versados_mkobject (bfd *abfd)
00147 {
00148   if (abfd->tdata.versados_data == NULL)
00149     {
00150       bfd_size_type amt = sizeof (tdata_type);
00151       tdata_type *tdata = bfd_alloc (abfd, amt);
00152 
00153       if (tdata == NULL)
00154        return FALSE;
00155       abfd->tdata.versados_data = tdata;
00156       tdata->symbols = NULL;
00157       VDATA (abfd)->alert = 0x12345678;
00158     }
00159 
00160   bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
00161   return TRUE;
00162 }
00163 
00164 /* Report a problem in an S record file.  FIXME: This probably should
00165    not call fprintf, but we really do need some mechanism for printing
00166    error messages.  */
00167 
00168 static asymbol *
00169 versados_new_symbol (bfd *abfd,
00170                    int snum,
00171                    const char *name,
00172                    bfd_vma val,
00173                    asection *sec)
00174 {
00175   asymbol *n = VDATA (abfd)->symbols + snum;
00176   n->name = name;
00177   n->value = val;
00178   n->section = sec;
00179   n->the_bfd = abfd;
00180   n->flags = 0;
00181   return n;
00182 }
00183 
00184 static int
00185 get_record (bfd *abfd, union ext_any *ptr)
00186 {
00187   if (bfd_bread (&ptr->size, (bfd_size_type) 1, abfd) != 1
00188       || (bfd_bread ((char *) ptr + 1, (bfd_size_type) ptr->size, abfd)
00189          != ptr->size))
00190     return 0;
00191   return 1;
00192 }
00193 
00194 static int
00195 get_4 (unsigned char **pp)
00196 {
00197   unsigned char *p = *pp;
00198 
00199   *pp += 4;
00200   return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
00201 }
00202 
00203 static void
00204 get_10 (unsigned char **pp, char *name)
00205 {
00206   char *p = (char *) *pp;
00207   int len = 10;
00208 
00209   *pp += len;
00210   while (*p != ' ' && len)
00211     {
00212       *name++ = *p++;
00213       len--;
00214     }
00215   *name = 0;
00216 }
00217 
00218 static char *
00219 new_symbol_string (bfd *abfd, const char *name)
00220 {
00221   char *n = VDATA (abfd)->strings;
00222 
00223   strcpy (VDATA (abfd)->strings, name);
00224   VDATA (abfd)->strings += strlen (VDATA (abfd)->strings) + 1;
00225   return n;
00226 }
00227 
00228 static void
00229 process_esd (bfd *abfd, struct ext_esd *esd, int pass)
00230 {
00231   /* Read through the ext def for the est entries.  */
00232   int togo = esd->size - 2;
00233   bfd_vma size;
00234   bfd_vma start;
00235   asection *sec;
00236   char name[11];
00237   unsigned char *ptr = esd->esd_entries;
00238   unsigned char *end = ptr + togo;
00239 
00240   while (ptr < end)
00241     {
00242       int scn = *ptr & 0xf;
00243       int typ = (*ptr >> 4) & 0xf;
00244 
00245       /* Declare this section.  */
00246       sprintf (name, "%d", scn);
00247       sec = bfd_make_section_old_way (abfd, strdup (name));
00248       sec->target_index = scn;
00249       EDATA (abfd, scn).section = sec;
00250       ptr++;
00251 
00252       switch (typ)
00253        {
00254        default:
00255          abort ();
00256        case ESD_XREF_SEC:
00257        case ESD_XREF_SYM:
00258          {
00259            int snum = VDATA (abfd)->ref_idx++;
00260            get_10 (&ptr, name);
00261            if (pass == 1)
00262              VDATA (abfd)->stringlen += strlen (name) + 1;
00263            else
00264              {
00265               int esidx;
00266               asymbol *s;
00267               char *n = new_symbol_string (abfd, name);
00268 
00269               s = versados_new_symbol (abfd, snum, n, (bfd_vma) 0,
00270                                     bfd_und_section_ptr);
00271               esidx = VDATA (abfd)->es_done++;
00272               RDATA (abfd, esidx - ES_BASE) = s;
00273              }
00274          }
00275          break;
00276 
00277        case ESD_ABS:
00278          size = get_4 (&ptr);
00279          start = get_4 (&ptr);
00280          break;
00281        case ESD_STD_REL_SEC:
00282        case ESD_SHRT_REL_SEC:
00283          sec->size = get_4 (&ptr);
00284          sec->flags |= SEC_ALLOC;
00285          break;
00286        case ESD_XDEF_IN_ABS:
00287          sec = (asection *) & bfd_abs_section;
00288        case ESD_XDEF_IN_SEC:
00289          {
00290            int snum = VDATA (abfd)->def_idx++;
00291            bfd_vma val;
00292 
00293            get_10 (&ptr, name);
00294            val = get_4 (&ptr);
00295            if (pass == 1)
00296              /* Just remember the symbol.  */
00297              VDATA (abfd)->stringlen += strlen (name) + 1;
00298            else
00299              {
00300               asymbol *s;
00301               char *n = new_symbol_string (abfd, name);
00302 
00303               s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n,
00304                                     val, sec);
00305               s->flags |= BSF_GLOBAL;
00306              }
00307          }
00308          break;
00309        }
00310     }
00311 }
00312 
00313 #define R_RELWORD     1
00314 #define R_RELLONG     2
00315 #define R_RELWORD_NEG 3
00316 #define R_RELLONG_NEG 4
00317 
00318 reloc_howto_type versados_howto_table[] =
00319 {
00320   HOWTO (R_RELWORD, 0, 1, 16, FALSE,
00321         0, complain_overflow_dont, 0,
00322         "+v16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00323   HOWTO (R_RELLONG, 0, 2, 32, FALSE,
00324         0, complain_overflow_dont, 0,
00325         "+v32", TRUE, 0xffffffff, 0xffffffff, FALSE),
00326 
00327   HOWTO (R_RELWORD_NEG, 0, -1, 16, FALSE,
00328         0, complain_overflow_dont, 0,
00329         "-v16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00330   HOWTO (R_RELLONG_NEG, 0, -2, 32, FALSE,
00331         0, complain_overflow_dont, 0,
00332         "-v32", TRUE, 0xffffffff, 0xffffffff, FALSE),
00333 };
00334 
00335 static int
00336 get_offset (int len, unsigned char *ptr)
00337 {
00338   int val = 0;
00339 
00340   if (len)
00341     {
00342       int i;
00343 
00344       val = *ptr++;
00345       if (val & 0x80)
00346        val |= ~0xff;
00347       for (i = 1; i < len; i++)
00348        val = (val << 8) | *ptr++;
00349     }
00350 
00351   return val;
00352 }
00353 
00354 static void
00355 process_otr (bfd *abfd, struct ext_otr *otr, int pass)
00356 {
00357   unsigned long shift;
00358   unsigned char *srcp = otr->data;
00359   unsigned char *endp = (unsigned char *) otr + otr->size;
00360   unsigned int bits = (otr->map[0] << 24)
00361   | (otr->map[1] << 16)
00362   | (otr->map[2] << 8)
00363   | (otr->map[3] << 0);
00364 
00365   struct esdid *esdid = &EDATA (abfd, otr->esdid - 1);
00366   unsigned char *contents = esdid->contents;
00367   int need_contents = 0;
00368   unsigned int dst_idx = esdid->pc;
00369 
00370   for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1)
00371     {
00372       if (bits & shift)
00373        {
00374          int flag = *srcp++;
00375          int esdids = (flag >> 5) & 0x7;
00376          int sizeinwords = ((flag >> 3) & 1) ? 2 : 1;
00377          int offsetlen = flag & 0x7;
00378          int j;
00379 
00380          if (esdids == 0)
00381            {
00382              /* A zero esdid means the new pc is the offset given.  */
00383              dst_idx += get_offset (offsetlen, srcp);
00384              srcp += offsetlen;
00385            }
00386          else
00387            {
00388              int val = get_offset (offsetlen, srcp + esdids);
00389 
00390              if (pass == 1)
00391               need_contents = 1;
00392              else
00393               for (j = 0; j < sizeinwords * 2; j++)
00394                 {
00395                   contents[dst_idx + (sizeinwords * 2) - j - 1] = val;
00396                   val >>= 8;
00397                 }
00398 
00399              for (j = 0; j < esdids; j++)
00400               {
00401                 int esdid = *srcp++;
00402 
00403                 if (esdid)
00404                   {
00405                     int rn = EDATA (abfd, otr->esdid - 1).relocs++;
00406 
00407                     if (pass == 1)
00408                      {
00409                        /* This is the first pass over the data,
00410                           just remember that we need a reloc.  */
00411                      }
00412                     else
00413                      {
00414                        arelent *n =
00415                        EDATA (abfd, otr->esdid - 1).section->relocation + rn;
00416                        n->address = dst_idx;
00417 
00418                        n->sym_ptr_ptr = (asymbol **) (size_t) esdid;
00419                        n->addend = 0;
00420                        n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1);
00421                      }
00422                   }
00423               }
00424              srcp += offsetlen;
00425              dst_idx += sizeinwords * 2;
00426            }
00427        }
00428       else
00429        {
00430          need_contents = 1;
00431          if (dst_idx < esdid->section->size)
00432            if (pass == 2)
00433              {
00434               /* Absolute code, comes in 16 bit lumps.  */
00435               contents[dst_idx] = srcp[0];
00436               contents[dst_idx + 1] = srcp[1];
00437              }
00438          dst_idx += 2;
00439          srcp += 2;
00440        }
00441     }
00442   EDATA (abfd, otr->esdid - 1).pc = dst_idx;
00443 
00444   if (!contents && need_contents)
00445     {
00446       bfd_size_type size = esdid->section->size;
00447       esdid->contents = bfd_alloc (abfd, size);
00448     }
00449 }
00450 
00451 static bfd_boolean
00452 versados_scan (bfd *abfd)
00453 {
00454   int loop = 1;
00455   int i;
00456   int j;
00457   int nsecs = 0;
00458   bfd_size_type amt;
00459 
00460   VDATA (abfd)->stringlen = 0;
00461   VDATA (abfd)->nrefs = 0;
00462   VDATA (abfd)->ndefs = 0;
00463   VDATA (abfd)->ref_idx = 0;
00464   VDATA (abfd)->def_idx = 0;
00465   VDATA (abfd)->pass_2_done = 0;
00466 
00467   while (loop)
00468     {
00469       union ext_any any;
00470 
00471       if (!get_record (abfd, &any))
00472        return TRUE;
00473       switch (any.header.type)
00474        {
00475        case VHEADER:
00476          break;
00477        case VEND:
00478          loop = 0;
00479          break;
00480        case VESTDEF:
00481          process_esd (abfd, &any.esd, 1);
00482          break;
00483        case VOTR:
00484          process_otr (abfd, &any.otr, 1);
00485          break;
00486        }
00487     }
00488 
00489   /* Now allocate space for the relocs and sections.  */
00490   VDATA (abfd)->nrefs = VDATA (abfd)->ref_idx;
00491   VDATA (abfd)->ndefs = VDATA (abfd)->def_idx;
00492   VDATA (abfd)->ref_idx = 0;
00493   VDATA (abfd)->def_idx = 0;
00494 
00495   abfd->symcount = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs;
00496 
00497   for (i = 0; i < 16; i++)
00498     {
00499       struct esdid *esdid = &EDATA (abfd, i);
00500 
00501       if (esdid->section)
00502        {
00503          amt = (bfd_size_type) esdid->relocs * sizeof (arelent);
00504          esdid->section->relocation = bfd_alloc (abfd, amt);
00505 
00506          esdid->pc = 0;
00507 
00508          if (esdid->contents)
00509            esdid->section->flags |= SEC_HAS_CONTENTS | SEC_LOAD;
00510 
00511          esdid->section->reloc_count = esdid->relocs;
00512          if (esdid->relocs)
00513            esdid->section->flags |= SEC_RELOC;
00514 
00515          esdid->relocs = 0;
00516 
00517          /* Add an entry into the symbol table for it.  */
00518          nsecs++;
00519          VDATA (abfd)->stringlen += strlen (esdid->section->name) + 1;
00520        }
00521     }
00522 
00523   abfd->symcount += nsecs;
00524 
00525   amt = abfd->symcount;
00526   amt *= sizeof (asymbol);
00527   VDATA (abfd)->symbols = bfd_alloc (abfd, amt);
00528 
00529   amt = VDATA (abfd)->stringlen;
00530   VDATA (abfd)->strings = bfd_alloc (abfd, amt);
00531 
00532   if ((VDATA (abfd)->symbols == NULL && abfd->symcount > 0)
00533       || (VDATA (abfd)->strings == NULL && VDATA (abfd)->stringlen > 0))
00534     return FALSE;
00535 
00536   /* Actually fill in the section symbols,
00537      we stick them at the end of the table.  */
00538   for (j = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs, i = 0; i < 16; i++)
00539     {
00540       struct esdid *esdid = &EDATA (abfd, i);
00541       asection *sec = esdid->section;
00542 
00543       if (sec)
00544        {
00545          asymbol *s = VDATA (abfd)->symbols + j;
00546          s->name = new_symbol_string (abfd, sec->name);
00547          s->section = sec;
00548          s->flags = BSF_LOCAL;
00549          s->value = 0;
00550          s->the_bfd = abfd;
00551          j++;
00552        }
00553     }
00554 
00555   if (abfd->symcount)
00556     abfd->flags |= HAS_SYMS;
00557 
00558   /* Set this to nsecs - since we've already planted the section
00559      symbols.  */
00560   VDATA (abfd)->nsecsyms = nsecs;
00561 
00562   VDATA (abfd)->ref_idx = 0;
00563 
00564   return 1;
00565 }
00566 
00567 /* Check whether an existing file is a versados  file.  */
00568 
00569 static const bfd_target *
00570 versados_object_p (bfd *abfd)
00571 {
00572   struct ext_vheader ext;
00573   unsigned char len;
00574   tdata_type *tdata_save;
00575 
00576   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
00577     return NULL;
00578 
00579   if (bfd_bread (&len, (bfd_size_type) 1, abfd) != 1)
00580     {
00581       if (bfd_get_error () != bfd_error_system_call)
00582        bfd_set_error (bfd_error_wrong_format);
00583       return NULL;
00584     }
00585 
00586   if (bfd_bread (&ext.type, (bfd_size_type) len, abfd) != len)
00587     {
00588       if (bfd_get_error () != bfd_error_system_call)
00589        bfd_set_error (bfd_error_wrong_format);
00590       return NULL;
00591     }
00592 
00593   /* We guess that the language field will never be larger than 10.
00594      In sample files, it is always either 0 or 1.  Checking for this
00595      prevents confusion with Intel Hex files.  */
00596   if (ext.type != VHEADER
00597       || ext.lang > 10)
00598     {
00599       bfd_set_error (bfd_error_wrong_format);
00600       return NULL;
00601     }
00602 
00603   /* OK, looks like a record, build the tdata and read in.  */
00604   tdata_save = abfd->tdata.versados_data;
00605   if (!versados_mkobject (abfd) || !versados_scan (abfd))
00606     {
00607       abfd->tdata.versados_data = tdata_save;
00608       return NULL;
00609     }
00610 
00611   return abfd->xvec;
00612 }
00613 
00614 static bfd_boolean
00615 versados_pass_2 (bfd *abfd)
00616 {
00617   union ext_any any;
00618 
00619   if (VDATA (abfd)->pass_2_done)
00620     return 1;
00621 
00622   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
00623     return 0;
00624 
00625   VDATA (abfd)->es_done = ES_BASE;
00626 
00627   /* Read records till we get to where we want to be.  */
00628   while (1)
00629     {
00630       get_record (abfd, &any);
00631       switch (any.header.type)
00632        {
00633        case VEND:
00634          VDATA (abfd)->pass_2_done = 1;
00635          return 1;
00636        case VESTDEF:
00637          process_esd (abfd, &any.esd, 2);
00638          break;
00639        case VOTR:
00640          process_otr (abfd, &any.otr, 2);
00641          break;
00642        }
00643     }
00644 }
00645 
00646 static bfd_boolean
00647 versados_get_section_contents (bfd *abfd,
00648                             asection *section,
00649                             void * location,
00650                             file_ptr offset,
00651                             bfd_size_type count)
00652 {
00653   if (!versados_pass_2 (abfd))
00654     return FALSE;
00655 
00656   memcpy (location,
00657          EDATA (abfd, section->target_index).contents + offset,
00658          (size_t) count);
00659 
00660   return TRUE;
00661 }
00662 
00663 #define versados_get_section_contents_in_window \
00664   _bfd_generic_get_section_contents_in_window
00665 
00666 static bfd_boolean
00667 versados_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
00668                             sec_ptr section ATTRIBUTE_UNUSED,
00669                             const void * location ATTRIBUTE_UNUSED,
00670                             file_ptr offset ATTRIBUTE_UNUSED,
00671                             bfd_size_type bytes_to_do ATTRIBUTE_UNUSED)
00672 {
00673   return FALSE;
00674 }
00675 
00676 static int
00677 versados_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
00678                       struct bfd_link_info *info ATTRIBUTE_UNUSED)
00679 {
00680   return 0;
00681 }
00682 
00683 /* Return the amount of memory needed to read the symbol table.  */
00684 
00685 static long
00686 versados_get_symtab_upper_bound (bfd *abfd)
00687 {
00688   return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
00689 }
00690 
00691 /* Return the symbol table.  */
00692 
00693 static long
00694 versados_canonicalize_symtab (bfd *abfd, asymbol **alocation)
00695 {
00696   unsigned int symcount = bfd_get_symcount (abfd);
00697   unsigned int i;
00698   asymbol *s;
00699 
00700   versados_pass_2 (abfd);
00701 
00702   for (i = 0, s = VDATA (abfd)->symbols;
00703        i < symcount;
00704        s++, i++)
00705     *alocation++ = s;
00706 
00707   *alocation = NULL;
00708 
00709   return symcount;
00710 }
00711 
00712 static void
00713 versados_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
00714                        asymbol *symbol,
00715                        symbol_info *ret)
00716 {
00717   bfd_symbol_info (symbol, ret);
00718 }
00719 
00720 static void
00721 versados_print_symbol (bfd *abfd,
00722                      void * afile,
00723                      asymbol *symbol,
00724                      bfd_print_symbol_type how)
00725 {
00726   FILE *file = (FILE *) afile;
00727 
00728   switch (how)
00729     {
00730     case bfd_print_symbol_name:
00731       fprintf (file, "%s", symbol->name);
00732       break;
00733     default:
00734       bfd_print_symbol_vandf (abfd, (void *) file, symbol);
00735       fprintf (file, " %-5s %s",
00736               symbol->section->name,
00737               symbol->name);
00738     }
00739 }
00740 
00741 static long
00742 versados_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
00743                             sec_ptr asect)
00744 {
00745   return (asect->reloc_count + 1) * sizeof (arelent *);
00746 }
00747 
00748 static long
00749 versados_canonicalize_reloc (bfd *abfd,
00750                           sec_ptr section,
00751                           arelent **relptr,
00752                           asymbol **symbols)
00753 {
00754   unsigned int count;
00755   arelent *src;
00756 
00757   versados_pass_2 (abfd);
00758   src = section->relocation;
00759   if (!EDATA (abfd, section->target_index).donerel)
00760     {
00761       EDATA (abfd, section->target_index).donerel = 1;
00762       /* Translate from indexes to symptr ptrs.  */
00763       for (count = 0; count < section->reloc_count; count++)
00764        {
00765          int esdid = (int) (size_t) src[count].sym_ptr_ptr;
00766 
00767          if (esdid == 0)
00768            src[count].sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
00769          else if (esdid < ES_BASE)
00770            {
00771              /* Section relative thing.  */
00772              struct esdid *e = &EDATA (abfd, esdid - 1);
00773 
00774              src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr;
00775            }
00776          else
00777            src[count].sym_ptr_ptr = symbols + esdid - ES_BASE;
00778        }
00779     }
00780 
00781   for (count = 0; count < section->reloc_count; count++)
00782     *relptr++ = src++;
00783 
00784   *relptr = 0;
00785   return section->reloc_count;
00786 }
00787 
00788 #define       versados_close_and_cleanup                    _bfd_generic_close_and_cleanup
00789 #define versados_bfd_free_cached_info                 _bfd_generic_bfd_free_cached_info
00790 #define versados_new_section_hook                     _bfd_generic_new_section_hook
00791 #define versados_bfd_is_target_special_symbol   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
00792 #define versados_bfd_is_local_label_name              bfd_generic_is_local_label_name
00793 #define versados_get_lineno                           _bfd_nosymbols_get_lineno
00794 #define versados_find_nearest_line                    _bfd_nosymbols_find_nearest_line
00795 #define versados_find_inliner_info                    _bfd_nosymbols_find_inliner_info
00796 #define versados_make_empty_symbol                    _bfd_generic_make_empty_symbol
00797 #define versados_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
00798 #define versados_read_minisymbols                     _bfd_generic_read_minisymbols
00799 #define versados_minisymbol_to_symbol                 _bfd_generic_minisymbol_to_symbol
00800 #define versados_bfd_reloc_type_lookup                _bfd_norelocs_bfd_reloc_type_lookup
00801 #define versados_bfd_reloc_name_lookup          _bfd_norelocs_bfd_reloc_name_lookup
00802 #define versados_set_arch_mach                        bfd_default_set_arch_mach
00803 #define versados_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
00804 #define versados_bfd_relax_section                    bfd_generic_relax_section
00805 #define versados_bfd_gc_sections                      bfd_generic_gc_sections
00806 #define versados_bfd_merge_sections                   bfd_generic_merge_sections
00807 #define versados_bfd_is_group_section                 bfd_generic_is_group_section
00808 #define versados_bfd_discard_group                    bfd_generic_discard_group
00809 #define versados_section_already_linked               _bfd_generic_section_already_linked
00810 #define versados_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
00811 #define versados_bfd_link_hash_table_free             _bfd_generic_link_hash_table_free
00812 #define versados_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
00813 #define versados_bfd_link_just_syms                   _bfd_generic_link_just_syms
00814 #define versados_bfd_final_link                       _bfd_generic_final_link
00815 #define versados_bfd_link_split_section               _bfd_generic_link_split_section
00816 
00817 const bfd_target versados_vec =
00818 {
00819   "versados",               /* Name.  */
00820   bfd_target_versados_flavour,
00821   BFD_ENDIAN_BIG,           /* Target byte order.  */
00822   BFD_ENDIAN_BIG,           /* Target headers byte order.  */
00823   (HAS_RELOC | EXEC_P |            /* Object flags.  */
00824    HAS_LINENO | HAS_DEBUG |
00825    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00826   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
00827    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),          /* Section flags.  */
00828   0,                        /* Leading underscore.  */
00829   ' ',                      /* AR_pad_char.  */
00830   16,                       /* AR_max_namelen.  */
00831   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
00832   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
00833   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* Data.  */
00834   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
00835   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
00836   bfd_getb16, bfd_getb_signed_16, bfd_putb16,    /* Headers.  */
00837 
00838   {
00839     _bfd_dummy_target,
00840     versados_object_p,             /* bfd_check_format.  */
00841     _bfd_dummy_target,
00842     _bfd_dummy_target,
00843   },
00844   {
00845     bfd_false,
00846     versados_mkobject,
00847     _bfd_generic_mkarchive,
00848     bfd_false,
00849   },
00850   {                         /* bfd_write_contents.  */
00851     bfd_false,
00852     bfd_false,
00853     _bfd_write_archive_contents,
00854     bfd_false,
00855   },
00856 
00857   BFD_JUMP_TABLE_GENERIC (versados),
00858   BFD_JUMP_TABLE_COPY (_bfd_generic),
00859   BFD_JUMP_TABLE_CORE (_bfd_nocore),
00860   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
00861   BFD_JUMP_TABLE_SYMBOLS (versados),
00862   BFD_JUMP_TABLE_RELOCS (versados),
00863   BFD_JUMP_TABLE_WRITE (versados),
00864   BFD_JUMP_TABLE_LINK (versados),
00865   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00866 
00867   NULL,
00868 
00869   NULL
00870 };