Fix compile time warnings (at -O3 with gcc 4.1.2)
[platform/upstream/binutils.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   relent.howto = NULL;
255   RTYPE2HOWTO (&relent, rel);
256
257   howto = relent.howto;
258
259   if (howto != NULL && howto->pc_relative)
260     *addendp += sec->vma;
261
262   return howto;
263 }
264
265 #endif /* ! defined (coff_rtype_to_howto) */
266 #endif /* ! defined (COFF_COMMON_ADDEND) */
267 \f
268 #ifdef COFF_COMMON_ADDEND
269
270 /* If COFF_COMMON_ADDEND is defined, then when using m68k COFF the
271    value stored in the .text section for a reference to a common
272    symbol is the value itself plus any desired offset.  (taken from
273    work done by Ian Taylor, Cygnus Support, for I386 COFF).  */
274
275 /* If we are producing relocatable output, we need to do some
276    adjustments to the object file that are not done by the
277    bfd_perform_relocation function.  This function is called by every
278    reloc type to make any required adjustments.  */
279
280 static bfd_reloc_status_type
281 m68kcoff_common_addend_special_fn (abfd, reloc_entry, symbol, data,
282                                    input_section, output_bfd, error_message)
283      bfd *abfd;
284      arelent *reloc_entry;
285      asymbol *symbol;
286      PTR data;
287      asection *input_section ATTRIBUTE_UNUSED;
288      bfd *output_bfd;
289      char **error_message ATTRIBUTE_UNUSED;
290 {
291   symvalue diff;
292
293   if (output_bfd == (bfd *) NULL)
294     return bfd_reloc_continue;
295
296   if (bfd_is_com_section (symbol->section))
297     {
298       /* We are relocating a common symbol.  The current value in the
299          object file is ORIG + OFFSET, where ORIG is the value of the
300          common symbol as seen by the object file when it was compiled
301          (this may be zero if the symbol was undefined) and OFFSET is
302          the offset into the common symbol (normally zero, but may be
303          non-zero when referring to a field in a common structure).
304          ORIG is the negative of reloc_entry->addend, which is set by
305          the CALC_ADDEND macro below.  We want to replace the value in
306          the object file with NEW + OFFSET, where NEW is the value of
307          the common symbol which we are going to put in the final
308          object file.  NEW is symbol->value.  */
309       diff = symbol->value + reloc_entry->addend;
310     }
311   else
312     {
313       /* For some reason bfd_perform_relocation always effectively
314          ignores the addend for a COFF target when producing
315          relocatable output.  This seems to be always wrong for 386
316          COFF, so we handle the addend here instead.  */
317       diff = reloc_entry->addend;
318     }
319
320 #define DOIT(x) \
321   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
322
323   if (diff != 0)
324     {
325       reloc_howto_type *howto = reloc_entry->howto;
326       unsigned char *addr = (unsigned char *) data + reloc_entry->address;
327
328       switch (howto->size)
329         {
330         case 0:
331           {
332             char x = bfd_get_8 (abfd, addr);
333             DOIT (x);
334             bfd_put_8 (abfd, x, addr);
335           }
336           break;
337
338         case 1:
339           {
340             short x = bfd_get_16 (abfd, addr);
341             DOIT (x);
342             bfd_put_16 (abfd, (bfd_vma) x, addr);
343           }
344           break;
345
346         case 2:
347           {
348             long x = bfd_get_32 (abfd, addr);
349             DOIT (x);
350             bfd_put_32 (abfd, (bfd_vma) x, addr);
351           }
352           break;
353
354         default:
355           abort ();
356         }
357     }
358
359   /* Now let bfd_perform_relocation finish everything up.  */
360   return bfd_reloc_continue;
361 }
362
363 /* Compute the addend of a reloc.  If the reloc is to a common symbol,
364    the object file contains the value of the common symbol.  By the
365    time this is called, the linker may be using a different symbol
366    from a different object file with a different value.  Therefore, we
367    hack wildly to locate the original symbol from this file so that we
368    can make the correct adjustment.  This macro sets coffsym to the
369    symbol from the original file, and uses it to set the addend value
370    correctly.  If this is not a common symbol, the usual addend
371    calculation is done, except that an additional tweak is needed for
372    PC relative relocs.
373    FIXME: This macro refers to symbols and asect; these are from the
374    calling function, not the macro arguments.  */
375
376 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
377   {                                                             \
378     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
379     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
380       coffsym = (obj_symbols (abfd)                             \
381                  + (cache_ptr->sym_ptr_ptr - symbols));         \
382     else if (ptr)                                               \
383       coffsym = coff_symbol_from (abfd, ptr);                   \
384     if (coffsym != (coff_symbol_type *) NULL                    \
385         && coffsym->native->u.syment.n_scnum == 0)              \
386       cache_ptr->addend = - coffsym->native->u.syment.n_value;  \
387     else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
388              && ptr->section != (asection *) NULL)              \
389       cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
390     else                                                        \
391       cache_ptr->addend = 0;                                    \
392     if (ptr && (reloc.r_type == R_PCRBYTE                       \
393                 || reloc.r_type == R_PCRWORD                    \
394                 || reloc.r_type == R_PCRLONG))                  \
395       cache_ptr->addend += asect->vma;                          \
396   }
397
398 #ifndef coff_rtype_to_howto
399
400 /* coff-m68k.c uses the special COFF backend linker.  We need to
401    adjust common symbols.  */
402
403 static reloc_howto_type *
404 m68kcoff_common_addend_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
405      bfd *abfd ATTRIBUTE_UNUSED;
406      asection *sec;
407      struct internal_reloc *rel;
408      struct coff_link_hash_entry *h;
409      struct internal_syment *sym;
410      bfd_vma *addendp;
411 {
412   arelent relent;
413   reloc_howto_type *howto;
414
415   relent.howto = NULL;
416   RTYPE2HOWTO (&relent, rel);
417
418   howto = relent.howto;
419
420   if (howto->pc_relative)
421     *addendp += sec->vma;
422
423   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
424     {
425       /* This is a common symbol.  The section contents include the
426          size (sym->n_value) as an addend.  The relocate_section
427          function will be adding in the final value of the symbol.  We
428          need to subtract out the current size in order to get the
429          correct result.  */
430       BFD_ASSERT (h != NULL);
431       *addendp -= sym->n_value;
432     }
433
434   /* If the output symbol is common (in which case this must be a
435      relocatable link), we need to add in the final size of the
436      common symbol.  */
437   if (h != NULL && h->root.type == bfd_link_hash_common)
438     *addendp += h->root.u.c.size;
439
440   return howto;
441 }
442
443 #define coff_rtype_to_howto m68kcoff_common_addend_rtype_to_howto
444
445 #endif /* ! defined (coff_rtype_to_howto) */
446
447 #endif /* COFF_COMMON_ADDEND */
448
449 #if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS
450 /* Given a .data section and a .emreloc in-memory section, store
451    relocation information into the .emreloc section which can be
452    used at runtime to relocate the section.  This is called by the
453    linker when the --embedded-relocs switch is used.  This is called
454    after the add_symbols entry point has been called for all the
455    objects, and before the final_link entry point is called.  */
456
457 bfd_boolean
458 bfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
459      bfd *abfd;
460      struct bfd_link_info *info;
461      asection *datasec;
462      asection *relsec;
463      char **errmsg;
464 {
465   char *extsyms;
466   bfd_size_type symesz;
467   struct internal_reloc *irel, *irelend;
468   bfd_byte *p;
469   bfd_size_type amt;
470
471   BFD_ASSERT (! info->relocatable);
472
473   *errmsg = NULL;
474
475   if (datasec->reloc_count == 0)
476     return TRUE;
477
478   extsyms = obj_coff_external_syms (abfd);
479   symesz = bfd_coff_symesz (abfd);
480
481   irel = _bfd_coff_read_internal_relocs (abfd, datasec, TRUE, NULL, FALSE,
482                                          NULL);
483   irelend = irel + datasec->reloc_count;
484
485   amt = (bfd_size_type) datasec->reloc_count * 12;
486   relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
487   if (relsec->contents == NULL)
488     return FALSE;
489
490   p = relsec->contents;
491
492   for (; irel < irelend; irel++, p += 12)
493     {
494       asection *targetsec;
495
496       /* We are going to write a four byte longword into the runtime
497        reloc section.  The longword will be the address in the data
498        section which must be relocated.  It is followed by the name
499        of the target section NUL-padded or truncated to 8
500        characters.  */
501
502       /* We can only relocate absolute longword relocs at run time.  */
503       if (irel->r_type != R_RELLONG)
504         {
505           *errmsg = _("unsupported reloc type");
506           bfd_set_error (bfd_error_bad_value);
507           return FALSE;
508         }
509
510       if (irel->r_symndx == -1)
511         targetsec = bfd_abs_section_ptr;
512       else
513         {
514           struct coff_link_hash_entry *h;
515
516           h = obj_coff_sym_hashes (abfd)[irel->r_symndx];
517           if (h == NULL)
518             {
519               struct internal_syment isym;
520
521               bfd_coff_swap_sym_in (abfd, extsyms + symesz * irel->r_symndx,
522                                     &isym);
523               targetsec = coff_section_from_bfd_index (abfd, isym.n_scnum);
524             }
525           else if (h->root.type == bfd_link_hash_defined
526                    || h->root.type == bfd_link_hash_defweak)
527             targetsec = h->root.u.def.section;
528           else
529             targetsec = NULL;
530         }
531
532       bfd_put_32 (abfd,
533                   (irel->r_vaddr - datasec->vma + datasec->output_offset), p);
534       memset (p + 4, 0, 8);
535       if (targetsec != NULL)
536         strncpy ((char *) p + 4, targetsec->output_section->name, 8);
537     }
538
539   return TRUE;
540 }
541 #endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS  */
542 \f
543 #define coff_bfd_is_local_label_name m68k_coff_is_local_label_name
544
545 #define coff_relocate_section _bfd_coff_generic_relocate_section
546
547 #include "coffcode.h"
548
549 #ifndef TARGET_SYM
550 #define TARGET_SYM m68kcoff_vec
551 #endif
552
553 #ifndef TARGET_NAME
554 #define TARGET_NAME "coff-m68k"
555 #endif
556
557 #ifdef NAMES_HAVE_UNDERSCORE
558 CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)
559 #else
560 CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL, COFF_SWAP_TABLE)
561 #endif