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