1/* BFD back-end for Intel 386 COFF files.
2   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3   2000, 2001, 2002, 2003, 2004
4   Free Software Foundation, Inc.
5   Written by Cygnus Support.
6
7   This file is part of BFD, the Binary File Descriptor library.
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22
23#include "bfd.h"
24#include "sysdep.h"
25#include "libbfd.h"
26
27#include "coff/i386.h"
28
29#include "coff/internal.h"
30
31#ifdef COFF_WITH_PE
32#include "coff/pe.h"
33#endif
34
35#ifdef COFF_GO32_EXE
36#include "coff/go32exe.h"
37#endif
38
39#include "libcoff.h"
40
41static bfd_reloc_status_type coff_i386_reloc
42  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
43static reloc_howto_type *coff_i386_rtype_to_howto
44  PARAMS ((bfd *, asection *, struct internal_reloc *,
45	   struct coff_link_hash_entry *, struct internal_syment *,
46	   bfd_vma *));
47static reloc_howto_type *coff_i386_reloc_type_lookup
48  PARAMS ((bfd *, bfd_reloc_code_real_type));
49
50#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
51/* The page size is a guess based on ELF.  */
52
53#define COFF_PAGE_SIZE 0x1000
54
55/* For some reason when using i386 COFF the value stored in the .text
56   section for a reference to a common symbol is the value itself plus
57   any desired offset.  Ian Taylor, Cygnus Support.  */
58
59/* If we are producing relocatable output, we need to do some
60   adjustments to the object file that are not done by the
61   bfd_perform_relocation function.  This function is called by every
62   reloc type to make any required adjustments.  */
63
64static bfd_reloc_status_type
65coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
66		 error_message)
67     bfd *abfd;
68     arelent *reloc_entry;
69     asymbol *symbol;
70     PTR data;
71     asection *input_section ATTRIBUTE_UNUSED;
72     bfd *output_bfd;
73     char **error_message ATTRIBUTE_UNUSED;
74{
75  symvalue diff;
76
77#ifndef COFF_WITH_PE
78  if (output_bfd == (bfd *) NULL)
79    return bfd_reloc_continue;
80#endif
81
82  if (bfd_is_com_section (symbol->section))
83    {
84#ifndef COFF_WITH_PE
85      /* We are relocating a common symbol.  The current value in the
86	 object file is ORIG + OFFSET, where ORIG is the value of the
87	 common symbol as seen by the object file when it was compiled
88	 (this may be zero if the symbol was undefined) and OFFSET is
89	 the offset into the common symbol (normally zero, but may be
90	 non-zero when referring to a field in a common structure).
91	 ORIG is the negative of reloc_entry->addend, which is set by
92	 the CALC_ADDEND macro below.  We want to replace the value in
93	 the object file with NEW + OFFSET, where NEW is the value of
94	 the common symbol which we are going to put in the final
95	 object file.  NEW is symbol->value.  */
96      diff = symbol->value + reloc_entry->addend;
97#else
98      /* In PE mode, we do not offset the common symbol.  */
99      diff = reloc_entry->addend;
100#endif
101    }
102  else
103    {
104      /* For some reason bfd_perform_relocation always effectively
105	 ignores the addend for a COFF target when producing
106	 relocatable output.  This seems to be always wrong for 386
107	 COFF, so we handle the addend here instead.  */
108#ifdef COFF_WITH_PE
109      if (output_bfd == (bfd *) NULL)
110	{
111	  reloc_howto_type *howto = reloc_entry->howto;
112
113	  /* Although PC relative relocations are very similar between
114	     PE and non-PE formats, but they are off by 1 << howto->size
115	     bytes. For the external relocation, PE is very different
116	     from others. See md_apply_fix3 () in gas/config/tc-i386.c.
117	     When we link PE and non-PE object files together to
118	     generate a non-PE executable, we have to compensate it
119	     here.  */
120	  if (howto->pc_relative && howto->pcrel_offset)
121	    diff = -(1 << howto->size);
122	  else if (symbol->flags & BSF_WEAK)
123	    diff = reloc_entry->addend - symbol->value;
124	  else
125	    diff = -reloc_entry->addend;
126	}
127      else
128#endif
129	diff = reloc_entry->addend;
130    }
131
132#ifdef COFF_WITH_PE
133  /* FIXME: How should this case be handled?  */
134  if (reloc_entry->howto->type == R_IMAGEBASE
135      && output_bfd != NULL
136      && bfd_get_flavour(output_bfd) == bfd_target_coff_flavour)
137    diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
138#endif
139
140#define DOIT(x) \
141  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
142
143    if (diff != 0)
144      {
145	reloc_howto_type *howto = reloc_entry->howto;
146	unsigned char *addr = (unsigned char *) data + reloc_entry->address;
147
148	switch (howto->size)
149	  {
150	  case 0:
151	    {
152	      char x = bfd_get_8 (abfd, addr);
153	      DOIT (x);
154	      bfd_put_8 (abfd, x, addr);
155	    }
156	    break;
157
158	  case 1:
159	    {
160	      short x = bfd_get_16 (abfd, addr);
161	      DOIT (x);
162	      bfd_put_16 (abfd, (bfd_vma) x, addr);
163	    }
164	    break;
165
166	  case 2:
167	    {
168	      long x = bfd_get_32 (abfd, addr);
169	      DOIT (x);
170	      bfd_put_32 (abfd, (bfd_vma) x, addr);
171	    }
172	    break;
173
174	  default:
175	    abort ();
176	  }
177      }
178
179  /* Now let bfd_perform_relocation finish everything up.  */
180  return bfd_reloc_continue;
181}
182
183#ifdef COFF_WITH_PE
184/* Return TRUE if this relocation should appear in the output .reloc
185   section.  */
186
187static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
188
189static bfd_boolean in_reloc_p (abfd, howto)
190     bfd * abfd ATTRIBUTE_UNUSED;
191     reloc_howto_type *howto;
192{
193  return ! howto->pc_relative && howto->type != R_IMAGEBASE;
194}
195#endif /* COFF_WITH_PE */
196
197#ifndef PCRELOFFSET
198#define PCRELOFFSET FALSE
199#endif
200
201static reloc_howto_type howto_table[] =
202{
203  EMPTY_HOWTO (0),
204  EMPTY_HOWTO (1),
205  EMPTY_HOWTO (2),
206  EMPTY_HOWTO (3),
207  EMPTY_HOWTO (4),
208  EMPTY_HOWTO (5),
209  HOWTO (R_DIR32,		/* type */
210	 0,			/* rightshift */
211	 2,			/* size (0 = byte, 1 = short, 2 = long) */
212	 32,			/* bitsize */
213	 FALSE,			/* pc_relative */
214	 0,			/* bitpos */
215	 complain_overflow_bitfield, /* complain_on_overflow */
216	 coff_i386_reloc,	/* special_function */
217	 "dir32",		/* name */
218	 TRUE,			/* partial_inplace */
219	 0xffffffff,		/* src_mask */
220	 0xffffffff,		/* dst_mask */
221	 TRUE),			/* pcrel_offset */
222  /* PE IMAGE_REL_I386_DIR32NB relocation (7).	*/
223  HOWTO (R_IMAGEBASE,		/* type */
224	 0,			/* rightshift */
225	 2,			/* size (0 = byte, 1 = short, 2 = long) */
226	 32,			/* bitsize */
227	 FALSE,			/* pc_relative */
228	 0,			/* bitpos */
229	 complain_overflow_bitfield, /* complain_on_overflow */
230	 coff_i386_reloc,	/* special_function */
231	 "rva32",		/* name */
232	 TRUE,			/* partial_inplace */
233	 0xffffffff,		/* src_mask */
234	 0xffffffff,		/* dst_mask */
235	 FALSE),		/* pcrel_offset */
236  EMPTY_HOWTO (010),
237  EMPTY_HOWTO (011),
238  EMPTY_HOWTO (012),
239#ifdef COFF_WITH_PE
240  /* 32-bit longword section relative relocation (013).  */
241  HOWTO (R_SECREL32,		/* type */
242	 0,			/* rightshift */
243	 2,			/* size (0 = byte, 1 = short, 2 = long) */
244	 32,			/* bitsize */
245	 FALSE,			/* pc_relative */
246	 0,			/* bitpos */
247	 complain_overflow_bitfield, /* complain_on_overflow */
248	 coff_i386_reloc,	/* special_function */
249	 "secrel32",		/* name */
250	 TRUE,			/* partial_inplace */
251	 0xffffffff,		/* src_mask */
252	 0xffffffff,		/* dst_mask */
253	 TRUE),			/* pcrel_offset */
254#else
255  EMPTY_HOWTO (013),
256#endif
257  EMPTY_HOWTO (014),
258  EMPTY_HOWTO (015),
259  EMPTY_HOWTO (016),
260  /* Byte relocation (017).  */
261  HOWTO (R_RELBYTE,		/* type */
262	 0,			/* rightshift */
263	 0,			/* size (0 = byte, 1 = short, 2 = long) */
264	 8,			/* bitsize */
265	 FALSE,			/* pc_relative */
266	 0,			/* bitpos */
267	 complain_overflow_bitfield, /* complain_on_overflow */
268	 coff_i386_reloc,	/* special_function */
269	 "8",			/* name */
270	 TRUE,			/* partial_inplace */
271	 0x000000ff,		/* src_mask */
272	 0x000000ff,		/* dst_mask */
273	 PCRELOFFSET),		/* pcrel_offset */
274  /* 16-bit word relocation (020).  */
275  HOWTO (R_RELWORD,		/* type */
276	 0,			/* rightshift */
277	 1,			/* size (0 = byte, 1 = short, 2 = long) */
278	 16,			/* bitsize */
279	 FALSE,			/* pc_relative */
280	 0,			/* bitpos */
281	 complain_overflow_bitfield, /* complain_on_overflow */
282	 coff_i386_reloc,	/* special_function */
283	 "16",			/* name */
284	 TRUE,			/* partial_inplace */
285	 0x0000ffff,		/* src_mask */
286	 0x0000ffff,		/* dst_mask */
287	 PCRELOFFSET),		/* pcrel_offset */
288  /* 32-bit longword relocation (021).	*/
289  HOWTO (R_RELLONG,		/* type */
290	 0,			/* rightshift */
291	 2,			/* size (0 = byte, 1 = short, 2 = long) */
292	 32,			/* bitsize */
293	 FALSE,			/* pc_relative */
294	 0,			/* bitpos */
295	 complain_overflow_bitfield, /* complain_on_overflow */
296	 coff_i386_reloc,	/* special_function */
297	 "32",			/* name */
298	 TRUE,			/* partial_inplace */
299	 0xffffffff,		/* src_mask */
300	 0xffffffff,		/* dst_mask */
301	 PCRELOFFSET),		/* pcrel_offset */
302  /* Byte PC relative relocation (022).	 */
303  HOWTO (R_PCRBYTE,		/* type */
304	 0,			/* rightshift */
305	 0,			/* size (0 = byte, 1 = short, 2 = long) */
306	 8,			/* bitsize */
307	 TRUE,			/* pc_relative */
308	 0,			/* bitpos */
309	 complain_overflow_signed, /* complain_on_overflow */
310	 coff_i386_reloc,	/* special_function */
311	 "DISP8",		/* name */
312	 TRUE,			/* partial_inplace */
313	 0x000000ff,		/* src_mask */
314	 0x000000ff,		/* dst_mask */
315	 PCRELOFFSET),		/* pcrel_offset */
316  /* 16-bit word PC relative relocation (023).	*/
317  HOWTO (R_PCRWORD,		/* type */
318	 0,			/* rightshift */
319	 1,			/* size (0 = byte, 1 = short, 2 = long) */
320	 16,			/* bitsize */
321	 TRUE,			/* pc_relative */
322	 0,			/* bitpos */
323	 complain_overflow_signed, /* complain_on_overflow */
324	 coff_i386_reloc,	/* special_function */
325	 "DISP16",		/* name */
326	 TRUE,			/* partial_inplace */
327	 0x0000ffff,		/* src_mask */
328	 0x0000ffff,		/* dst_mask */
329	 PCRELOFFSET),		/* pcrel_offset */
330  /* 32-bit longword PC relative relocation (024).  */
331  HOWTO (R_PCRLONG,		/* type */
332	 0,			/* rightshift */
333	 2,			/* size (0 = byte, 1 = short, 2 = long) */
334	 32,			/* bitsize */
335	 TRUE,			/* pc_relative */
336	 0,			/* bitpos */
337	 complain_overflow_signed, /* complain_on_overflow */
338	 coff_i386_reloc,	/* special_function */
339	 "DISP32",		/* name */
340	 TRUE,			/* partial_inplace */
341	 0xffffffff,		/* src_mask */
342	 0xffffffff,		/* dst_mask */
343	 PCRELOFFSET)		/* pcrel_offset */
344};
345
346/* Turn a howto into a reloc  nunmber */
347
348#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
349#define BADMAG(x) I386BADMAG(x)
350#define I386 1			/* Customize coffcode.h */
351
352#define RTYPE2HOWTO(cache_ptr, dst)					\
353  ((cache_ptr)->howto =							\
354   ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])	\
355    ? howto_table + (dst)->r_type					\
356    : NULL))
357
358/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
359   library.  On some other COFF targets STYP_BSS is normally
360   STYP_NOLOAD.  */
361#define BSS_NOLOAD_IS_SHARED_LIBRARY
362
363/* Compute the addend of a reloc.  If the reloc is to a common symbol,
364   the object file contains the value of the common symbol.  By the
365   time this is called, the linker may be using a different symbol
366   from a different object file with a different value.  Therefore, we
367   hack wildly to locate the original symbol from this file so that we
368   can make the correct adjustment.  This macro sets coffsym to the
369   symbol from the original file, and uses it to set the addend value
370   correctly.  If this is not a common symbol, the usual addend
371   calculation is done, except that an additional tweak is needed for
372   PC relative relocs.
373   FIXME: This macro refers to symbols and asect; these are from the
374   calling function, not the macro arguments.  */
375
376#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)		\
377  {								\
378    coff_symbol_type *coffsym = (coff_symbol_type *) NULL;	\
379    if (ptr && bfd_asymbol_bfd (ptr) != abfd)			\
380      coffsym = (obj_symbols (abfd)				\
381	         + (cache_ptr->sym_ptr_ptr - symbols));		\
382    else if (ptr)						\
383      coffsym = coff_symbol_from (abfd, ptr);			\
384    if (coffsym != (coff_symbol_type *) NULL			\
385	&& coffsym->native->u.syment.n_scnum == 0)		\
386      cache_ptr->addend = - coffsym->native->u.syment.n_value;	\
387    else if (ptr && bfd_asymbol_bfd (ptr) == abfd		\
388	     && ptr->section != (asection *) NULL)		\
389      cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
390    else							\
391      cache_ptr->addend = 0;					\
392    if (ptr && howto_table[reloc.r_type].pc_relative)		\
393      cache_ptr->addend += asect->vma;				\
394  }
395
396/* We use the special COFF backend linker.  For normal i386 COFF, we
397   can use the generic relocate_section routine.  For PE, we need our
398   own routine.  */
399
400#ifndef COFF_WITH_PE
401
402#define coff_relocate_section _bfd_coff_generic_relocate_section
403
404#else /* COFF_WITH_PE */
405
406/* The PE relocate section routine.  The only difference between this
407   and the regular routine is that we don't want to do anything for a
408   relocatable link.  */
409
410static bfd_boolean coff_pe_i386_relocate_section
411  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
412	   struct internal_reloc *, struct internal_syment *, asection **));
413
414static bfd_boolean
415coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
416			       input_section, contents, relocs, syms,
417			       sections)
418     bfd *output_bfd;
419     struct bfd_link_info *info;
420     bfd *input_bfd;
421     asection *input_section;
422     bfd_byte *contents;
423     struct internal_reloc *relocs;
424     struct internal_syment *syms;
425     asection **sections;
426{
427  if (info->relocatable)
428    return TRUE;
429
430  return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
431					     input_section, contents,
432					     relocs, syms, sections);
433}
434
435#define coff_relocate_section coff_pe_i386_relocate_section
436
437#endif /* COFF_WITH_PE */
438
439/* Convert an rtype to howto for the COFF backend linker.  */
440
441static reloc_howto_type *
442coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
443     bfd *abfd ATTRIBUTE_UNUSED;
444     asection *sec;
445     struct internal_reloc *rel;
446     struct coff_link_hash_entry *h;
447     struct internal_syment *sym;
448     bfd_vma *addendp;
449{
450  reloc_howto_type *howto;
451
452  if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
453    {
454      bfd_set_error (bfd_error_bad_value);
455      return NULL;
456    }
457
458  howto = howto_table + rel->r_type;
459
460#ifdef COFF_WITH_PE
461  /* Cancel out code in _bfd_coff_generic_relocate_section.  */
462  *addendp = 0;
463#endif
464
465  if (howto->pc_relative)
466    *addendp += sec->vma;
467
468  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
469    {
470      /* This is a common symbol.  The section contents include the
471	 size (sym->n_value) as an addend.  The relocate_section
472	 function will be adding in the final value of the symbol.  We
473	 need to subtract out the current size in order to get the
474	 correct result.  */
475
476      BFD_ASSERT (h != NULL);
477
478#ifndef COFF_WITH_PE
479      /* I think we *do* want to bypass this.  If we don't, I have
480	 seen some data parameters get the wrong relocation address.
481	 If I link two versions with and without this section bypassed
482	 and then do a binary comparison, the addresses which are
483	 different can be looked up in the map.  The case in which
484	 this section has been bypassed has addresses which correspond
485	 to values I can find in the map.  */
486      *addendp -= sym->n_value;
487#endif
488    }
489
490#ifndef COFF_WITH_PE
491  /* If the output symbol is common (in which case this must be a
492     relocatable link), we need to add in the final size of the
493     common symbol.  */
494  if (h != NULL && h->root.type == bfd_link_hash_common)
495    *addendp += h->root.u.c.size;
496#endif
497
498#ifdef COFF_WITH_PE
499  if (howto->pc_relative)
500    {
501      *addendp -= 4;
502
503      /* If the symbol is defined, then the generic code is going to
504         add back the symbol value in order to cancel out an
505         adjustment it made to the addend.  However, we set the addend
506         to 0 at the start of this function.  We need to adjust here,
507         to avoid the adjustment the generic code will make.  FIXME:
508         This is getting a bit hackish.  */
509      if (sym != NULL && sym->n_scnum != 0)
510	*addendp -= sym->n_value;
511    }
512
513  if (rel->r_type == R_IMAGEBASE
514      && (bfd_get_flavour(sec->output_section->owner)
515	  == bfd_target_coff_flavour))
516    {
517      *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
518    }
519
520  if (rel->r_type == R_SECREL32)
521    {
522      bfd_vma osect_vma;
523
524      if (h && (h->type == bfd_link_hash_defined
525		|| h->type == bfd_link_hash_defweak))
526	osect_vma = h->root.u.def.section->output_section->vma;
527      else
528	{
529	  asection *sec;
530	  int i;
531
532	  /* Sigh, the only way to get the section to offset against
533	     is to find it the hard way.  */
534
535	  for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
536	    sec = sec->next;
537
538	  osect_vma = sec->output_section->vma;
539	}
540
541      *addendp -= osect_vma;
542    }
543#endif
544
545  return howto;
546}
547
548#define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
549
550static reloc_howto_type *
551coff_i386_reloc_type_lookup (abfd, code)
552     bfd *abfd ATTRIBUTE_UNUSED;
553     bfd_reloc_code_real_type code;
554{
555  switch (code)
556    {
557    case BFD_RELOC_RVA:
558      return howto_table + R_IMAGEBASE;
559    case BFD_RELOC_32:
560      return howto_table + R_DIR32;
561    case BFD_RELOC_32_PCREL:
562      return howto_table + R_PCRLONG;
563    case BFD_RELOC_16:
564      return howto_table + R_RELWORD;
565    case BFD_RELOC_16_PCREL:
566      return howto_table + R_PCRWORD;
567    case BFD_RELOC_8:
568      return howto_table + R_RELBYTE;
569    case BFD_RELOC_8_PCREL:
570      return howto_table + R_PCRBYTE;
571#ifdef COFF_WITH_PE
572    case BFD_RELOC_32_SECREL:
573      return howto_table + R_SECREL32;
574#endif
575    default:
576      BFD_FAIL ();
577      return 0;
578    }
579}
580
581#define coff_rtype_to_howto coff_i386_rtype_to_howto
582
583#ifdef TARGET_UNDERSCORE
584
585/* If i386 gcc uses underscores for symbol names, then it does not use
586   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
587   we treat all symbols starting with L as local.  */
588
589static bfd_boolean coff_i386_is_local_label_name
590  PARAMS ((bfd *, const char *));
591
592static bfd_boolean
593coff_i386_is_local_label_name (abfd, name)
594     bfd *abfd;
595     const char *name;
596{
597  if (name[0] == 'L')
598    return TRUE;
599
600  return _bfd_coff_is_local_label_name (abfd, name);
601}
602
603#define coff_bfd_is_local_label_name coff_i386_is_local_label_name
604
605#endif /* TARGET_UNDERSCORE */
606
607#include "coffcode.h"
608
609const bfd_target
610#ifdef TARGET_SYM
611  TARGET_SYM =
612#else
613  i386coff_vec =
614#endif
615{
616#ifdef TARGET_NAME
617  TARGET_NAME,
618#else
619  "coff-i386",			/* name */
620#endif
621  bfd_target_coff_flavour,
622  BFD_ENDIAN_LITTLE,		/* data byte order is little */
623  BFD_ENDIAN_LITTLE,		/* header byte order is little */
624
625  (HAS_RELOC | EXEC_P |		/* object flags */
626   HAS_LINENO | HAS_DEBUG |
627   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
628
629  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
630#ifdef COFF_WITH_PE
631   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
632#endif
633   | SEC_CODE | SEC_DATA),
634
635#ifdef TARGET_UNDERSCORE
636  TARGET_UNDERSCORE,		/* leading underscore */
637#else
638  0,				/* leading underscore */
639#endif
640  '/',				/* ar_pad_char */
641  15,				/* ar_max_namelen */
642
643  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
644     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
645     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
646  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
647     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
648     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
649
650/* Note that we allow an object file to be treated as a core file as well.  */
651    {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
652       bfd_generic_archive_p, coff_object_p},
653    {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
654       bfd_false},
655    {bfd_false, coff_write_object_contents, /* bfd_write_contents */
656       _bfd_write_archive_contents, bfd_false},
657
658     BFD_JUMP_TABLE_GENERIC (coff),
659     BFD_JUMP_TABLE_COPY (coff),
660     BFD_JUMP_TABLE_CORE (_bfd_nocore),
661     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
662     BFD_JUMP_TABLE_SYMBOLS (coff),
663     BFD_JUMP_TABLE_RELOCS (coff),
664     BFD_JUMP_TABLE_WRITE (coff),
665     BFD_JUMP_TABLE_LINK (coff),
666     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
667
668  NULL,
669
670  COFF_SWAP_TABLE
671};
672