xref: /openbsd-src/gnu/usr.bin/binutils/bfd/coff-m68k.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* BFD back-end for Motorola 68000 COFF binaries.
2c074d1c9Sdrahn    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999,
3*007c2a45Smiod    2000, 2001, 2002, 2003
4b305b0f1Sespie    Free Software Foundation, Inc.
52159047fSniklas    Written by Cygnus Support.
62159047fSniklas 
72159047fSniklas This file is part of BFD, the Binary File Descriptor library.
82159047fSniklas 
92159047fSniklas This program is free software; you can redistribute it and/or modify
102159047fSniklas it under the terms of the GNU General Public License as published by
112159047fSniklas the Free Software Foundation; either version 2 of the License, or
122159047fSniklas (at your option) any later version.
132159047fSniklas 
142159047fSniklas This program is distributed in the hope that it will be useful,
152159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
162159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
172159047fSniklas GNU General Public License for more details.
182159047fSniklas 
192159047fSniklas You should have received a copy of the GNU General Public License
202159047fSniklas along with this program; if not, write to the Free Software
212159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
222159047fSniklas 
232159047fSniklas #include "bfd.h"
242159047fSniklas #include "sysdep.h"
252159047fSniklas #include "libbfd.h"
262159047fSniklas #include "coff/m68k.h"
272159047fSniklas #include "coff/internal.h"
282159047fSniklas #include "libcoff.h"
292159047fSniklas 
30b305b0f1Sespie /* This source file is compiled multiple times for various m68k COFF
31b305b0f1Sespie    variants.  The following macros control its behaviour:
32b305b0f1Sespie 
33b305b0f1Sespie    TARGET_SYM
34b305b0f1Sespie      The C name of the BFD target vector.  The default is m68kcoff_vec.
35b305b0f1Sespie    TARGET_NAME
36b305b0f1Sespie      The user visible target name.  The default is "coff-m68k".
37b305b0f1Sespie    NAMES_HAVE_UNDERSCORE
38b305b0f1Sespie      Whether symbol names have an underscore.
39b305b0f1Sespie    ONLY_DECLARE_RELOCS
40b305b0f1Sespie      Only declare the relocation howto array.  Don't actually compile
41b305b0f1Sespie      it.  The actual array will be picked up in another version of the
42b305b0f1Sespie      file.
43b305b0f1Sespie    STATIC_RELOCS
44b305b0f1Sespie      Make the relocation howto array, and associated functions, static.
45b305b0f1Sespie    COFF_COMMON_ADDEND
46b305b0f1Sespie      If this is defined, then, for a relocation against a common
47b305b0f1Sespie      symbol, the object file holds the value (the size) of the common
48b305b0f1Sespie      symbol.  If this is not defined, then, for a relocation against a
49b305b0f1Sespie      common symbol, the object file holds zero.  */
502159047fSniklas 
512159047fSniklas #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
522159047fSniklas 
53c88b1d6cSniklas #ifndef COFF_PAGE_SIZE
542159047fSniklas /* The page size is a guess based on ELF.  */
552159047fSniklas #define COFF_PAGE_SIZE 0x2000
56c88b1d6cSniklas #endif
572159047fSniklas 
58b305b0f1Sespie #ifndef COFF_COMMON_ADDEND
59b305b0f1Sespie #define RELOC_SPECIAL_FN 0
60b305b0f1Sespie #else
61b305b0f1Sespie static bfd_reloc_status_type m68kcoff_common_addend_special_fn
62b305b0f1Sespie   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
63b305b0f1Sespie static reloc_howto_type *m68kcoff_common_addend_rtype_to_howto
64b305b0f1Sespie   PARAMS ((bfd *, asection *, struct internal_reloc *,
65b305b0f1Sespie 	   struct coff_link_hash_entry *, struct internal_syment *,
66b305b0f1Sespie 	   bfd_vma *));
67b305b0f1Sespie #define RELOC_SPECIAL_FN m68kcoff_common_addend_special_fn
68b305b0f1Sespie #endif
69b305b0f1Sespie 
70c074d1c9Sdrahn static bfd_boolean m68k_coff_is_local_label_name
71c074d1c9Sdrahn   PARAMS ((bfd *, const char *));
72b305b0f1Sespie 
73b305b0f1Sespie /* On the delta, a symbol starting with L% is local.  We won't see
74b305b0f1Sespie    such a symbol on other platforms, so it should be safe to always
75b305b0f1Sespie    consider it local here.  */
76b305b0f1Sespie 
77c074d1c9Sdrahn static bfd_boolean
m68k_coff_is_local_label_name(abfd,name)78b305b0f1Sespie m68k_coff_is_local_label_name (abfd, name)
79b305b0f1Sespie      bfd *abfd;
80b305b0f1Sespie      const char *name;
81b305b0f1Sespie {
82b305b0f1Sespie   if (name[0] == 'L' && name[1] == '%')
83c074d1c9Sdrahn     return TRUE;
84b305b0f1Sespie 
85b305b0f1Sespie   return _bfd_coff_is_local_label_name (abfd, name);
86b305b0f1Sespie }
87b305b0f1Sespie 
88b305b0f1Sespie #ifndef STATIC_RELOCS
892159047fSniklas /* Clean up namespace.  */
902159047fSniklas #define m68kcoff_howto_table	_bfd_m68kcoff_howto_table
912159047fSniklas #define m68k_rtype2howto	_bfd_m68kcoff_rtype2howto
922159047fSniklas #define m68k_howto2rtype	_bfd_m68kcoff_howto2rtype
932159047fSniklas #define m68k_reloc_type_lookup	_bfd_m68kcoff_reloc_type_lookup
94b305b0f1Sespie #endif
952159047fSniklas 
962159047fSniklas #ifdef ONLY_DECLARE_RELOCS
972159047fSniklas extern reloc_howto_type m68kcoff_howto_table[];
982159047fSniklas #else
99b305b0f1Sespie #ifdef STATIC_RELOCS
100b305b0f1Sespie static
101b305b0f1Sespie #endif
1022159047fSniklas reloc_howto_type m68kcoff_howto_table[] =
1032159047fSniklas   {
104c074d1c9Sdrahn     HOWTO (R_RELBYTE,	       0,  0,  	8,  FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "8",	TRUE, 0x000000ff,0x000000ff, FALSE),
105c074d1c9Sdrahn     HOWTO (R_RELWORD,	       0,  1, 	16, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "16",	TRUE, 0x0000ffff,0x0000ffff, FALSE),
106c074d1c9Sdrahn     HOWTO (R_RELLONG,	       0,  2, 	32, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "32",	TRUE, 0xffffffff,0xffffffff, FALSE),
107c074d1c9Sdrahn     HOWTO (R_PCRBYTE,	       0,  0, 	8,  TRUE,  0, complain_overflow_signed,   RELOC_SPECIAL_FN, "DISP8",    TRUE, 0x000000ff,0x000000ff, FALSE),
108c074d1c9Sdrahn     HOWTO (R_PCRWORD,	       0,  1, 	16, TRUE,  0, complain_overflow_signed,   RELOC_SPECIAL_FN, "DISP16",   TRUE, 0x0000ffff,0x0000ffff, FALSE),
109c074d1c9Sdrahn     HOWTO (R_PCRLONG,	       0,  2, 	32, TRUE,  0, complain_overflow_signed,   RELOC_SPECIAL_FN, "DISP32",   TRUE, 0xffffffff,0xffffffff, FALSE),
110c074d1c9Sdrahn     HOWTO (R_RELLONG_NEG,      0, -2, 	32, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "-32",	TRUE, 0xffffffff,0xffffffff, FALSE),
1112159047fSniklas   };
1122159047fSniklas #endif /* not ONLY_DECLARE_RELOCS */
1132159047fSniklas 
1142159047fSniklas #ifndef BADMAG
1152159047fSniklas #define BADMAG(x) M68KBADMAG(x)
1162159047fSniklas #endif
1172159047fSniklas #define M68 1		/* Customize coffcode.h */
1182159047fSniklas 
1192159047fSniklas /* Turn a howto into a reloc number */
1202159047fSniklas 
1212159047fSniklas #ifdef ONLY_DECLARE_RELOCS
1222159047fSniklas extern void m68k_rtype2howto PARAMS ((arelent *internal, int relocentry));
1232159047fSniklas extern int m68k_howto2rtype PARAMS ((reloc_howto_type *));
1242159047fSniklas extern reloc_howto_type *m68k_reloc_type_lookup
1252159047fSniklas   PARAMS ((bfd *, bfd_reloc_code_real_type));
1262159047fSniklas #else
127c074d1c9Sdrahn 
128b305b0f1Sespie #ifdef STATIC_RELOCS
129c074d1c9Sdrahn #define STAT_REL static
130c074d1c9Sdrahn #else
131c074d1c9Sdrahn #define STAT_REL
132b305b0f1Sespie #endif
133c074d1c9Sdrahn 
134c074d1c9Sdrahn STAT_REL reloc_howto_type * m68k_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
135c074d1c9Sdrahn STAT_REL int m68k_howto2rtype PARAMS ((reloc_howto_type *));
136c074d1c9Sdrahn STAT_REL void m68k_rtype2howto PARAMS ((arelent *, int));
137c074d1c9Sdrahn 
138c074d1c9Sdrahn 
139c074d1c9Sdrahn STAT_REL void
m68k_rtype2howto(internal,relocentry)1402159047fSniklas m68k_rtype2howto(internal, relocentry)
1412159047fSniklas      arelent *internal;
1422159047fSniklas      int relocentry;
1432159047fSniklas {
1442159047fSniklas   switch (relocentry)
1452159047fSniklas     {
1462159047fSniklas     case R_RELBYTE:	internal->howto = m68kcoff_howto_table + 0; break;
1472159047fSniklas     case R_RELWORD:	internal->howto = m68kcoff_howto_table + 1; break;
1482159047fSniklas     case R_RELLONG:	internal->howto = m68kcoff_howto_table + 2; break;
1492159047fSniklas     case R_PCRBYTE:	internal->howto = m68kcoff_howto_table + 3; break;
1502159047fSniklas     case R_PCRWORD:	internal->howto = m68kcoff_howto_table + 4; break;
1512159047fSniklas     case R_PCRLONG:	internal->howto = m68kcoff_howto_table + 5; break;
1522159047fSniklas     case R_RELLONG_NEG:	internal->howto = m68kcoff_howto_table + 6; break;
1532159047fSniklas     }
1542159047fSniklas }
1552159047fSniklas 
156c074d1c9Sdrahn STAT_REL int
m68k_howto2rtype(internal)1572159047fSniklas m68k_howto2rtype (internal)
1582159047fSniklas      reloc_howto_type *internal;
1592159047fSniklas {
1602159047fSniklas   if (internal->pc_relative)
1612159047fSniklas     {
1622159047fSniklas       switch (internal->bitsize)
1632159047fSniklas 	{
1642159047fSniklas 	case 32: return R_PCRLONG;
1652159047fSniklas 	case 16: return R_PCRWORD;
1662159047fSniklas 	case 8: return R_PCRBYTE;
1672159047fSniklas 	}
1682159047fSniklas     }
1692159047fSniklas   else
1702159047fSniklas     {
1712159047fSniklas       switch (internal->bitsize)
1722159047fSniklas 	{
1732159047fSniklas 	case 32: return R_RELLONG;
1742159047fSniklas 	case 16: return R_RELWORD;
1752159047fSniklas 	case 8: return R_RELBYTE;
1762159047fSniklas 	}
1772159047fSniklas     }
1782159047fSniklas   return R_RELLONG;
1792159047fSniklas }
1802159047fSniklas 
181c074d1c9Sdrahn STAT_REL reloc_howto_type *
m68k_reloc_type_lookup(abfd,code)1822159047fSniklas m68k_reloc_type_lookup (abfd, code)
183b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
1842159047fSniklas      bfd_reloc_code_real_type code;
1852159047fSniklas {
1862159047fSniklas   switch (code)
1872159047fSniklas     {
1882159047fSniklas     default:			return NULL;
1892159047fSniklas     case BFD_RELOC_8:		return m68kcoff_howto_table + 0;
1902159047fSniklas     case BFD_RELOC_16:		return m68kcoff_howto_table + 1;
1912159047fSniklas     case BFD_RELOC_CTOR:
1922159047fSniklas     case BFD_RELOC_32:		return m68kcoff_howto_table + 2;
1932159047fSniklas     case BFD_RELOC_8_PCREL:	return m68kcoff_howto_table + 3;
1942159047fSniklas     case BFD_RELOC_16_PCREL:	return m68kcoff_howto_table + 4;
1952159047fSniklas     case BFD_RELOC_32_PCREL:	return m68kcoff_howto_table + 5;
1962159047fSniklas       /* FIXME: There doesn't seem to be a code for R_RELLONG_NEG.  */
1972159047fSniklas     }
1982159047fSniklas   /*NOTREACHED*/
1992159047fSniklas }
2002159047fSniklas 
2012159047fSniklas #endif /* not ONLY_DECLARE_RELOCS */
2022159047fSniklas 
2032159047fSniklas #define RTYPE2HOWTO(internal, relocentry) \
2042159047fSniklas   m68k_rtype2howto(internal, (relocentry)->r_type)
2052159047fSniklas 
2062159047fSniklas #define SELECT_RELOC(external, internal) \
207b305b0f1Sespie   external.r_type = m68k_howto2rtype (internal)
2082159047fSniklas 
2092159047fSniklas #define coff_bfd_reloc_type_lookup m68k_reloc_type_lookup
2102159047fSniklas 
211b305b0f1Sespie #ifndef COFF_COMMON_ADDEND
212e93f7393Sniklas #ifndef coff_rtype_to_howto
213e93f7393Sniklas 
214e93f7393Sniklas #define coff_rtype_to_howto m68kcoff_rtype_to_howto
215e93f7393Sniklas 
216e93f7393Sniklas static reloc_howto_type *m68kcoff_rtype_to_howto
217e93f7393Sniklas   PARAMS ((bfd *, asection *, struct internal_reloc *,
218e93f7393Sniklas 	   struct coff_link_hash_entry *, struct internal_syment *,
219e93f7393Sniklas 	   bfd_vma *));
220e93f7393Sniklas 
221e93f7393Sniklas static reloc_howto_type *
m68kcoff_rtype_to_howto(abfd,sec,rel,h,sym,addendp)222e93f7393Sniklas m68kcoff_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
223b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
224e93f7393Sniklas      asection *sec;
225e93f7393Sniklas      struct internal_reloc *rel;
226b305b0f1Sespie      struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
227b305b0f1Sespie      struct internal_syment *sym ATTRIBUTE_UNUSED;
228e93f7393Sniklas      bfd_vma *addendp;
229e93f7393Sniklas {
230e93f7393Sniklas   arelent relent;
231e93f7393Sniklas   reloc_howto_type *howto;
232e93f7393Sniklas 
233e93f7393Sniklas   RTYPE2HOWTO (&relent, rel);
234e93f7393Sniklas 
235e93f7393Sniklas   howto = relent.howto;
236e93f7393Sniklas 
237e93f7393Sniklas   if (howto->pc_relative)
238e93f7393Sniklas     *addendp += sec->vma;
239e93f7393Sniklas 
240e93f7393Sniklas   return howto;
241e93f7393Sniklas }
242e93f7393Sniklas 
243e93f7393Sniklas #endif /* ! defined (coff_rtype_to_howto) */
244b305b0f1Sespie #endif /* ! defined (COFF_COMMON_ADDEND) */
245b305b0f1Sespie 
246b305b0f1Sespie #ifdef COFF_COMMON_ADDEND
247b305b0f1Sespie 
248b305b0f1Sespie /* If COFF_COMMON_ADDEND is defined, then when using m68k COFF the
249b305b0f1Sespie    value stored in the .text section for a reference to a common
250b305b0f1Sespie    symbol is the value itself plus any desired offset.  (taken from
251b305b0f1Sespie    work done by Ian Taylor, Cygnus Support, for I386 COFF).  */
252b305b0f1Sespie 
253*007c2a45Smiod /* If we are producing relocatable output, we need to do some
254b305b0f1Sespie    adjustments to the object file that are not done by the
255b305b0f1Sespie    bfd_perform_relocation function.  This function is called by every
256b305b0f1Sespie    reloc type to make any required adjustments.  */
257b305b0f1Sespie 
258b305b0f1Sespie static bfd_reloc_status_type
m68kcoff_common_addend_special_fn(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)259b305b0f1Sespie m68kcoff_common_addend_special_fn (abfd, reloc_entry, symbol, data,
260b305b0f1Sespie 				   input_section, output_bfd, error_message)
261b305b0f1Sespie      bfd *abfd;
262b305b0f1Sespie      arelent *reloc_entry;
263b305b0f1Sespie      asymbol *symbol;
264b305b0f1Sespie      PTR data;
265b305b0f1Sespie      asection *input_section ATTRIBUTE_UNUSED;
266b305b0f1Sespie      bfd *output_bfd;
267b305b0f1Sespie      char **error_message ATTRIBUTE_UNUSED;
268b305b0f1Sespie {
269b305b0f1Sespie   symvalue diff;
270b305b0f1Sespie 
271b305b0f1Sespie   if (output_bfd == (bfd *) NULL)
272b305b0f1Sespie     return bfd_reloc_continue;
273b305b0f1Sespie 
274b305b0f1Sespie   if (bfd_is_com_section (symbol->section))
275b305b0f1Sespie     {
276b305b0f1Sespie       /* We are relocating a common symbol.  The current value in the
277b305b0f1Sespie 	 object file is ORIG + OFFSET, where ORIG is the value of the
278b305b0f1Sespie 	 common symbol as seen by the object file when it was compiled
279b305b0f1Sespie 	 (this may be zero if the symbol was undefined) and OFFSET is
280b305b0f1Sespie 	 the offset into the common symbol (normally zero, but may be
281b305b0f1Sespie 	 non-zero when referring to a field in a common structure).
282b305b0f1Sespie 	 ORIG is the negative of reloc_entry->addend, which is set by
283b305b0f1Sespie 	 the CALC_ADDEND macro below.  We want to replace the value in
284b305b0f1Sespie 	 the object file with NEW + OFFSET, where NEW is the value of
285b305b0f1Sespie 	 the common symbol which we are going to put in the final
286b305b0f1Sespie 	 object file.  NEW is symbol->value.  */
287b305b0f1Sespie       diff = symbol->value + reloc_entry->addend;
288b305b0f1Sespie     }
289b305b0f1Sespie   else
290b305b0f1Sespie     {
291b305b0f1Sespie       /* For some reason bfd_perform_relocation always effectively
292b305b0f1Sespie 	 ignores the addend for a COFF target when producing
293*007c2a45Smiod 	 relocatable output.  This seems to be always wrong for 386
294b305b0f1Sespie 	 COFF, so we handle the addend here instead.  */
295b305b0f1Sespie       diff = reloc_entry->addend;
296b305b0f1Sespie     }
297b305b0f1Sespie 
298b305b0f1Sespie #define DOIT(x) \
299b305b0f1Sespie   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
300b305b0f1Sespie 
301b305b0f1Sespie   if (diff != 0)
302b305b0f1Sespie     {
303b305b0f1Sespie       reloc_howto_type *howto = reloc_entry->howto;
304b305b0f1Sespie       unsigned char *addr = (unsigned char *) data + reloc_entry->address;
305b305b0f1Sespie 
306b305b0f1Sespie       switch (howto->size)
307b305b0f1Sespie 	{
308b305b0f1Sespie 	case 0:
309b305b0f1Sespie 	  {
310b305b0f1Sespie 	    char x = bfd_get_8 (abfd, addr);
311b305b0f1Sespie 	    DOIT (x);
312b305b0f1Sespie 	    bfd_put_8 (abfd, x, addr);
313b305b0f1Sespie 	  }
314b305b0f1Sespie 	  break;
315b305b0f1Sespie 
316b305b0f1Sespie 	case 1:
317b305b0f1Sespie 	  {
318b305b0f1Sespie 	    short x = bfd_get_16 (abfd, addr);
319b305b0f1Sespie 	    DOIT (x);
320c074d1c9Sdrahn 	    bfd_put_16 (abfd, (bfd_vma) x, addr);
321b305b0f1Sespie 	  }
322b305b0f1Sespie 	  break;
323b305b0f1Sespie 
324b305b0f1Sespie 	case 2:
325b305b0f1Sespie 	  {
326b305b0f1Sespie 	    long x = bfd_get_32 (abfd, addr);
327b305b0f1Sespie 	    DOIT (x);
328c074d1c9Sdrahn 	    bfd_put_32 (abfd, (bfd_vma) x, addr);
329b305b0f1Sespie 	  }
330b305b0f1Sespie 	  break;
331b305b0f1Sespie 
332b305b0f1Sespie 	default:
333b305b0f1Sespie 	  abort ();
334b305b0f1Sespie 	}
335b305b0f1Sespie     }
336b305b0f1Sespie 
337b305b0f1Sespie   /* Now let bfd_perform_relocation finish everything up.  */
338b305b0f1Sespie   return bfd_reloc_continue;
339b305b0f1Sespie }
340b305b0f1Sespie 
341b305b0f1Sespie /* Compute the addend of a reloc.  If the reloc is to a common symbol,
342b305b0f1Sespie    the object file contains the value of the common symbol.  By the
343b305b0f1Sespie    time this is called, the linker may be using a different symbol
344b305b0f1Sespie    from a different object file with a different value.  Therefore, we
345b305b0f1Sespie    hack wildly to locate the original symbol from this file so that we
346b305b0f1Sespie    can make the correct adjustment.  This macro sets coffsym to the
347b305b0f1Sespie    symbol from the original file, and uses it to set the addend value
348b305b0f1Sespie    correctly.  If this is not a common symbol, the usual addend
349b305b0f1Sespie    calculation is done, except that an additional tweak is needed for
350b305b0f1Sespie    PC relative relocs.
351b305b0f1Sespie    FIXME: This macro refers to symbols and asect; these are from the
352b305b0f1Sespie    calling function, not the macro arguments.  */
353b305b0f1Sespie 
354b305b0f1Sespie #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)		\
355b305b0f1Sespie   {								\
356b305b0f1Sespie     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;	\
357b305b0f1Sespie     if (ptr && bfd_asymbol_bfd (ptr) != abfd)			\
358b305b0f1Sespie       coffsym = (obj_symbols (abfd)				\
359b305b0f1Sespie 	         + (cache_ptr->sym_ptr_ptr - symbols));		\
360b305b0f1Sespie     else if (ptr)						\
361b305b0f1Sespie       coffsym = coff_symbol_from (abfd, ptr);			\
362b305b0f1Sespie     if (coffsym != (coff_symbol_type *) NULL			\
363b305b0f1Sespie 	&& coffsym->native->u.syment.n_scnum == 0)		\
364b305b0f1Sespie       cache_ptr->addend = - coffsym->native->u.syment.n_value;	\
365b305b0f1Sespie     else if (ptr && bfd_asymbol_bfd (ptr) == abfd		\
366b305b0f1Sespie 	     && ptr->section != (asection *) NULL)		\
367b305b0f1Sespie       cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
368b305b0f1Sespie     else							\
369b305b0f1Sespie       cache_ptr->addend = 0;					\
370b305b0f1Sespie     if (ptr && (reloc.r_type == R_PCRBYTE			\
371b305b0f1Sespie 		|| reloc.r_type == R_PCRWORD			\
372b305b0f1Sespie 		|| reloc.r_type == R_PCRLONG))			\
373b305b0f1Sespie       cache_ptr->addend += asect->vma;				\
374b305b0f1Sespie   }
375b305b0f1Sespie 
376b305b0f1Sespie #ifndef coff_rtype_to_howto
377b305b0f1Sespie 
378b305b0f1Sespie /* coff-m68k.c uses the special COFF backend linker.  We need to
379b305b0f1Sespie    adjust common symbols.  */
380b305b0f1Sespie 
381b305b0f1Sespie static reloc_howto_type *
m68kcoff_common_addend_rtype_to_howto(abfd,sec,rel,h,sym,addendp)382b305b0f1Sespie m68kcoff_common_addend_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
383b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
384b305b0f1Sespie      asection *sec;
385b305b0f1Sespie      struct internal_reloc *rel;
386b305b0f1Sespie      struct coff_link_hash_entry *h;
387b305b0f1Sespie      struct internal_syment *sym;
388b305b0f1Sespie      bfd_vma *addendp;
389b305b0f1Sespie {
390b305b0f1Sespie   arelent relent;
391b305b0f1Sespie   reloc_howto_type *howto;
392b305b0f1Sespie 
393b305b0f1Sespie   RTYPE2HOWTO (&relent, rel);
394b305b0f1Sespie 
395b305b0f1Sespie   howto = relent.howto;
396b305b0f1Sespie 
397b305b0f1Sespie   if (howto->pc_relative)
398b305b0f1Sespie     *addendp += sec->vma;
399b305b0f1Sespie 
400b305b0f1Sespie   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
401b305b0f1Sespie     {
402b305b0f1Sespie       /* This is a common symbol.  The section contents include the
403b305b0f1Sespie 	 size (sym->n_value) as an addend.  The relocate_section
404b305b0f1Sespie 	 function will be adding in the final value of the symbol.  We
405b305b0f1Sespie 	 need to subtract out the current size in order to get the
406b305b0f1Sespie 	 correct result.  */
407b305b0f1Sespie       BFD_ASSERT (h != NULL);
408b305b0f1Sespie       *addendp -= sym->n_value;
409b305b0f1Sespie     }
410b305b0f1Sespie 
411b305b0f1Sespie   /* If the output symbol is common (in which case this must be a
412*007c2a45Smiod      relocatable link), we need to add in the final size of the
413b305b0f1Sespie      common symbol.  */
414b305b0f1Sespie   if (h != NULL && h->root.type == bfd_link_hash_common)
415b305b0f1Sespie     *addendp += h->root.u.c.size;
416b305b0f1Sespie 
417b305b0f1Sespie   return howto;
418b305b0f1Sespie }
419b305b0f1Sespie 
420b305b0f1Sespie #define coff_rtype_to_howto m68kcoff_common_addend_rtype_to_howto
421b305b0f1Sespie 
422b305b0f1Sespie #endif /* ! defined (coff_rtype_to_howto) */
423b305b0f1Sespie 
424b305b0f1Sespie #endif /* COFF_COMMON_ADDEND */
425b55d4692Sfgsch 
426b55d4692Sfgsch #if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS
427b55d4692Sfgsch /* Given a .data section and a .emreloc in-memory section, store
428b55d4692Sfgsch    relocation information into the .emreloc section which can be
429b55d4692Sfgsch    used at runtime to relocate the section.  This is called by the
430b55d4692Sfgsch    linker when the --embedded-relocs switch is used.  This is called
431b55d4692Sfgsch    after the add_symbols entry point has been called for all the
432b55d4692Sfgsch    objects, and before the final_link entry point is called.  */
433b55d4692Sfgsch 
434c074d1c9Sdrahn bfd_boolean
bfd_m68k_coff_create_embedded_relocs(abfd,info,datasec,relsec,errmsg)435b55d4692Sfgsch bfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
436b55d4692Sfgsch      bfd *abfd;
437b55d4692Sfgsch      struct bfd_link_info *info;
438b55d4692Sfgsch      asection *datasec;
439b55d4692Sfgsch      asection *relsec;
440b55d4692Sfgsch      char **errmsg;
441b55d4692Sfgsch {
442b55d4692Sfgsch   char *extsyms;
443b55d4692Sfgsch   bfd_size_type symesz;
444b55d4692Sfgsch   struct internal_reloc *irel, *irelend;
445b55d4692Sfgsch   bfd_byte *p;
446c074d1c9Sdrahn   bfd_size_type amt;
447b55d4692Sfgsch 
448*007c2a45Smiod   BFD_ASSERT (! info->relocatable);
449b55d4692Sfgsch 
450b55d4692Sfgsch   *errmsg = NULL;
451b55d4692Sfgsch 
452b55d4692Sfgsch   if (datasec->reloc_count == 0)
453c074d1c9Sdrahn     return TRUE;
454b55d4692Sfgsch 
455b55d4692Sfgsch   extsyms = obj_coff_external_syms (abfd);
456b55d4692Sfgsch   symesz = bfd_coff_symesz (abfd);
457b55d4692Sfgsch 
458c074d1c9Sdrahn   irel = _bfd_coff_read_internal_relocs (abfd, datasec, TRUE, NULL, FALSE,
459b55d4692Sfgsch 					 NULL);
460b55d4692Sfgsch   irelend = irel + datasec->reloc_count;
461b55d4692Sfgsch 
462c074d1c9Sdrahn   amt = (bfd_size_type) datasec->reloc_count * 12;
463c074d1c9Sdrahn   relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
464b55d4692Sfgsch   if (relsec->contents == NULL)
465c074d1c9Sdrahn     return FALSE;
466b55d4692Sfgsch 
467b55d4692Sfgsch   p = relsec->contents;
468b55d4692Sfgsch 
469b55d4692Sfgsch   for (; irel < irelend; irel++, p += 12)
470b55d4692Sfgsch     {
471b55d4692Sfgsch       asection *targetsec;
472b55d4692Sfgsch 
473b55d4692Sfgsch       /* We are going to write a four byte longword into the runtime
474b55d4692Sfgsch        reloc section.  The longword will be the address in the data
475b55d4692Sfgsch        section which must be relocated.  It is followed by the name
476b55d4692Sfgsch        of the target section NUL-padded or truncated to 8
477b55d4692Sfgsch        characters.  */
478b55d4692Sfgsch 
479b55d4692Sfgsch       /* We can only relocate absolute longword relocs at run time.  */
480b55d4692Sfgsch       if (irel->r_type != R_RELLONG)
481b55d4692Sfgsch 	{
482b55d4692Sfgsch 	  *errmsg = _("unsupported reloc type");
483b55d4692Sfgsch 	  bfd_set_error (bfd_error_bad_value);
484c074d1c9Sdrahn 	  return FALSE;
485b55d4692Sfgsch 	}
486b55d4692Sfgsch 
487b55d4692Sfgsch       if (irel->r_symndx == -1)
488b55d4692Sfgsch 	targetsec = bfd_abs_section_ptr;
489b55d4692Sfgsch       else
490b55d4692Sfgsch 	{
491b55d4692Sfgsch 	  struct coff_link_hash_entry *h;
492b55d4692Sfgsch 
493b55d4692Sfgsch 	  h = obj_coff_sym_hashes (abfd)[irel->r_symndx];
494b55d4692Sfgsch 	  if (h == NULL)
495b55d4692Sfgsch 	    {
496b55d4692Sfgsch 	      struct internal_syment isym;
497b55d4692Sfgsch 
498b55d4692Sfgsch 	      bfd_coff_swap_sym_in (abfd, extsyms + symesz * irel->r_symndx,
499b55d4692Sfgsch 				    &isym);
500b55d4692Sfgsch 	      targetsec = coff_section_from_bfd_index (abfd, isym.n_scnum);
501b55d4692Sfgsch 	    }
502b55d4692Sfgsch 	  else if (h->root.type == bfd_link_hash_defined
503b55d4692Sfgsch 		   || h->root.type == bfd_link_hash_defweak)
504b55d4692Sfgsch 	    targetsec = h->root.u.def.section;
505b55d4692Sfgsch 	  else
506b55d4692Sfgsch 	    targetsec = NULL;
507b55d4692Sfgsch 	}
508b55d4692Sfgsch 
509b55d4692Sfgsch       bfd_put_32 (abfd,
510b55d4692Sfgsch 		  (irel->r_vaddr - datasec->vma + datasec->output_offset), p);
511b55d4692Sfgsch       memset (p + 4, 0, 8);
512b55d4692Sfgsch       if (targetsec != NULL)
513b55d4692Sfgsch 	strncpy (p + 4, targetsec->output_section->name, 8);
514b55d4692Sfgsch     }
515b55d4692Sfgsch 
516c074d1c9Sdrahn   return TRUE;
517b55d4692Sfgsch }
518b55d4692Sfgsch #endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS  */
519b305b0f1Sespie 
520b305b0f1Sespie #define coff_bfd_is_local_label_name m68k_coff_is_local_label_name
521e93f7393Sniklas 
5222159047fSniklas #define coff_relocate_section _bfd_coff_generic_relocate_section
5232159047fSniklas 
5242159047fSniklas #include "coffcode.h"
5252159047fSniklas 
526b305b0f1Sespie #ifndef TARGET_SYM
527b305b0f1Sespie #define TARGET_SYM m68kcoff_vec
5282159047fSniklas #endif
529b305b0f1Sespie 
530b305b0f1Sespie #ifndef TARGET_NAME
531b305b0f1Sespie #define TARGET_NAME "coff-m68k"
5322159047fSniklas #endif
5332159047fSniklas 
5342159047fSniklas #ifdef NAMES_HAVE_UNDERSCORE
535*007c2a45Smiod CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)
5362159047fSniklas #else
537*007c2a45Smiod CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL, COFF_SWAP_TABLE)
5382159047fSniklas #endif
539