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