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 
41 static bfd_reloc_status_type coff_i386_reloc
42   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
43 static 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 *));
47 static 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 
64 static bfd_reloc_status_type
65 coff_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 
187 static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
188 
189 static 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 
201 static 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 
410 static 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 
414 static bfd_boolean
415 coff_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 
441 static reloc_howto_type *
442 coff_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 
550 static reloc_howto_type *
551 coff_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 
589 static bfd_boolean coff_i386_is_local_label_name
590   PARAMS ((bfd *, const char *));
591 
592 static bfd_boolean
593 coff_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 
609 const 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