1179407Sobrien/* BFD back-end for MIPS PE COFF files.
2179407Sobrien   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3218822Sdim   2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4179407Sobrien   Modified from coff-i386.c by DJ Delorie, dj@cygnus.com
5179407Sobrien
6218822Sdim   This file is part of BFD, the Binary File Descriptor library.
7179407Sobrien
8218822Sdim   This program is free software; you can redistribute it and/or modify
9218822Sdim   it under the terms of the GNU General Public License as published by
10218822Sdim   the Free Software Foundation; either version 2 of the License, or
11218822Sdim   (at your option) any later version.
12179407Sobrien
13218822Sdim   This program is distributed in the hope that it will be useful,
14218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
15218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16218822Sdim   GNU General Public License for more details.
17179407Sobrien
18218822Sdim   You should have received a copy of the GNU General Public License
19218822Sdim   along with this program; if not, write to the Free Software
20218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21179407Sobrien
22179407Sobrien#define COFF_WITH_PE
23179407Sobrien#define COFF_LONG_SECTION_NAMES
24179407Sobrien#define PCRELOFFSET TRUE
25179407Sobrien
26218822Sdim#include "sysdep.h"
27179407Sobrien#include "bfd.h"
28179407Sobrien#include "libbfd.h"
29179407Sobrien#include "coff/mipspe.h"
30179407Sobrien#include "coff/internal.h"
31179407Sobrien#include "coff/pe.h"
32179407Sobrien#include "libcoff.h"
33179407Sobrien
34218822Sdim#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
35179407Sobrien/* The page size is a guess based on ELF.  */
36179407Sobrien
37179407Sobrien#define COFF_PAGE_SIZE 0x1000
38179407Sobrien
39179407Sobrien/* For some reason when using mips COFF the value stored in the .text
40179407Sobrien   section for a reference to a common symbol is the value itself plus
41179407Sobrien   any desired offset.  Ian Taylor, Cygnus Support.  */
42179407Sobrien
43179407Sobrien/* If we are producing relocatable output, we need to do some
44179407Sobrien   adjustments to the object file that are not done by the
45179407Sobrien   bfd_perform_relocation function.  This function is called by every
46179407Sobrien   reloc type to make any required adjustments.  */
47179407Sobrien
48179407Sobrienstatic bfd_reloc_status_type
49218822Sdimcoff_mips_reloc (bfd *abfd,
50218822Sdim		 arelent *reloc_entry,
51218822Sdim		 asymbol *symbol,
52218822Sdim		 void * data,
53218822Sdim		 asection *input_section ATTRIBUTE_UNUSED,
54218822Sdim		 bfd *output_bfd,
55218822Sdim		 char **error_message ATTRIBUTE_UNUSED)
56179407Sobrien{
57179407Sobrien  symvalue diff;
58179407Sobrien
59218822Sdim  if (output_bfd == NULL)
60179407Sobrien    return bfd_reloc_continue;
61179407Sobrien
62179407Sobrien  if (bfd_is_com_section (symbol->section))
63179407Sobrien    {
64179407Sobrien#ifndef COFF_WITH_PE
65179407Sobrien      /* We are relocating a common symbol.  The current value in the
66179407Sobrien	 object file is ORIG + OFFSET, where ORIG is the value of the
67179407Sobrien	 common symbol as seen by the object file when it was compiled
68179407Sobrien	 (this may be zero if the symbol was undefined) and OFFSET is
69179407Sobrien	 the offset into the common symbol (normally zero, but may be
70179407Sobrien	 non-zero when referring to a field in a common structure).
71179407Sobrien	 ORIG is the negative of reloc_entry->addend, which is set by
72179407Sobrien	 the CALC_ADDEND macro below.  We want to replace the value in
73179407Sobrien	 the object file with NEW + OFFSET, where NEW is the value of
74179407Sobrien	 the common symbol which we are going to put in the final
75179407Sobrien	 object file.  NEW is symbol->value.  */
76179407Sobrien      diff = symbol->value + reloc_entry->addend;
77179407Sobrien#else
78179407Sobrien      /* In PE mode, we do not offset the common symbol.  */
79179407Sobrien      diff = reloc_entry->addend;
80179407Sobrien#endif
81179407Sobrien    }
82179407Sobrien  else
83218822Sdim    /* For some reason bfd_perform_relocation always effectively
84218822Sdim       ignores the addend for a COFF target when producing
85218822Sdim       relocatable output.  This seems to be always wrong for 386
86218822Sdim       COFF, so we handle the addend here instead.  */
87218822Sdim    diff = reloc_entry->addend;
88179407Sobrien
89179407Sobrien#define DOIT(x) \
90179407Sobrien  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + (diff >> howto->rightshift)) & howto->dst_mask))
91179407Sobrien
92179407Sobrien    if (diff != 0)
93179407Sobrien      {
94179407Sobrien	reloc_howto_type *howto = reloc_entry->howto;
95179407Sobrien	unsigned char *addr = (unsigned char *) data + reloc_entry->address;
96179407Sobrien
97179407Sobrien	switch (howto->size)
98179407Sobrien	  {
99179407Sobrien	  case 0:
100179407Sobrien	    {
101179407Sobrien	      char x = bfd_get_8 (abfd, addr);
102218822Sdim
103179407Sobrien	      DOIT (x);
104179407Sobrien	      bfd_put_8 (abfd, x, addr);
105179407Sobrien	    }
106179407Sobrien	    break;
107179407Sobrien
108179407Sobrien	  case 1:
109179407Sobrien	    {
110179407Sobrien	      short x = bfd_get_16 (abfd, addr);
111218822Sdim
112179407Sobrien	      DOIT (x);
113179407Sobrien	      bfd_put_16 (abfd, (bfd_vma) x, addr);
114179407Sobrien	    }
115179407Sobrien	    break;
116179407Sobrien
117179407Sobrien	  case 2:
118179407Sobrien	    {
119179407Sobrien	      long x = bfd_get_32 (abfd, addr);
120218822Sdim
121179407Sobrien	      DOIT (x);
122179407Sobrien	      bfd_put_32 (abfd, (bfd_vma) x, addr);
123179407Sobrien	    }
124179407Sobrien	    break;
125179407Sobrien
126179407Sobrien	  default:
127179407Sobrien	    abort ();
128179407Sobrien	  }
129179407Sobrien      }
130179407Sobrien
131179407Sobrien  /* Now let bfd_perform_relocation finish everything up.  */
132179407Sobrien  return bfd_reloc_continue;
133179407Sobrien}
134179407Sobrien
135179407Sobrien#ifdef COFF_WITH_PE
136179407Sobrien/* Return TRUE if this relocation should
137179407Sobrien   appear in the output .reloc section.  */
138179407Sobrien
139179407Sobrienstatic bfd_boolean
140218822Sdimin_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
141179407Sobrien{
142179407Sobrien  return ! howto->pc_relative && howto->type != MIPS_R_RVA;
143179407Sobrien}
144179407Sobrien#endif
145179407Sobrien
146179407Sobrien#ifndef PCRELOFFSET
147179407Sobrien#define PCRELOFFSET FALSE
148179407Sobrien#endif
149179407Sobrien
150179407Sobrienstatic reloc_howto_type howto_table[] =
151179407Sobrien{
152179407Sobrien  /* Reloc type 0 is ignored.  The reloc reading code ensures that
153179407Sobrien     this is a reference to the .abs section, which will cause
154179407Sobrien     bfd_perform_relocation to do nothing.  */
155218822Sdim  HOWTO (MIPS_R_ABSOLUTE,	/* Type.  */
156218822Sdim	 0,			/* Rightshift.  */
157218822Sdim	 0,			/* Size (0 = byte, 1 = short, 2 = long).  */
158218822Sdim	 8,			/* Bitsize.  */
159218822Sdim	 FALSE,			/* PC_relative.  */
160218822Sdim	 0,			/* Bitpos. */
161218822Sdim	 complain_overflow_dont, /* Complain_on_overflow. */
162218822Sdim	 0,			/* Special_function. */
163218822Sdim	 "IGNORE",		/* Name. */
164218822Sdim	 FALSE,			/* Partial_inplace. */
165218822Sdim	 0,			/* Src_mask. */
166218822Sdim	 0,			/* Dst_mask. */
167218822Sdim	 FALSE),		/* Pcrel_offset. */
168179407Sobrien
169179407Sobrien  /* A 16 bit reference to a symbol, normally from a data section.  */
170218822Sdim  HOWTO (MIPS_R_REFHALF,	/* Type.  */
171218822Sdim	 0,			/* Rightshift.  */
172218822Sdim	 1,			/* Size (0 = byte, 1 = short, 2 = long).  */
173218822Sdim	 16,			/* Bitsize.  */
174218822Sdim	 FALSE,			/* PC_relative.  */
175218822Sdim	 0,			/* Bitpos. */
176218822Sdim	 complain_overflow_bitfield, /* Complain_on_overflow. */
177218822Sdim	 coff_mips_reloc,	/* Special_function. */
178218822Sdim	 "REFHALF",		/* Name. */
179218822Sdim	 TRUE,			/* Partial_inplace. */
180218822Sdim	 0xffff,		/* Src_mask. */
181218822Sdim	 0xffff,		/* Dst_mask. */
182218822Sdim	 FALSE),		/* Pcrel_offset. */
183179407Sobrien
184179407Sobrien  /* A 32 bit reference to a symbol, normally from a data section.  */
185218822Sdim  HOWTO (MIPS_R_REFWORD,	/* Type.  */
186218822Sdim	 0,			/* Rightshift.  */
187218822Sdim	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
188218822Sdim	 32,			/* Bitsize.  */
189218822Sdim	 FALSE,			/* PC_relative.  */
190218822Sdim	 0,			/* Bitpos. */
191218822Sdim	 complain_overflow_bitfield, /* Complain_on_overflow. */
192218822Sdim	 coff_mips_reloc,	/* Special_function. */
193218822Sdim	 "REFWORD",		/* Name. */
194218822Sdim	 TRUE,			/* Partial_inplace. */
195218822Sdim	 0xffffffff,		/* Src_mask. */
196218822Sdim	 0xffffffff,		/* Dst_mask. */
197218822Sdim	 FALSE),		/* Pcrel_offset. */
198179407Sobrien
199179407Sobrien  /* A 26 bit absolute jump address.  */
200218822Sdim  HOWTO (MIPS_R_JMPADDR,	/* Type.  */
201218822Sdim	 2,			/* Rightshift.  */
202218822Sdim	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
203218822Sdim	 26,			/* Bitsize.  */
204218822Sdim	 FALSE,			/* PC_relative.  */
205218822Sdim	 0,			/* Bitpos. */
206218822Sdim	 complain_overflow_dont, /* Complain_on_overflow. */
207179407Sobrien	 			/* This needs complex overflow
208179407Sobrien				   detection, because the upper four
209179407Sobrien				   bits must match the PC.  */
210218822Sdim	 coff_mips_reloc,	/* Special_function. */
211218822Sdim	 "JMPADDR",		/* Name. */
212218822Sdim	 TRUE,			/* Partial_inplace. */
213218822Sdim	 0x3ffffff,		/* Src_mask. */
214218822Sdim	 0x3ffffff,		/* Dst_mask. */
215218822Sdim	 FALSE),		/* Pcrel_offset. */
216179407Sobrien
217179407Sobrien  /* The high 16 bits of a symbol value.  Handled by the function
218179407Sobrien     mips_refhi_reloc.  */
219218822Sdim  HOWTO (MIPS_R_REFHI,		/* Type.  */
220218822Sdim	 16,			/* Rightshift.  */
221218822Sdim	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
222218822Sdim	 16,			/* Bitsize.  */
223218822Sdim	 FALSE,			/* PC_relative.  */
224218822Sdim	 0,			/* Bitpos. */
225218822Sdim	 complain_overflow_bitfield, /* Complain_on_overflow. */
226218822Sdim	 coff_mips_reloc,	/* Special_function. */
227218822Sdim	 "REFHI",		/* Name. */
228218822Sdim	 TRUE,			/* Partial_inplace. */
229218822Sdim	 0xffff,		/* Src_mask. */
230218822Sdim	 0xffff,		/* Dst_mask. */
231218822Sdim	 FALSE),		/* Pcrel_offset. */
232179407Sobrien
233179407Sobrien  /* The low 16 bits of a symbol value.  */
234218822Sdim  HOWTO (MIPS_R_REFLO,		/* Type.  */
235218822Sdim	 0,			/* Rightshift.  */
236218822Sdim	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
237218822Sdim	 16,			/* Bitsize.  */
238218822Sdim	 FALSE,			/* PC_relative.  */
239218822Sdim	 0,			/* Bitpos. */
240218822Sdim	 complain_overflow_dont, /* Complain_on_overflow. */
241218822Sdim	 coff_mips_reloc,	/* Special_function. */
242218822Sdim	 "REFLO",		/* Name. */
243218822Sdim	 TRUE,			/* Partial_inplace. */
244218822Sdim	 0xffff,		/* Src_mask. */
245218822Sdim	 0xffff,		/* Dst_mask. */
246218822Sdim	 FALSE),		/* Pcrel_offset. */
247179407Sobrien
248179407Sobrien  /* A reference to an offset from the gp register.  Handled by the
249179407Sobrien     function mips_gprel_reloc.  */
250218822Sdim  HOWTO (MIPS_R_GPREL,		/* Type.  */
251218822Sdim	 0,			/* Rightshift.  */
252218822Sdim	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
253218822Sdim	 16,			/* Bitsize.  */
254218822Sdim	 FALSE,			/* PC_relative.  */
255218822Sdim	 0,			/* Bitpos. */
256218822Sdim	 complain_overflow_signed, /* Complain_on_overflow. */
257218822Sdim	 coff_mips_reloc,	/* Special_function. */
258218822Sdim	 "GPREL",		/* Name. */
259218822Sdim	 TRUE,			/* Partial_inplace. */
260218822Sdim	 0xffff,		/* Src_mask. */
261218822Sdim	 0xffff,		/* Dst_mask. */
262218822Sdim	 FALSE),		/* Pcrel_offset. */
263179407Sobrien
264179407Sobrien  /* A reference to a literal using an offset from the gp register.
265179407Sobrien     Handled by the function mips_gprel_reloc.  */
266218822Sdim  HOWTO (MIPS_R_LITERAL,	/* Type.  */
267218822Sdim	 0,			/* Rightshift.  */
268218822Sdim	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
269218822Sdim	 16,			/* Bitsize.  */
270218822Sdim	 FALSE,			/* PC_relative.  */
271218822Sdim	 0,			/* Bitpos. */
272218822Sdim	 complain_overflow_signed, /* Complain_on_overflow. */
273218822Sdim	 coff_mips_reloc,	/* Special_function. */
274218822Sdim	 "LITERAL",		/* Name. */
275218822Sdim	 TRUE,			/* Partial_inplace. */
276218822Sdim	 0xffff,		/* Src_mask. */
277218822Sdim	 0xffff,		/* Dst_mask. */
278218822Sdim	 FALSE),		/* Pcrel_offset. */
279179407Sobrien
280179407Sobrien  EMPTY_HOWTO (8),
281179407Sobrien  EMPTY_HOWTO (9),
282179407Sobrien  EMPTY_HOWTO (10),
283179407Sobrien  EMPTY_HOWTO (11),
284179407Sobrien  EMPTY_HOWTO (12),
285179407Sobrien  EMPTY_HOWTO (13),
286179407Sobrien  EMPTY_HOWTO (14),
287179407Sobrien  EMPTY_HOWTO (15),
288179407Sobrien  EMPTY_HOWTO (16),
289179407Sobrien  EMPTY_HOWTO (17),
290179407Sobrien  EMPTY_HOWTO (18),
291179407Sobrien  EMPTY_HOWTO (19),
292179407Sobrien  EMPTY_HOWTO (20),
293179407Sobrien  EMPTY_HOWTO (21),
294179407Sobrien  EMPTY_HOWTO (22),
295179407Sobrien  EMPTY_HOWTO (23),
296179407Sobrien  EMPTY_HOWTO (24),
297179407Sobrien  EMPTY_HOWTO (25),
298179407Sobrien  EMPTY_HOWTO (26),
299179407Sobrien  EMPTY_HOWTO (27),
300179407Sobrien  EMPTY_HOWTO (28),
301179407Sobrien  EMPTY_HOWTO (29),
302179407Sobrien  EMPTY_HOWTO (30),
303179407Sobrien  EMPTY_HOWTO (31),
304179407Sobrien  EMPTY_HOWTO (32),
305179407Sobrien  EMPTY_HOWTO (33),
306218822Sdim  HOWTO (MIPS_R_RVA,            /* Type.  */
307218822Sdim	 0,	                /* Rightshift.  */
308218822Sdim	 2,	                /* Size (0 = byte, 1 = short, 2 = long).  */
309218822Sdim	 32,	                /* Bitsize.  */
310218822Sdim	 FALSE,	                /* PC_relative.  */
311218822Sdim	 0,	                /* Bitpos. */
312218822Sdim	 complain_overflow_bitfield, /* Complain_on_overflow. */
313218822Sdim	 coff_mips_reloc,       /* Special_function. */
314218822Sdim	 "rva32",	        /* Name. */
315218822Sdim	 TRUE,	                /* Partial_inplace. */
316218822Sdim	 0xffffffff,            /* Src_mask. */
317218822Sdim	 0xffffffff,            /* Dst_mask. */
318218822Sdim	 FALSE),                /* Pcrel_offset. */
319179407Sobrien  EMPTY_HOWTO (35),
320179407Sobrien  EMPTY_HOWTO (36),
321218822Sdim  HOWTO (MIPS_R_PAIR,           /* Type.  */
322218822Sdim	 0,	                /* Rightshift.  */
323218822Sdim	 2,	                /* Size (0 = byte, 1 = short, 2 = long).  */
324218822Sdim	 32,	                /* Bitsize.  */
325218822Sdim	 FALSE,	                /* PC_relative.  */
326218822Sdim	 0,	                /* Bitpos. */
327218822Sdim	 complain_overflow_bitfield, /* Complain_on_overflow. */
328218822Sdim	 coff_mips_reloc,       /* Special_function. */
329218822Sdim	 "PAIR",	        /* Name. */
330218822Sdim	 TRUE,	                /* Partial_inplace. */
331218822Sdim	 0xffffffff,            /* Src_mask. */
332218822Sdim	 0xffffffff,            /* Dst_mask. */
333218822Sdim	 FALSE),                /* Pcrel_offset. */
334179407Sobrien};
335179407Sobrien
336218822Sdim/* Turn a howto into a reloc nunmber.  */
337179407Sobrien
338218822Sdim#define SELECT_RELOC(x, howto) { x.r_type = howto->type; }
339218822Sdim#define BADMAG(x)              MIPSBADMAG (x)
340179407Sobrien
341218822Sdim/* Customize coffcode.h.  */
342218822Sdim#define MIPS 1
343218822Sdim
344179407Sobrien#define RTYPE2HOWTO(cache_ptr, dst) \
345179407Sobrien	    (cache_ptr)->howto = howto_table + (dst)->r_type;
346179407Sobrien
347179407Sobrien/* Compute the addend of a reloc.  If the reloc is to a common symbol,
348179407Sobrien   the object file contains the value of the common symbol.  By the
349179407Sobrien   time this is called, the linker may be using a different symbol
350179407Sobrien   from a different object file with a different value.  Therefore, we
351179407Sobrien   hack wildly to locate the original symbol from this file so that we
352179407Sobrien   can make the correct adjustment.  This macro sets coffsym to the
353179407Sobrien   symbol from the original file, and uses it to set the addend value
354179407Sobrien   correctly.  If this is not a common symbol, the usual addend
355179407Sobrien   calculation is done, except that an additional tweak is needed for
356179407Sobrien   PC relative relocs.
357179407Sobrien   FIXME: This macro refers to symbols and asect; these are from the
358179407Sobrien   calling function, not the macro arguments.  */
359179407Sobrien
360179407Sobrien#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)		\
361179407Sobrien  {								\
362218822Sdim    coff_symbol_type *coffsym = NULL;				\
363179407Sobrien    if (ptr && bfd_asymbol_bfd (ptr) != abfd)			\
364179407Sobrien      coffsym = (obj_symbols (abfd)				\
365179407Sobrien	         + (cache_ptr->sym_ptr_ptr - symbols));		\
366179407Sobrien    else if (ptr)						\
367179407Sobrien      coffsym = coff_symbol_from (abfd, ptr);			\
368218822Sdim    if (coffsym != NULL						\
369179407Sobrien	&& coffsym->native->u.syment.n_scnum == 0)		\
370179407Sobrien      cache_ptr->addend = - coffsym->native->u.syment.n_value;	\
371179407Sobrien    else if (ptr && bfd_asymbol_bfd (ptr) == abfd		\
372218822Sdim	     && ptr->section != NULL)				\
373179407Sobrien      cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
374179407Sobrien    else							\
375179407Sobrien      cache_ptr->addend = 0;					\
376179407Sobrien    if (ptr && howto_table[reloc.r_type].pc_relative)		\
377179407Sobrien      cache_ptr->addend += asect->vma;				\
378179407Sobrien  }
379179407Sobrien
380179407Sobrien/* Convert an rtype to howto for the COFF backend linker.  */
381179407Sobrien
382179407Sobrienstatic reloc_howto_type *
383218822Sdimcoff_mips_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
384218822Sdim			  asection *sec,
385218822Sdim			  struct internal_reloc *rel,
386218822Sdim			  struct coff_link_hash_entry *h,
387218822Sdim			  struct internal_syment *sym,
388218822Sdim			  bfd_vma *addendp)
389179407Sobrien{
390179407Sobrien
391179407Sobrien  reloc_howto_type *howto;
392179407Sobrien
393179407Sobrien  howto = howto_table + rel->r_type;
394179407Sobrien
395179407Sobrien#ifdef COFF_WITH_PE
396179407Sobrien  *addendp = 0;
397179407Sobrien#endif
398179407Sobrien
399179407Sobrien  if (howto->pc_relative)
400179407Sobrien    *addendp += sec->vma;
401179407Sobrien
402179407Sobrien  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
403179407Sobrien    {
404179407Sobrien      /* This is a common symbol.  The section contents include the
405179407Sobrien	 size (sym->n_value) as an addend.  The relocate_section
406179407Sobrien	 function will be adding in the final value of the symbol.  We
407179407Sobrien	 need to subtract out the current size in order to get the
408179407Sobrien	 correct result.  */
409179407Sobrien
410179407Sobrien      BFD_ASSERT (h != NULL);
411179407Sobrien
412179407Sobrien#ifndef COFF_WITH_PE
413179407Sobrien      /* I think we *do* want to bypass this.  If we don't, I have
414179407Sobrien	 seen some data parameters get the wrong relocation address.
415179407Sobrien	 If I link two versions with and without this section bypassed
416179407Sobrien	 and then do a binary comparison, the addresses which are
417179407Sobrien	 different can be looked up in the map.  The case in which
418179407Sobrien	 this section has been bypassed has addresses which correspond
419179407Sobrien	 to values I can find in the map.  */
420179407Sobrien      *addendp -= sym->n_value;
421179407Sobrien#endif
422179407Sobrien    }
423179407Sobrien
424179407Sobrien#ifndef COFF_WITH_PE
425179407Sobrien  /* If the output symbol is common (in which case this must be a
426179407Sobrien     relocatable link), we need to add in the final size of the
427179407Sobrien     common symbol.  */
428179407Sobrien  if (h != NULL && h->root.type == bfd_link_hash_common)
429179407Sobrien    *addendp += h->root.u.c.size;
430179407Sobrien#endif
431179407Sobrien
432179407Sobrien#ifdef COFF_WITH_PE
433179407Sobrien  if (howto->pc_relative)
434179407Sobrien    {
435179407Sobrien      *addendp -= 4;
436179407Sobrien
437179407Sobrien      /* If the symbol is defined, then the generic code is going to
438179407Sobrien         add back the symbol value in order to cancel out an
439179407Sobrien         adjustment it made to the addend.  However, we set the addend
440179407Sobrien         to 0 at the start of this function.  We need to adjust here,
441179407Sobrien         to avoid the adjustment the generic code will make.  FIXME:
442179407Sobrien         This is getting a bit hackish.  */
443179407Sobrien      if (sym != NULL && sym->n_scnum != 0)
444179407Sobrien	*addendp -= sym->n_value;
445179407Sobrien    }
446179407Sobrien
447179407Sobrien  if (rel->r_type == MIPS_R_RVA)
448218822Sdim    *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
449179407Sobrien#endif
450179407Sobrien
451179407Sobrien  return howto;
452179407Sobrien}
453179407Sobrien
454218822Sdim#define coff_rtype_to_howto         coff_mips_rtype_to_howto
455218822Sdim#define coff_bfd_reloc_type_lookup  coff_mips_reloc_type_lookup
456218822Sdim#define coff_bfd_reloc_name_lookup coff_mips_reloc_name_lookup
457179407Sobrien
458179407Sobrien/* Get the howto structure for a generic reloc type.  */
459179407Sobrien
460179407Sobrienstatic reloc_howto_type *
461218822Sdimcoff_mips_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
462218822Sdim			     bfd_reloc_code_real_type code)
463179407Sobrien{
464179407Sobrien  int mips_type;
465179407Sobrien
466179407Sobrien  switch (code)
467179407Sobrien    {
468179407Sobrien    case BFD_RELOC_16:
469179407Sobrien      mips_type = MIPS_R_REFHALF;
470179407Sobrien      break;
471179407Sobrien    case BFD_RELOC_32:
472179407Sobrien    case BFD_RELOC_CTOR:
473179407Sobrien      mips_type = MIPS_R_REFWORD;
474179407Sobrien      break;
475179407Sobrien    case BFD_RELOC_MIPS_JMP:
476179407Sobrien      mips_type = MIPS_R_JMPADDR;
477179407Sobrien      break;
478179407Sobrien    case BFD_RELOC_HI16_S:
479179407Sobrien      mips_type = MIPS_R_REFHI;
480179407Sobrien      break;
481179407Sobrien    case BFD_RELOC_LO16:
482179407Sobrien      mips_type = MIPS_R_REFLO;
483179407Sobrien      break;
484179407Sobrien    case BFD_RELOC_GPREL16:
485179407Sobrien      mips_type = MIPS_R_GPREL;
486179407Sobrien      break;
487179407Sobrien    case BFD_RELOC_MIPS_LITERAL:
488179407Sobrien      mips_type = MIPS_R_LITERAL;
489179407Sobrien      break;
490179407Sobrien    case BFD_RELOC_RVA:
491179407Sobrien      mips_type = MIPS_R_RVA;
492179407Sobrien      break;
493179407Sobrien    default:
494218822Sdim      return NULL;
495179407Sobrien    }
496179407Sobrien
497218822Sdim  return & howto_table [mips_type];
498179407Sobrien}
499179407Sobrien
500218822Sdimstatic reloc_howto_type *
501218822Sdimcoff_mips_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
502218822Sdim			     const char *r_name)
503218822Sdim{
504218822Sdim  unsigned int i;
505218822Sdim
506218822Sdim  for (i = 0;
507218822Sdim       i < sizeof (howto_table) / sizeof (howto_table[0]);
508218822Sdim       i++)
509218822Sdim    if (howto_table[i].name != NULL
510218822Sdim	&& strcasecmp (howto_table[i].name, r_name) == 0)
511218822Sdim      return &howto_table[i];
512218822Sdim
513218822Sdim  return NULL;
514218822Sdim}
515218822Sdim
516179407Sobrienstatic void
517218822Sdimmips_swap_reloc_in (bfd * abfd, void * src, void * dst)
518179407Sobrien{
519179407Sobrien  static struct internal_reloc pair_prev;
520179407Sobrien  RELOC *reloc_src = (RELOC *) src;
521179407Sobrien  struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
522179407Sobrien
523179407Sobrien  reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr);
524179407Sobrien  reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
525179407Sobrien  reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
526179407Sobrien  reloc_dst->r_size = 0;
527179407Sobrien  reloc_dst->r_extern = 0;
528179407Sobrien  reloc_dst->r_offset = 0;
529179407Sobrien
530179407Sobrien  switch (reloc_dst->r_type)
531179407Sobrien  {
532179407Sobrien  case MIPS_R_REFHI:
533179407Sobrien    pair_prev = *reloc_dst;
534179407Sobrien    break;
535179407Sobrien  case MIPS_R_PAIR:
536179407Sobrien    reloc_dst->r_offset = reloc_dst->r_symndx;
537179407Sobrien    if (reloc_dst->r_offset & 0x8000)
538179407Sobrien      reloc_dst->r_offset -= 0x10000;
539179407Sobrien    reloc_dst->r_symndx = pair_prev.r_symndx;
540179407Sobrien    break;
541179407Sobrien  }
542179407Sobrien}
543179407Sobrien
544179407Sobrienstatic unsigned int
545218822Sdimmips_swap_reloc_out (bfd * abfd, void * src, void * dst)
546179407Sobrien{
547179407Sobrien  static int prev_offset = 1;
548179407Sobrien  static bfd_vma prev_addr = 0;
549179407Sobrien  struct internal_reloc *reloc_src = (struct internal_reloc *)src;
550179407Sobrien  struct external_reloc *reloc_dst = (struct external_reloc *)dst;
551179407Sobrien
552179407Sobrien  switch (reloc_src->r_type)
553179407Sobrien    {
554179407Sobrien    case MIPS_R_REFHI:
555179407Sobrien      prev_addr = reloc_src->r_vaddr;
556179407Sobrien      prev_offset = reloc_src->r_offset;
557179407Sobrien      break;
558179407Sobrien    case MIPS_R_REFLO:
559179407Sobrien      if (reloc_src->r_vaddr == prev_addr)
560179407Sobrien	{
561179407Sobrien	  /* FIXME: only slightly hackish.  If we see a REFLO pointing to
562179407Sobrien	     the same address as a REFHI, we assume this is the matching
563179407Sobrien	     PAIR reloc and output it accordingly.  The symndx is really
564179407Sobrien	     the low 16 bits of the addend */
565179407Sobrien	  H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
566179407Sobrien	  H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
567179407Sobrien	  H_PUT_16 (abfd, MIPS_R_PAIR, reloc_dst->r_type);
568179407Sobrien	  return RELSZ;
569179407Sobrien	}
570179407Sobrien      break;
571179407Sobrien    }
572179407Sobrien
573179407Sobrien  H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
574179407Sobrien  H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
575179407Sobrien
576179407Sobrien  H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
577179407Sobrien  return RELSZ;
578179407Sobrien}
579179407Sobrien
580218822Sdim#define coff_swap_reloc_in   mips_swap_reloc_in
581218822Sdim#define coff_swap_reloc_out  mips_swap_reloc_out
582179407Sobrien#define NO_COFF_RELOCS
583179407Sobrien
584179407Sobrienstatic bfd_boolean
585218822Sdimcoff_pe_mips_relocate_section (bfd *output_bfd,
586218822Sdim			       struct bfd_link_info *info,
587218822Sdim			       bfd *input_bfd,
588218822Sdim			       asection *input_section,
589218822Sdim			       bfd_byte *contents,
590218822Sdim			       struct internal_reloc *relocs,
591218822Sdim			       struct internal_syment *syms,
592218822Sdim			       asection **sections)
593179407Sobrien{
594179407Sobrien  bfd_vma gp;
595179407Sobrien  bfd_boolean gp_undefined;
596179407Sobrien  size_t adjust;
597179407Sobrien  struct internal_reloc *rel;
598179407Sobrien  struct internal_reloc *rel_end;
599179407Sobrien  unsigned int i;
600179407Sobrien  bfd_boolean got_lo;
601179407Sobrien
602179407Sobrien  if (info->relocatable)
603218822Sdim    {
604218822Sdim      (*_bfd_error_handler)
605218822Sdim	(_("%B: `ld -r' not supported with PE MIPS objects\n"), input_bfd);
606218822Sdim      bfd_set_error (bfd_error_bad_value);
607218822Sdim      return FALSE;
608218822Sdim    }
609179407Sobrien
610179407Sobrien  BFD_ASSERT (input_bfd->xvec->byteorder
611179407Sobrien	      == output_bfd->xvec->byteorder);
612179407Sobrien
613179407Sobrien  gp = _bfd_get_gp_value (output_bfd);
614218822Sdim  gp_undefined = (gp == 0) ? TRUE : FALSE;
615179407Sobrien  got_lo = FALSE;
616179407Sobrien  adjust = 0;
617179407Sobrien  rel = relocs;
618179407Sobrien  rel_end = rel + input_section->reloc_count;
619218822Sdim
620179407Sobrien  for (i = 0; rel < rel_end; rel++, i++)
621179407Sobrien    {
622179407Sobrien      long symndx;
623179407Sobrien      struct coff_link_hash_entry *h;
624179407Sobrien      struct internal_syment *sym;
625179407Sobrien      bfd_vma addend = 0;
626179407Sobrien      bfd_vma val, tmp, targ, src, low;
627179407Sobrien      reloc_howto_type *howto;
628179407Sobrien      unsigned char *mem = contents + rel->r_vaddr;
629179407Sobrien
630179407Sobrien      symndx = rel->r_symndx;
631179407Sobrien
632179407Sobrien      if (symndx == -1)
633179407Sobrien	{
634179407Sobrien	  h = NULL;
635179407Sobrien	  sym = NULL;
636179407Sobrien	}
637179407Sobrien      else
638179407Sobrien	{
639179407Sobrien	  h = obj_coff_sym_hashes (input_bfd)[symndx];
640179407Sobrien	  sym = syms + symndx;
641179407Sobrien	}
642179407Sobrien
643179407Sobrien      /* COFF treats common symbols in one of two ways.  Either the
644179407Sobrien         size of the symbol is included in the section contents, or it
645179407Sobrien         is not.  We assume that the size is not included, and force
646179407Sobrien         the rtype_to_howto function to adjust the addend as needed.  */
647179407Sobrien
648179407Sobrien      if (sym != NULL && sym->n_scnum != 0)
649179407Sobrien	addend = - sym->n_value;
650179407Sobrien      else
651179407Sobrien	addend = 0;
652179407Sobrien
653179407Sobrien      howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
654179407Sobrien				       sym, &addend);
655179407Sobrien      if (howto == NULL)
656179407Sobrien	return FALSE;
657179407Sobrien
658179407Sobrien      /* If we are doing a relocatable link, then we can just ignore
659179407Sobrien         a PC relative reloc that is pcrel_offset.  It will already
660179407Sobrien         have the correct value.  If this is not a relocatable link,
661179407Sobrien         then we should ignore the symbol value.  */
662179407Sobrien      if (howto->pc_relative && howto->pcrel_offset)
663179407Sobrien	{
664179407Sobrien	  if (info->relocatable)
665179407Sobrien	    continue;
666179407Sobrien	  if (sym != NULL && sym->n_scnum != 0)
667179407Sobrien	    addend += sym->n_value;
668179407Sobrien	}
669179407Sobrien
670179407Sobrien      val = 0;
671179407Sobrien
672179407Sobrien      if (h == NULL)
673179407Sobrien	{
674179407Sobrien	  asection *sec;
675179407Sobrien
676179407Sobrien	  if (symndx == -1)
677179407Sobrien	    {
678179407Sobrien	      sec = bfd_abs_section_ptr;
679179407Sobrien	      val = 0;
680179407Sobrien	    }
681179407Sobrien	  else
682179407Sobrien	    {
683179407Sobrien	      sec = sections[symndx];
684179407Sobrien              val = (sec->output_section->vma
685179407Sobrien		     + sec->output_offset
686179407Sobrien		     + sym->n_value);
687179407Sobrien	      if (! obj_pe (input_bfd))
688179407Sobrien		val -= sec->vma;
689179407Sobrien	    }
690179407Sobrien	}
691179407Sobrien      else
692179407Sobrien	{
693179407Sobrien	  if (h->root.type == bfd_link_hash_defined
694179407Sobrien	      || h->root.type == bfd_link_hash_defweak)
695179407Sobrien	    {
696179407Sobrien	      asection *sec;
697179407Sobrien
698179407Sobrien	      sec = h->root.u.def.section;
699179407Sobrien	      val = (h->root.u.def.value
700179407Sobrien		     + sec->output_section->vma
701179407Sobrien		     + sec->output_offset);
702179407Sobrien	      }
703179407Sobrien
704179407Sobrien	  else if (! info->relocatable)
705179407Sobrien	    {
706179407Sobrien	      if (! ((*info->callbacks->undefined_symbol)
707179407Sobrien		     (info, h->root.root.string, input_bfd, input_section,
708179407Sobrien		      rel->r_vaddr - input_section->vma, TRUE)))
709179407Sobrien		return FALSE;
710179407Sobrien	    }
711179407Sobrien	}
712179407Sobrien
713179407Sobrien      src = rel->r_vaddr + input_section->output_section->vma
714179407Sobrien	+ input_section->output_offset;
715179407Sobrien
716179407Sobrien      /* OK, at this point the following variables are set up:
717179407Sobrien	   src = VMA of the memory we're fixing up
718179407Sobrien	   mem = pointer to memory we're fixing up
719218822Sdim	   val = VMA of what we need to refer to.  */
720179407Sobrien
721218822Sdim#define UI(x) (*_bfd_error_handler) (_("%B: unimplemented %s\n"), \
722218822Sdim				     input_bfd, x); \
723179407Sobrien	      bfd_set_error (bfd_error_bad_value);
724179407Sobrien
725179407Sobrien      switch (rel->r_type)
726179407Sobrien	{
727179407Sobrien	case MIPS_R_ABSOLUTE:
728218822Sdim	  /* Ignore these.  */
729179407Sobrien	  break;
730179407Sobrien
731179407Sobrien	case MIPS_R_REFHALF:
732218822Sdim	  UI ("refhalf");
733179407Sobrien	  break;
734179407Sobrien
735179407Sobrien	case MIPS_R_REFWORD:
736218822Sdim	  tmp = bfd_get_32 (input_bfd, mem);
737179407Sobrien	  /* printf ("refword: src=%08x targ=%08x+%08x\n", src, tmp, val); */
738179407Sobrien	  tmp += val;
739218822Sdim	  bfd_put_32 (input_bfd, tmp, mem);
740179407Sobrien	  break;
741179407Sobrien
742179407Sobrien	case MIPS_R_JMPADDR:
743218822Sdim	  tmp = bfd_get_32 (input_bfd, mem);
744218822Sdim	  targ = val + (tmp & 0x03ffffff) * 4;
745179407Sobrien	  if ((src & 0xf0000000) != (targ & 0xf0000000))
746179407Sobrien	    {
747218822Sdim	      (*_bfd_error_handler) (_("%B: jump too far away\n"), input_bfd);
748179407Sobrien	      bfd_set_error (bfd_error_bad_value);
749179407Sobrien	      return FALSE;
750179407Sobrien	    }
751179407Sobrien	  tmp &= 0xfc000000;
752218822Sdim	  tmp |= (targ / 4) & 0x3ffffff;
753218822Sdim	  bfd_put_32 (input_bfd, tmp, mem);
754179407Sobrien	  break;
755179407Sobrien
756179407Sobrien	case MIPS_R_REFHI:
757218822Sdim	  tmp = bfd_get_32 (input_bfd, mem);
758179407Sobrien	  switch (rel[1].r_type)
759179407Sobrien	    {
760179407Sobrien	    case MIPS_R_PAIR:
761179407Sobrien	      /* MS PE object */
762179407Sobrien	      targ = val + rel[1].r_offset + ((tmp & 0xffff) << 16);
763179407Sobrien	      break;
764179407Sobrien	    case MIPS_R_REFLO:
765179407Sobrien	      /* GNU COFF object */
766218822Sdim	      low = bfd_get_32 (input_bfd, contents + rel[1].r_vaddr);
767179407Sobrien	      low &= 0xffff;
768179407Sobrien	      if (low & 0x8000)
769179407Sobrien		low -= 0x10000;
770179407Sobrien	      targ = val + low + ((tmp & 0xffff) << 16);
771179407Sobrien	      break;
772179407Sobrien	    default:
773218822Sdim	      (*_bfd_error_handler) (_("%B: bad pair/reflo after refhi\n"),
774218822Sdim				     input_bfd);
775179407Sobrien	      bfd_set_error (bfd_error_bad_value);
776179407Sobrien	      return FALSE;
777179407Sobrien	    }
778179407Sobrien	  tmp &= 0xffff0000;
779179407Sobrien	  tmp |= (targ >> 16) & 0xffff;
780218822Sdim	  bfd_put_32 (input_bfd, tmp, mem);
781179407Sobrien	  break;
782179407Sobrien
783179407Sobrien	case MIPS_R_REFLO:
784218822Sdim	  tmp = bfd_get_32 (input_bfd, mem);
785179407Sobrien	  targ = val + (tmp & 0xffff);
786179407Sobrien	  /* printf ("refword: src=%08x targ=%08x\n", src, targ); */
787179407Sobrien	  tmp &= 0xffff0000;
788179407Sobrien	  tmp |= targ & 0xffff;
789218822Sdim	  bfd_put_32 (input_bfd, tmp, mem);
790179407Sobrien	  break;
791179407Sobrien
792179407Sobrien	case MIPS_R_GPREL:
793179407Sobrien	case MIPS_R_LITERAL:
794218822Sdim	  UI ("gprel");
795179407Sobrien	  break;
796179407Sobrien
797179407Sobrien	case MIPS_R_SECTION:
798218822Sdim	  UI ("section");
799179407Sobrien	  break;
800179407Sobrien
801179407Sobrien	case MIPS_R_SECREL:
802218822Sdim	  UI ("secrel");
803179407Sobrien	  break;
804179407Sobrien
805179407Sobrien	case MIPS_R_SECRELLO:
806218822Sdim	  UI ("secrello");
807179407Sobrien	  break;
808179407Sobrien
809179407Sobrien	case MIPS_R_SECRELHI:
810218822Sdim	  UI ("secrelhi");
811179407Sobrien	  break;
812179407Sobrien
813179407Sobrien	case MIPS_R_RVA:
814179407Sobrien	  tmp = bfd_get_32 (input_bfd, mem);
815179407Sobrien	  /* printf ("rva: src=%08x targ=%08x+%08x\n", src, tmp, val); */
816179407Sobrien	  tmp += val
817179407Sobrien	    - pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
818179407Sobrien	  bfd_put_32 (input_bfd, tmp, mem);
819179407Sobrien	  break;
820179407Sobrien
821179407Sobrien	case MIPS_R_PAIR:
822179407Sobrien	  /* ignore these */
823179407Sobrien	  break;
824179407Sobrien	}
825179407Sobrien    }
826179407Sobrien
827179407Sobrien  return TRUE;
828179407Sobrien}
829179407Sobrien
830179407Sobrien#define coff_relocate_section coff_pe_mips_relocate_section
831179407Sobrien
832179407Sobrien#ifdef TARGET_UNDERSCORE
833179407Sobrien
834179407Sobrien/* If mips gcc uses underscores for symbol names, then it does not use
835179407Sobrien   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
836179407Sobrien   we treat all symbols starting with L as local.  */
837179407Sobrien
838179407Sobrienstatic bfd_boolean
839218822Sdimcoff_mips_is_local_label_name (bfd *abfd, const char *name)
840179407Sobrien{
841179407Sobrien  if (name[0] == 'L')
842179407Sobrien    return TRUE;
843179407Sobrien
844179407Sobrien  return _bfd_coff_is_local_label_name (abfd, name);
845179407Sobrien}
846179407Sobrien
847179407Sobrien#define coff_bfd_is_local_label_name coff_mips_is_local_label_name
848179407Sobrien
849179407Sobrien#endif /* TARGET_UNDERSCORE */
850179407Sobrien
851179407Sobrien#define COFF_NO_HACK_SCNHDR_SIZE
852179407Sobrien
853179407Sobrien#include "coffcode.h"
854179407Sobrien
855179407Sobrienconst bfd_target
856179407Sobrien#ifdef TARGET_SYM
857179407Sobrien  TARGET_SYM =
858179407Sobrien#else
859179407Sobrien  mipslpe_vec =
860179407Sobrien#endif
861179407Sobrien{
862179407Sobrien#ifdef TARGET_NAME
863179407Sobrien  TARGET_NAME,
864179407Sobrien#else
865218822Sdim  "pe-mips",			/* Name.  */
866179407Sobrien#endif
867179407Sobrien  bfd_target_coff_flavour,
868218822Sdim  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */
869218822Sdim  BFD_ENDIAN_LITTLE,		/* Header byte order is little.  */
870179407Sobrien
871218822Sdim  (HAS_RELOC | EXEC_P |		/* Object flags.  */
872179407Sobrien   HAS_LINENO | HAS_DEBUG |
873179407Sobrien   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
874179407Sobrien
875179407Sobrien#ifndef COFF_WITH_PE
876218822Sdim  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
877179407Sobrien   | SEC_CODE | SEC_DATA),
878179407Sobrien#else
879218822Sdim  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
880179407Sobrien   | SEC_CODE | SEC_DATA
881179407Sobrien   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
882179407Sobrien#endif
883179407Sobrien
884179407Sobrien#ifdef TARGET_UNDERSCORE
885218822Sdim  TARGET_UNDERSCORE,		/* Leading underscore.  */
886179407Sobrien#else
887179407Sobrien  0,				/* leading underscore */
888179407Sobrien#endif
889218822Sdim  '/',				/* AR_pad_char.  */
890218822Sdim  15,				/* AR_max_namelen.  */
891179407Sobrien
892179407Sobrien  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
893179407Sobrien     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
894218822Sdim     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
895179407Sobrien  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
896179407Sobrien     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
897218822Sdim     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
898179407Sobrien
899218822Sdim  /* Note that we allow an object file to be treated as a core file as well.  */
900218822Sdim  {_bfd_dummy_target, coff_object_p, /* bfd_check_format.  */
901218822Sdim   bfd_generic_archive_p, coff_object_p},
902218822Sdim  {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format.  */
903218822Sdim   bfd_false},
904218822Sdim  {bfd_false, coff_write_object_contents, /* bfd_write_contents.  */
905218822Sdim   _bfd_write_archive_contents, bfd_false},
906179407Sobrien
907218822Sdim  BFD_JUMP_TABLE_GENERIC (coff),
908218822Sdim  BFD_JUMP_TABLE_COPY (coff),
909218822Sdim  BFD_JUMP_TABLE_CORE (_bfd_nocore),
910218822Sdim  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
911218822Sdim  BFD_JUMP_TABLE_SYMBOLS (coff),
912218822Sdim  BFD_JUMP_TABLE_RELOCS (coff),
913218822Sdim  BFD_JUMP_TABLE_WRITE (coff),
914218822Sdim  BFD_JUMP_TABLE_LINK (coff),
915218822Sdim  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
916179407Sobrien
917179407Sobrien  NULL,
918179407Sobrien
919179407Sobrien  COFF_SWAP_TABLE
920179407Sobrien};
921