OSDN Git Service

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