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