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