1*3d8817e4Smiod /* BFD back-end for Motorola 68000 COFF binaries.
2*3d8817e4Smiod Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999,
3*3d8817e4Smiod 2000, 2001, 2002, 2003, 2005
4*3d8817e4Smiod Free Software Foundation, Inc.
5*3d8817e4Smiod Written by Cygnus Support.
6*3d8817e4Smiod
7*3d8817e4Smiod This file is part of BFD, the Binary File Descriptor library.
8*3d8817e4Smiod
9*3d8817e4Smiod This program is free software; you can redistribute it and/or modify
10*3d8817e4Smiod it under the terms of the GNU General Public License as published by
11*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
12*3d8817e4Smiod (at your option) any later version.
13*3d8817e4Smiod
14*3d8817e4Smiod This program is distributed in the hope that it will be useful,
15*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
16*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17*3d8817e4Smiod GNU General Public License for more details.
18*3d8817e4Smiod
19*3d8817e4Smiod You should have received a copy of the GNU General Public License
20*3d8817e4Smiod along with this program; if not, write to the Free Software
21*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
22*3d8817e4Smiod
23*3d8817e4Smiod #include "bfd.h"
24*3d8817e4Smiod #include "sysdep.h"
25*3d8817e4Smiod #include "libbfd.h"
26*3d8817e4Smiod #include "coff/m68k.h"
27*3d8817e4Smiod #include "coff/internal.h"
28*3d8817e4Smiod #include "libcoff.h"
29*3d8817e4Smiod
30*3d8817e4Smiod /* This source file is compiled multiple times for various m68k COFF
31*3d8817e4Smiod variants. The following macros control its behaviour:
32*3d8817e4Smiod
33*3d8817e4Smiod TARGET_SYM
34*3d8817e4Smiod The C name of the BFD target vector. The default is m68kcoff_vec.
35*3d8817e4Smiod TARGET_NAME
36*3d8817e4Smiod The user visible target name. The default is "coff-m68k".
37*3d8817e4Smiod NAMES_HAVE_UNDERSCORE
38*3d8817e4Smiod Whether symbol names have an underscore.
39*3d8817e4Smiod ONLY_DECLARE_RELOCS
40*3d8817e4Smiod Only declare the relocation howto array. Don't actually compile
41*3d8817e4Smiod it. The actual array will be picked up in another version of the
42*3d8817e4Smiod file.
43*3d8817e4Smiod STATIC_RELOCS
44*3d8817e4Smiod Make the relocation howto array, and associated functions, static.
45*3d8817e4Smiod COFF_COMMON_ADDEND
46*3d8817e4Smiod If this is defined, then, for a relocation against a common
47*3d8817e4Smiod symbol, the object file holds the value (the size) of the common
48*3d8817e4Smiod symbol. If this is not defined, then, for a relocation against a
49*3d8817e4Smiod common symbol, the object file holds zero. */
50*3d8817e4Smiod
51*3d8817e4Smiod #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
52*3d8817e4Smiod
53*3d8817e4Smiod #ifndef COFF_PAGE_SIZE
54*3d8817e4Smiod /* The page size is a guess based on ELF. */
55*3d8817e4Smiod #define COFF_PAGE_SIZE 0x2000
56*3d8817e4Smiod #endif
57*3d8817e4Smiod
58*3d8817e4Smiod #ifndef COFF_COMMON_ADDEND
59*3d8817e4Smiod #define RELOC_SPECIAL_FN 0
60*3d8817e4Smiod #else
61*3d8817e4Smiod static bfd_reloc_status_type m68kcoff_common_addend_special_fn
62*3d8817e4Smiod PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
63*3d8817e4Smiod static reloc_howto_type *m68kcoff_common_addend_rtype_to_howto
64*3d8817e4Smiod PARAMS ((bfd *, asection *, struct internal_reloc *,
65*3d8817e4Smiod struct coff_link_hash_entry *, struct internal_syment *,
66*3d8817e4Smiod bfd_vma *));
67*3d8817e4Smiod #define RELOC_SPECIAL_FN m68kcoff_common_addend_special_fn
68*3d8817e4Smiod #endif
69*3d8817e4Smiod
70*3d8817e4Smiod static bfd_boolean m68k_coff_is_local_label_name
71*3d8817e4Smiod PARAMS ((bfd *, const char *));
72*3d8817e4Smiod
73*3d8817e4Smiod /* On the delta, a symbol starting with L% is local. We won't see
74*3d8817e4Smiod such a symbol on other platforms, so it should be safe to always
75*3d8817e4Smiod consider it local here. */
76*3d8817e4Smiod
77*3d8817e4Smiod static bfd_boolean
m68k_coff_is_local_label_name(abfd,name)78*3d8817e4Smiod m68k_coff_is_local_label_name (abfd, name)
79*3d8817e4Smiod bfd *abfd;
80*3d8817e4Smiod const char *name;
81*3d8817e4Smiod {
82*3d8817e4Smiod if (name[0] == 'L' && name[1] == '%')
83*3d8817e4Smiod return TRUE;
84*3d8817e4Smiod
85*3d8817e4Smiod return _bfd_coff_is_local_label_name (abfd, name);
86*3d8817e4Smiod }
87*3d8817e4Smiod
88*3d8817e4Smiod #ifndef STATIC_RELOCS
89*3d8817e4Smiod /* Clean up namespace. */
90*3d8817e4Smiod #define m68kcoff_howto_table _bfd_m68kcoff_howto_table
91*3d8817e4Smiod #define m68k_rtype2howto _bfd_m68kcoff_rtype2howto
92*3d8817e4Smiod #define m68k_howto2rtype _bfd_m68kcoff_howto2rtype
93*3d8817e4Smiod #define m68k_reloc_type_lookup _bfd_m68kcoff_reloc_type_lookup
94*3d8817e4Smiod #endif
95*3d8817e4Smiod
96*3d8817e4Smiod #ifdef ONLY_DECLARE_RELOCS
97*3d8817e4Smiod extern reloc_howto_type m68kcoff_howto_table[];
98*3d8817e4Smiod #else
99*3d8817e4Smiod #ifdef STATIC_RELOCS
100*3d8817e4Smiod static
101*3d8817e4Smiod #endif
102*3d8817e4Smiod reloc_howto_type m68kcoff_howto_table[] =
103*3d8817e4Smiod {
104*3d8817e4Smiod HOWTO (R_RELBYTE, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "8", TRUE, 0x000000ff,0x000000ff, FALSE),
105*3d8817e4Smiod HOWTO (R_RELWORD, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
106*3d8817e4Smiod HOWTO (R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "32", TRUE, 0xffffffff,0xffffffff, FALSE),
107*3d8817e4Smiod HOWTO (R_PCRBYTE, 0, 0, 8, TRUE, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP8", TRUE, 0x000000ff,0x000000ff, FALSE),
108*3d8817e4Smiod HOWTO (R_PCRWORD, 0, 1, 16, TRUE, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
109*3d8817e4Smiod HOWTO (R_PCRLONG, 0, 2, 32, TRUE, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP32", TRUE, 0xffffffff,0xffffffff, FALSE),
110*3d8817e4Smiod HOWTO (R_RELLONG_NEG, 0, -2, 32, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "-32", TRUE, 0xffffffff,0xffffffff, FALSE),
111*3d8817e4Smiod };
112*3d8817e4Smiod #endif /* not ONLY_DECLARE_RELOCS */
113*3d8817e4Smiod
114*3d8817e4Smiod #ifndef BADMAG
115*3d8817e4Smiod #define BADMAG(x) M68KBADMAG(x)
116*3d8817e4Smiod #endif
117*3d8817e4Smiod #define M68 1 /* Customize coffcode.h */
118*3d8817e4Smiod
119*3d8817e4Smiod /* Turn a howto into a reloc number */
120*3d8817e4Smiod
121*3d8817e4Smiod #ifdef ONLY_DECLARE_RELOCS
122*3d8817e4Smiod extern void m68k_rtype2howto PARAMS ((arelent *internal, int relocentry));
123*3d8817e4Smiod extern int m68k_howto2rtype PARAMS ((reloc_howto_type *));
124*3d8817e4Smiod extern reloc_howto_type *m68k_reloc_type_lookup
125*3d8817e4Smiod PARAMS ((bfd *, bfd_reloc_code_real_type));
126*3d8817e4Smiod #else
127*3d8817e4Smiod
128*3d8817e4Smiod #ifdef STATIC_RELOCS
129*3d8817e4Smiod #define STAT_REL static
130*3d8817e4Smiod #else
131*3d8817e4Smiod #define STAT_REL
132*3d8817e4Smiod #endif
133*3d8817e4Smiod
134*3d8817e4Smiod STAT_REL reloc_howto_type * m68k_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
135*3d8817e4Smiod STAT_REL int m68k_howto2rtype PARAMS ((reloc_howto_type *));
136*3d8817e4Smiod STAT_REL void m68k_rtype2howto PARAMS ((arelent *, int));
137*3d8817e4Smiod
138*3d8817e4Smiod
139*3d8817e4Smiod STAT_REL void
m68k_rtype2howto(internal,relocentry)140*3d8817e4Smiod m68k_rtype2howto(internal, relocentry)
141*3d8817e4Smiod arelent *internal;
142*3d8817e4Smiod int relocentry;
143*3d8817e4Smiod {
144*3d8817e4Smiod switch (relocentry)
145*3d8817e4Smiod {
146*3d8817e4Smiod case R_RELBYTE: internal->howto = m68kcoff_howto_table + 0; break;
147*3d8817e4Smiod case R_RELWORD: internal->howto = m68kcoff_howto_table + 1; break;
148*3d8817e4Smiod case R_RELLONG: internal->howto = m68kcoff_howto_table + 2; break;
149*3d8817e4Smiod case R_PCRBYTE: internal->howto = m68kcoff_howto_table + 3; break;
150*3d8817e4Smiod case R_PCRWORD: internal->howto = m68kcoff_howto_table + 4; break;
151*3d8817e4Smiod case R_PCRLONG: internal->howto = m68kcoff_howto_table + 5; break;
152*3d8817e4Smiod case R_RELLONG_NEG: internal->howto = m68kcoff_howto_table + 6; break;
153*3d8817e4Smiod }
154*3d8817e4Smiod }
155*3d8817e4Smiod
156*3d8817e4Smiod STAT_REL int
m68k_howto2rtype(internal)157*3d8817e4Smiod m68k_howto2rtype (internal)
158*3d8817e4Smiod reloc_howto_type *internal;
159*3d8817e4Smiod {
160*3d8817e4Smiod if (internal->pc_relative)
161*3d8817e4Smiod {
162*3d8817e4Smiod switch (internal->bitsize)
163*3d8817e4Smiod {
164*3d8817e4Smiod case 32: return R_PCRLONG;
165*3d8817e4Smiod case 16: return R_PCRWORD;
166*3d8817e4Smiod case 8: return R_PCRBYTE;
167*3d8817e4Smiod }
168*3d8817e4Smiod }
169*3d8817e4Smiod else
170*3d8817e4Smiod {
171*3d8817e4Smiod switch (internal->bitsize)
172*3d8817e4Smiod {
173*3d8817e4Smiod case 32: return R_RELLONG;
174*3d8817e4Smiod case 16: return R_RELWORD;
175*3d8817e4Smiod case 8: return R_RELBYTE;
176*3d8817e4Smiod }
177*3d8817e4Smiod }
178*3d8817e4Smiod return R_RELLONG;
179*3d8817e4Smiod }
180*3d8817e4Smiod
181*3d8817e4Smiod STAT_REL reloc_howto_type *
m68k_reloc_type_lookup(abfd,code)182*3d8817e4Smiod m68k_reloc_type_lookup (abfd, code)
183*3d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
184*3d8817e4Smiod bfd_reloc_code_real_type code;
185*3d8817e4Smiod {
186*3d8817e4Smiod switch (code)
187*3d8817e4Smiod {
188*3d8817e4Smiod default: return NULL;
189*3d8817e4Smiod case BFD_RELOC_8: return m68kcoff_howto_table + 0;
190*3d8817e4Smiod case BFD_RELOC_16: return m68kcoff_howto_table + 1;
191*3d8817e4Smiod case BFD_RELOC_CTOR:
192*3d8817e4Smiod case BFD_RELOC_32: return m68kcoff_howto_table + 2;
193*3d8817e4Smiod case BFD_RELOC_8_PCREL: return m68kcoff_howto_table + 3;
194*3d8817e4Smiod case BFD_RELOC_16_PCREL: return m68kcoff_howto_table + 4;
195*3d8817e4Smiod case BFD_RELOC_32_PCREL: return m68kcoff_howto_table + 5;
196*3d8817e4Smiod /* FIXME: There doesn't seem to be a code for R_RELLONG_NEG. */
197*3d8817e4Smiod }
198*3d8817e4Smiod /*NOTREACHED*/
199*3d8817e4Smiod }
200*3d8817e4Smiod
201*3d8817e4Smiod #endif /* not ONLY_DECLARE_RELOCS */
202*3d8817e4Smiod
203*3d8817e4Smiod #define RTYPE2HOWTO(internal, relocentry) \
204*3d8817e4Smiod m68k_rtype2howto(internal, (relocentry)->r_type)
205*3d8817e4Smiod
206*3d8817e4Smiod #define SELECT_RELOC(external, internal) \
207*3d8817e4Smiod external.r_type = m68k_howto2rtype (internal)
208*3d8817e4Smiod
209*3d8817e4Smiod #define coff_bfd_reloc_type_lookup m68k_reloc_type_lookup
210*3d8817e4Smiod
211*3d8817e4Smiod #ifndef COFF_COMMON_ADDEND
212*3d8817e4Smiod #ifndef coff_rtype_to_howto
213*3d8817e4Smiod
214*3d8817e4Smiod #define coff_rtype_to_howto m68kcoff_rtype_to_howto
215*3d8817e4Smiod
216*3d8817e4Smiod static reloc_howto_type *m68kcoff_rtype_to_howto
217*3d8817e4Smiod PARAMS ((bfd *, asection *, struct internal_reloc *,
218*3d8817e4Smiod struct coff_link_hash_entry *, struct internal_syment *,
219*3d8817e4Smiod bfd_vma *));
220*3d8817e4Smiod
221*3d8817e4Smiod static reloc_howto_type *
m68kcoff_rtype_to_howto(abfd,sec,rel,h,sym,addendp)222*3d8817e4Smiod m68kcoff_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
223*3d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
224*3d8817e4Smiod asection *sec;
225*3d8817e4Smiod struct internal_reloc *rel;
226*3d8817e4Smiod struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
227*3d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
228*3d8817e4Smiod bfd_vma *addendp;
229*3d8817e4Smiod {
230*3d8817e4Smiod arelent relent;
231*3d8817e4Smiod reloc_howto_type *howto;
232*3d8817e4Smiod
233*3d8817e4Smiod RTYPE2HOWTO (&relent, rel);
234*3d8817e4Smiod
235*3d8817e4Smiod howto = relent.howto;
236*3d8817e4Smiod
237*3d8817e4Smiod if (howto->pc_relative)
238*3d8817e4Smiod *addendp += sec->vma;
239*3d8817e4Smiod
240*3d8817e4Smiod return howto;
241*3d8817e4Smiod }
242*3d8817e4Smiod
243*3d8817e4Smiod #endif /* ! defined (coff_rtype_to_howto) */
244*3d8817e4Smiod #endif /* ! defined (COFF_COMMON_ADDEND) */
245*3d8817e4Smiod
246*3d8817e4Smiod #ifdef COFF_COMMON_ADDEND
247*3d8817e4Smiod
248*3d8817e4Smiod /* If COFF_COMMON_ADDEND is defined, then when using m68k COFF the
249*3d8817e4Smiod value stored in the .text section for a reference to a common
250*3d8817e4Smiod symbol is the value itself plus any desired offset. (taken from
251*3d8817e4Smiod work done by Ian Taylor, Cygnus Support, for I386 COFF). */
252*3d8817e4Smiod
253*3d8817e4Smiod /* If we are producing relocatable output, we need to do some
254*3d8817e4Smiod adjustments to the object file that are not done by the
255*3d8817e4Smiod bfd_perform_relocation function. This function is called by every
256*3d8817e4Smiod reloc type to make any required adjustments. */
257*3d8817e4Smiod
258*3d8817e4Smiod static bfd_reloc_status_type
m68kcoff_common_addend_special_fn(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)259*3d8817e4Smiod m68kcoff_common_addend_special_fn (abfd, reloc_entry, symbol, data,
260*3d8817e4Smiod input_section, output_bfd, error_message)
261*3d8817e4Smiod bfd *abfd;
262*3d8817e4Smiod arelent *reloc_entry;
263*3d8817e4Smiod asymbol *symbol;
264*3d8817e4Smiod PTR data;
265*3d8817e4Smiod asection *input_section ATTRIBUTE_UNUSED;
266*3d8817e4Smiod bfd *output_bfd;
267*3d8817e4Smiod char **error_message ATTRIBUTE_UNUSED;
268*3d8817e4Smiod {
269*3d8817e4Smiod symvalue diff;
270*3d8817e4Smiod
271*3d8817e4Smiod if (output_bfd == (bfd *) NULL)
272*3d8817e4Smiod return bfd_reloc_continue;
273*3d8817e4Smiod
274*3d8817e4Smiod if (bfd_is_com_section (symbol->section))
275*3d8817e4Smiod {
276*3d8817e4Smiod /* We are relocating a common symbol. The current value in the
277*3d8817e4Smiod object file is ORIG + OFFSET, where ORIG is the value of the
278*3d8817e4Smiod common symbol as seen by the object file when it was compiled
279*3d8817e4Smiod (this may be zero if the symbol was undefined) and OFFSET is
280*3d8817e4Smiod the offset into the common symbol (normally zero, but may be
281*3d8817e4Smiod non-zero when referring to a field in a common structure).
282*3d8817e4Smiod ORIG is the negative of reloc_entry->addend, which is set by
283*3d8817e4Smiod the CALC_ADDEND macro below. We want to replace the value in
284*3d8817e4Smiod the object file with NEW + OFFSET, where NEW is the value of
285*3d8817e4Smiod the common symbol which we are going to put in the final
286*3d8817e4Smiod object file. NEW is symbol->value. */
287*3d8817e4Smiod diff = symbol->value + reloc_entry->addend;
288*3d8817e4Smiod }
289*3d8817e4Smiod else
290*3d8817e4Smiod {
291*3d8817e4Smiod /* For some reason bfd_perform_relocation always effectively
292*3d8817e4Smiod ignores the addend for a COFF target when producing
293*3d8817e4Smiod relocatable output. This seems to be always wrong for 386
294*3d8817e4Smiod COFF, so we handle the addend here instead. */
295*3d8817e4Smiod diff = reloc_entry->addend;
296*3d8817e4Smiod }
297*3d8817e4Smiod
298*3d8817e4Smiod #define DOIT(x) \
299*3d8817e4Smiod x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
300*3d8817e4Smiod
301*3d8817e4Smiod if (diff != 0)
302*3d8817e4Smiod {
303*3d8817e4Smiod reloc_howto_type *howto = reloc_entry->howto;
304*3d8817e4Smiod unsigned char *addr = (unsigned char *) data + reloc_entry->address;
305*3d8817e4Smiod
306*3d8817e4Smiod switch (howto->size)
307*3d8817e4Smiod {
308*3d8817e4Smiod case 0:
309*3d8817e4Smiod {
310*3d8817e4Smiod char x = bfd_get_8 (abfd, addr);
311*3d8817e4Smiod DOIT (x);
312*3d8817e4Smiod bfd_put_8 (abfd, x, addr);
313*3d8817e4Smiod }
314*3d8817e4Smiod break;
315*3d8817e4Smiod
316*3d8817e4Smiod case 1:
317*3d8817e4Smiod {
318*3d8817e4Smiod short x = bfd_get_16 (abfd, addr);
319*3d8817e4Smiod DOIT (x);
320*3d8817e4Smiod bfd_put_16 (abfd, (bfd_vma) x, addr);
321*3d8817e4Smiod }
322*3d8817e4Smiod break;
323*3d8817e4Smiod
324*3d8817e4Smiod case 2:
325*3d8817e4Smiod {
326*3d8817e4Smiod long x = bfd_get_32 (abfd, addr);
327*3d8817e4Smiod DOIT (x);
328*3d8817e4Smiod bfd_put_32 (abfd, (bfd_vma) x, addr);
329*3d8817e4Smiod }
330*3d8817e4Smiod break;
331*3d8817e4Smiod
332*3d8817e4Smiod default:
333*3d8817e4Smiod abort ();
334*3d8817e4Smiod }
335*3d8817e4Smiod }
336*3d8817e4Smiod
337*3d8817e4Smiod /* Now let bfd_perform_relocation finish everything up. */
338*3d8817e4Smiod return bfd_reloc_continue;
339*3d8817e4Smiod }
340*3d8817e4Smiod
341*3d8817e4Smiod /* Compute the addend of a reloc. If the reloc is to a common symbol,
342*3d8817e4Smiod the object file contains the value of the common symbol. By the
343*3d8817e4Smiod time this is called, the linker may be using a different symbol
344*3d8817e4Smiod from a different object file with a different value. Therefore, we
345*3d8817e4Smiod hack wildly to locate the original symbol from this file so that we
346*3d8817e4Smiod can make the correct adjustment. This macro sets coffsym to the
347*3d8817e4Smiod symbol from the original file, and uses it to set the addend value
348*3d8817e4Smiod correctly. If this is not a common symbol, the usual addend
349*3d8817e4Smiod calculation is done, except that an additional tweak is needed for
350*3d8817e4Smiod PC relative relocs.
351*3d8817e4Smiod FIXME: This macro refers to symbols and asect; these are from the
352*3d8817e4Smiod calling function, not the macro arguments. */
353*3d8817e4Smiod
354*3d8817e4Smiod #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
355*3d8817e4Smiod { \
356*3d8817e4Smiod coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
357*3d8817e4Smiod if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
358*3d8817e4Smiod coffsym = (obj_symbols (abfd) \
359*3d8817e4Smiod + (cache_ptr->sym_ptr_ptr - symbols)); \
360*3d8817e4Smiod else if (ptr) \
361*3d8817e4Smiod coffsym = coff_symbol_from (abfd, ptr); \
362*3d8817e4Smiod if (coffsym != (coff_symbol_type *) NULL \
363*3d8817e4Smiod && coffsym->native->u.syment.n_scnum == 0) \
364*3d8817e4Smiod cache_ptr->addend = - coffsym->native->u.syment.n_value; \
365*3d8817e4Smiod else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
366*3d8817e4Smiod && ptr->section != (asection *) NULL) \
367*3d8817e4Smiod cache_ptr->addend = - (ptr->section->vma + ptr->value); \
368*3d8817e4Smiod else \
369*3d8817e4Smiod cache_ptr->addend = 0; \
370*3d8817e4Smiod if (ptr && (reloc.r_type == R_PCRBYTE \
371*3d8817e4Smiod || reloc.r_type == R_PCRWORD \
372*3d8817e4Smiod || reloc.r_type == R_PCRLONG)) \
373*3d8817e4Smiod cache_ptr->addend += asect->vma; \
374*3d8817e4Smiod }
375*3d8817e4Smiod
376*3d8817e4Smiod #ifndef coff_rtype_to_howto
377*3d8817e4Smiod
378*3d8817e4Smiod /* coff-m68k.c uses the special COFF backend linker. We need to
379*3d8817e4Smiod adjust common symbols. */
380*3d8817e4Smiod
381*3d8817e4Smiod static reloc_howto_type *
m68kcoff_common_addend_rtype_to_howto(abfd,sec,rel,h,sym,addendp)382*3d8817e4Smiod m68kcoff_common_addend_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
383*3d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
384*3d8817e4Smiod asection *sec;
385*3d8817e4Smiod struct internal_reloc *rel;
386*3d8817e4Smiod struct coff_link_hash_entry *h;
387*3d8817e4Smiod struct internal_syment *sym;
388*3d8817e4Smiod bfd_vma *addendp;
389*3d8817e4Smiod {
390*3d8817e4Smiod arelent relent;
391*3d8817e4Smiod reloc_howto_type *howto;
392*3d8817e4Smiod
393*3d8817e4Smiod RTYPE2HOWTO (&relent, rel);
394*3d8817e4Smiod
395*3d8817e4Smiod howto = relent.howto;
396*3d8817e4Smiod
397*3d8817e4Smiod if (howto->pc_relative)
398*3d8817e4Smiod *addendp += sec->vma;
399*3d8817e4Smiod
400*3d8817e4Smiod if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
401*3d8817e4Smiod {
402*3d8817e4Smiod /* This is a common symbol. The section contents include the
403*3d8817e4Smiod size (sym->n_value) as an addend. The relocate_section
404*3d8817e4Smiod function will be adding in the final value of the symbol. We
405*3d8817e4Smiod need to subtract out the current size in order to get the
406*3d8817e4Smiod correct result. */
407*3d8817e4Smiod BFD_ASSERT (h != NULL);
408*3d8817e4Smiod *addendp -= sym->n_value;
409*3d8817e4Smiod }
410*3d8817e4Smiod
411*3d8817e4Smiod /* If the output symbol is common (in which case this must be a
412*3d8817e4Smiod relocatable link), we need to add in the final size of the
413*3d8817e4Smiod common symbol. */
414*3d8817e4Smiod if (h != NULL && h->root.type == bfd_link_hash_common)
415*3d8817e4Smiod *addendp += h->root.u.c.size;
416*3d8817e4Smiod
417*3d8817e4Smiod return howto;
418*3d8817e4Smiod }
419*3d8817e4Smiod
420*3d8817e4Smiod #define coff_rtype_to_howto m68kcoff_common_addend_rtype_to_howto
421*3d8817e4Smiod
422*3d8817e4Smiod #endif /* ! defined (coff_rtype_to_howto) */
423*3d8817e4Smiod
424*3d8817e4Smiod #endif /* COFF_COMMON_ADDEND */
425*3d8817e4Smiod
426*3d8817e4Smiod #if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS
427*3d8817e4Smiod /* Given a .data section and a .emreloc in-memory section, store
428*3d8817e4Smiod relocation information into the .emreloc section which can be
429*3d8817e4Smiod used at runtime to relocate the section. This is called by the
430*3d8817e4Smiod linker when the --embedded-relocs switch is used. This is called
431*3d8817e4Smiod after the add_symbols entry point has been called for all the
432*3d8817e4Smiod objects, and before the final_link entry point is called. */
433*3d8817e4Smiod
434*3d8817e4Smiod bfd_boolean
bfd_m68k_coff_create_embedded_relocs(abfd,info,datasec,relsec,errmsg)435*3d8817e4Smiod bfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
436*3d8817e4Smiod bfd *abfd;
437*3d8817e4Smiod struct bfd_link_info *info;
438*3d8817e4Smiod asection *datasec;
439*3d8817e4Smiod asection *relsec;
440*3d8817e4Smiod char **errmsg;
441*3d8817e4Smiod {
442*3d8817e4Smiod char *extsyms;
443*3d8817e4Smiod bfd_size_type symesz;
444*3d8817e4Smiod struct internal_reloc *irel, *irelend;
445*3d8817e4Smiod bfd_byte *p;
446*3d8817e4Smiod bfd_size_type amt;
447*3d8817e4Smiod
448*3d8817e4Smiod BFD_ASSERT (! info->relocatable);
449*3d8817e4Smiod
450*3d8817e4Smiod *errmsg = NULL;
451*3d8817e4Smiod
452*3d8817e4Smiod if (datasec->reloc_count == 0)
453*3d8817e4Smiod return TRUE;
454*3d8817e4Smiod
455*3d8817e4Smiod extsyms = obj_coff_external_syms (abfd);
456*3d8817e4Smiod symesz = bfd_coff_symesz (abfd);
457*3d8817e4Smiod
458*3d8817e4Smiod irel = _bfd_coff_read_internal_relocs (abfd, datasec, TRUE, NULL, FALSE,
459*3d8817e4Smiod NULL);
460*3d8817e4Smiod irelend = irel + datasec->reloc_count;
461*3d8817e4Smiod
462*3d8817e4Smiod amt = (bfd_size_type) datasec->reloc_count * 12;
463*3d8817e4Smiod relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
464*3d8817e4Smiod if (relsec->contents == NULL)
465*3d8817e4Smiod return FALSE;
466*3d8817e4Smiod
467*3d8817e4Smiod p = relsec->contents;
468*3d8817e4Smiod
469*3d8817e4Smiod for (; irel < irelend; irel++, p += 12)
470*3d8817e4Smiod {
471*3d8817e4Smiod asection *targetsec;
472*3d8817e4Smiod
473*3d8817e4Smiod /* We are going to write a four byte longword into the runtime
474*3d8817e4Smiod reloc section. The longword will be the address in the data
475*3d8817e4Smiod section which must be relocated. It is followed by the name
476*3d8817e4Smiod of the target section NUL-padded or truncated to 8
477*3d8817e4Smiod characters. */
478*3d8817e4Smiod
479*3d8817e4Smiod /* We can only relocate absolute longword relocs at run time. */
480*3d8817e4Smiod if (irel->r_type != R_RELLONG)
481*3d8817e4Smiod {
482*3d8817e4Smiod *errmsg = _("unsupported reloc type");
483*3d8817e4Smiod bfd_set_error (bfd_error_bad_value);
484*3d8817e4Smiod return FALSE;
485*3d8817e4Smiod }
486*3d8817e4Smiod
487*3d8817e4Smiod if (irel->r_symndx == -1)
488*3d8817e4Smiod targetsec = bfd_abs_section_ptr;
489*3d8817e4Smiod else
490*3d8817e4Smiod {
491*3d8817e4Smiod struct coff_link_hash_entry *h;
492*3d8817e4Smiod
493*3d8817e4Smiod h = obj_coff_sym_hashes (abfd)[irel->r_symndx];
494*3d8817e4Smiod if (h == NULL)
495*3d8817e4Smiod {
496*3d8817e4Smiod struct internal_syment isym;
497*3d8817e4Smiod
498*3d8817e4Smiod bfd_coff_swap_sym_in (abfd, extsyms + symesz * irel->r_symndx,
499*3d8817e4Smiod &isym);
500*3d8817e4Smiod targetsec = coff_section_from_bfd_index (abfd, isym.n_scnum);
501*3d8817e4Smiod }
502*3d8817e4Smiod else if (h->root.type == bfd_link_hash_defined
503*3d8817e4Smiod || h->root.type == bfd_link_hash_defweak)
504*3d8817e4Smiod targetsec = h->root.u.def.section;
505*3d8817e4Smiod else
506*3d8817e4Smiod targetsec = NULL;
507*3d8817e4Smiod }
508*3d8817e4Smiod
509*3d8817e4Smiod bfd_put_32 (abfd,
510*3d8817e4Smiod (irel->r_vaddr - datasec->vma + datasec->output_offset), p);
511*3d8817e4Smiod memset (p + 4, 0, 8);
512*3d8817e4Smiod if (targetsec != NULL)
513*3d8817e4Smiod strncpy ((char *) p + 4, targetsec->output_section->name, 8);
514*3d8817e4Smiod }
515*3d8817e4Smiod
516*3d8817e4Smiod return TRUE;
517*3d8817e4Smiod }
518*3d8817e4Smiod #endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS */
519*3d8817e4Smiod
520*3d8817e4Smiod #define coff_bfd_is_local_label_name m68k_coff_is_local_label_name
521*3d8817e4Smiod
522*3d8817e4Smiod #define coff_relocate_section _bfd_coff_generic_relocate_section
523*3d8817e4Smiod
524*3d8817e4Smiod #include "coffcode.h"
525*3d8817e4Smiod
526*3d8817e4Smiod #ifndef TARGET_SYM
527*3d8817e4Smiod #define TARGET_SYM m68kcoff_vec
528*3d8817e4Smiod #endif
529*3d8817e4Smiod
530*3d8817e4Smiod #ifndef TARGET_NAME
531*3d8817e4Smiod #define TARGET_NAME "coff-m68k"
532*3d8817e4Smiod #endif
533*3d8817e4Smiod
534*3d8817e4Smiod #ifdef NAMES_HAVE_UNDERSCORE
535*3d8817e4Smiod CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)
536*3d8817e4Smiod #else
537*3d8817e4Smiod CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL, COFF_SWAP_TABLE)
538*3d8817e4Smiod #endif
539