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, 2007
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 "sysdep.h"
24#include "bfd.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#define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup
550
551static reloc_howto_type *
552coff_i386_reloc_type_lookup (abfd, code)
553     bfd *abfd ATTRIBUTE_UNUSED;
554     bfd_reloc_code_real_type code;
555{
556  switch (code)
557    {
558    case BFD_RELOC_RVA:
559      return howto_table + R_IMAGEBASE;
560    case BFD_RELOC_32:
561      return howto_table + R_DIR32;
562    case BFD_RELOC_32_PCREL:
563      return howto_table + R_PCRLONG;
564    case BFD_RELOC_16:
565      return howto_table + R_RELWORD;
566    case BFD_RELOC_16_PCREL:
567      return howto_table + R_PCRWORD;
568    case BFD_RELOC_8:
569      return howto_table + R_RELBYTE;
570    case BFD_RELOC_8_PCREL:
571      return howto_table + R_PCRBYTE;
572#ifdef COFF_WITH_PE
573    case BFD_RELOC_32_SECREL:
574      return howto_table + R_SECREL32;
575#endif
576    default:
577      BFD_FAIL ();
578      return 0;
579    }
580}
581
582static reloc_howto_type *
583coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
584			     const char *r_name)
585{
586  unsigned int i;
587
588  for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
589    if (howto_table[i].name != NULL
590	&& strcasecmp (howto_table[i].name, r_name) == 0)
591      return &howto_table[i];
592
593  return NULL;
594}
595
596#define coff_rtype_to_howto coff_i386_rtype_to_howto
597
598#ifdef TARGET_UNDERSCORE
599
600/* If i386 gcc uses underscores for symbol names, then it does not use
601   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
602   we treat all symbols starting with L as local.  */
603
604static bfd_boolean coff_i386_is_local_label_name
605  PARAMS ((bfd *, const char *));
606
607static bfd_boolean
608coff_i386_is_local_label_name (abfd, name)
609     bfd *abfd;
610     const char *name;
611{
612  if (name[0] == 'L')
613    return TRUE;
614
615  return _bfd_coff_is_local_label_name (abfd, name);
616}
617
618#define coff_bfd_is_local_label_name coff_i386_is_local_label_name
619
620#endif /* TARGET_UNDERSCORE */
621
622#include "coffcode.h"
623
624const bfd_target
625#ifdef TARGET_SYM
626  TARGET_SYM =
627#else
628  i386coff_vec =
629#endif
630{
631#ifdef TARGET_NAME
632  TARGET_NAME,
633#else
634  "coff-i386",			/* name */
635#endif
636  bfd_target_coff_flavour,
637  BFD_ENDIAN_LITTLE,		/* data byte order is little */
638  BFD_ENDIAN_LITTLE,		/* header byte order is little */
639
640  (HAS_RELOC | EXEC_P |		/* object flags */
641   HAS_LINENO | HAS_DEBUG |
642   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
643
644  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
645#ifdef COFF_WITH_PE
646   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
647#endif
648   | SEC_CODE | SEC_DATA),
649
650#ifdef TARGET_UNDERSCORE
651  TARGET_UNDERSCORE,		/* leading underscore */
652#else
653  0,				/* leading underscore */
654#endif
655  '/',				/* ar_pad_char */
656  15,				/* ar_max_namelen */
657
658  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
659     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
660     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
661  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
662     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
663     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
664
665/* Note that we allow an object file to be treated as a core file as well.  */
666    {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
667       bfd_generic_archive_p, coff_object_p},
668    {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
669       bfd_false},
670    {bfd_false, coff_write_object_contents, /* bfd_write_contents */
671       _bfd_write_archive_contents, bfd_false},
672
673     BFD_JUMP_TABLE_GENERIC (coff),
674     BFD_JUMP_TABLE_COPY (coff),
675     BFD_JUMP_TABLE_CORE (_bfd_nocore),
676     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
677     BFD_JUMP_TABLE_SYMBOLS (coff),
678     BFD_JUMP_TABLE_RELOCS (coff),
679     BFD_JUMP_TABLE_WRITE (coff),
680     BFD_JUMP_TABLE_LINK (coff),
681     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
682
683  NULL,
684
685  COFF_SWAP_TABLE
686};
687