Convert to ISO C90
[external/binutils.git] / bfd / elf32-iq2000.c
1 /* IQ2000-specific support for 32-bit ELF.
2    Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3
4    This file is part of BFD, the Binary File Descriptor library.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23 #include "elf-bfd.h"
24 #include "elf/iq2000.h"
25
26 /* Forward declarations.  */
27
28 static bfd_reloc_status_type iq2000_elf_howto_hi16_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
29
30 \f
31 static reloc_howto_type iq2000_elf_howto_table [] =
32 {
33   /* This reloc does nothing.  */
34
35   HOWTO (R_IQ2000_NONE,              /* type */
36          0,                          /* rightshift */
37          2,                          /* size (0 = byte, 1 = short, 2 = long) */
38          32,                         /* bitsize */
39          FALSE,                      /* pc_relative */
40          0,                          /* bitpos */
41          complain_overflow_bitfield, /* complain_on_overflow */
42          bfd_elf_generic_reloc,      /* special_function */
43          "R_IQ2000_NONE",            /* name */
44          FALSE,                      /* partial_inplace */
45          0,                          /* src_mask */
46          0,                          /* dst_mask */
47          FALSE),                     /* pcrel_offset */
48
49   /* A 16 bit absolute relocation.  */
50   HOWTO (R_IQ2000_16,                /* type */
51          0,                          /* rightshift */
52          1,                          /* size (0 = byte, 1 = short, 2 = long) */
53          16,                         /* bitsize */
54          FALSE,                      /* pc_relative */
55          0,                          /* bitpos */
56          complain_overflow_bitfield, /* complain_on_overflow */
57          bfd_elf_generic_reloc,      /* special_function */
58          "R_IQ2000_16",              /* name */
59          FALSE,                      /* partial_inplace */
60          0x0000,                     /* src_mask */
61          0xffff,                     /* dst_mask */
62          FALSE),                     /* pcrel_offset */
63
64   /* A 32 bit absolute relocation.  */
65   HOWTO (R_IQ2000_32,                /* type */
66          0,                          /* rightshift */
67          2,                          /* size (0 = byte, 1 = short, 2 = long) */
68          31,                         /* bitsize */
69          FALSE,                      /* pc_relative */
70          0,                          /* bitpos */
71          complain_overflow_bitfield, /* complain_on_overflow */
72          bfd_elf_generic_reloc,      /* special_function */
73          "R_IQ2000_32",              /* name */
74          FALSE,                      /* partial_inplace */
75          0x00000000,                 /* src_mask */
76          0x7fffffff,                 /* dst_mask */
77          FALSE),                     /* pcrel_offset */
78
79   /* 26 bit branch address.  */
80   HOWTO (R_IQ2000_26,           /* type */
81          2,                     /* rightshift */
82          2,                     /* size (0 = byte, 1 = short, 2 = long) */
83          26,                    /* bitsize */
84          FALSE,                 /* pc_relative */
85          0,                     /* bitpos */
86          complain_overflow_dont, /* complain_on_overflow */
87                                 /* This needs complex overflow
88                                    detection, because the upper four
89                                    bits must match the PC.  */
90          bfd_elf_generic_reloc, /* special_function */
91          "R_IQ2000_26",         /* name */
92          FALSE,                 /* partial_inplace */
93          0x00000000,            /* src_mask */
94          0x03ffffff,            /* dst_mask */
95          FALSE),                /* pcrel_offset */
96
97   /* 16 bit PC relative reference.  */
98   HOWTO (R_IQ2000_PC16,         /* type */
99          2,                     /* rightshift */
100          2,                     /* size (0 = byte, 1 = short, 2 = long) */
101          16,                    /* bitsize */
102          TRUE,                  /* pc_relative */
103          0,                     /* bitpos */
104          complain_overflow_signed, /* complain_on_overflow */
105          bfd_elf_generic_reloc, /* special_function */
106          "R_IQ2000_PC16",       /* name */
107          FALSE,                 /* partial_inplace */
108          0x0000,                /* src_mask */
109          0xffff,                /* dst_mask */
110          TRUE),                 /* pcrel_offset */
111
112   /* high 16 bits of symbol value.  */
113   HOWTO (R_IQ2000_HI16,         /* type */
114          16,                    /* rightshift */
115          2,                     /* size (0 = byte, 1 = short, 2 = long) */
116          15,                    /* bitsize */
117          FALSE,                 /* pc_relative */
118          0,                     /* bitpos */
119          complain_overflow_dont, /* complain_on_overflow */
120          iq2000_elf_howto_hi16_reloc,   /* special_function */
121          "R_IQ2000_HI16",       /* name */
122          FALSE,                 /* partial_inplace */
123          0x0000,                /* src_mask */
124          0x7fff,                /* dst_mask */
125          FALSE),                /* pcrel_offset */
126
127   /* Low 16 bits of symbol value.  */
128   HOWTO (R_IQ2000_LO16,         /* type */
129          0,                     /* rightshift */
130          2,                     /* size (0 = byte, 1 = short, 2 = long) */
131          16,                    /* bitsize */
132          FALSE,                 /* pc_relative */
133          0,                     /* bitpos */
134          complain_overflow_dont, /* complain_on_overflow */
135          bfd_elf_generic_reloc, /* special_function */
136          "R_IQ2000_LO16",       /* name */
137          FALSE,                 /* partial_inplace */
138          0x0000,                /* src_mask */
139          0xffff,                /* dst_mask */
140          FALSE),                /* pcrel_offset */
141
142   /* 16-bit jump offset.  */
143   HOWTO (R_IQ2000_OFFSET_16,    /* type */
144          2,                     /* rightshift */
145          2,                     /* size (0 = byte, 1 = short, 2 = long) */
146          16,                    /* bitsize */
147          FALSE,                 /* pc_relative */
148          0,                     /* bitpos */
149          complain_overflow_dont, /* complain_on_overflow */
150          bfd_elf_generic_reloc, /* special_function */
151          "R_IQ2000_OFFSET_16",  /* name */
152          FALSE,                 /* partial_inplace */
153          0x0000,                /* src_mask */
154          0xffff,                /* dst_mask */
155          FALSE),                /* pcrel_offset */
156
157   /* 21-bit jump offset.  */
158   HOWTO (R_IQ2000_OFFSET_21,    /* type */
159          2,                     /* rightshift */
160          2,                     /* size (0 = byte, 1 = short, 2 = long) */
161          21,                    /* bitsize */
162          FALSE,                 /* pc_relative */
163          0,                     /* bitpos */
164          complain_overflow_dont, /* complain_on_overflow */
165          bfd_elf_generic_reloc, /* special_function */
166          "R_IQ2000_OFFSET_21",  /* name */
167          FALSE,                 /* partial_inplace */
168          0x000000,              /* src_mask */
169          0x1fffff,              /* dst_mask */
170          FALSE),                /* pcrel_offset */
171
172   /* unsigned high 16 bits of value.  */
173   HOWTO (R_IQ2000_OFFSET_21,    /* type */
174          16,                    /* rightshift */
175          2,                     /* size (0 = byte, 1 = short, 2 = long) */
176          16,                    /* bitsize */
177          FALSE,                 /* pc_relative */
178          0,                     /* bitpos */
179          complain_overflow_dont, /* complain_on_overflow */
180          bfd_elf_generic_reloc, /* special_function */
181          "R_IQ2000_UHI16",      /* name */
182          FALSE,                 /* partial_inplace */
183          0x0000,                /* src_mask */
184          0x7fff,                /* dst_mask */
185          FALSE),                /* pcrel_offset */
186
187   /* A 32 bit absolute debug relocation.  */
188   HOWTO (R_IQ2000_32_DEBUG,          /* type */
189          0,                          /* rightshift */
190          2,                          /* size (0 = byte, 1 = short, 2 = long) */
191          32,                         /* bitsize */
192          FALSE,                      /* pc_relative */
193          0,                          /* bitpos */
194          complain_overflow_bitfield, /* complain_on_overflow */
195          bfd_elf_generic_reloc,      /* special_function */
196          "R_IQ2000_32",              /* name */
197          FALSE,                      /* partial_inplace */
198          0x00000000,                 /* src_mask */
199          0xffffffff,                 /* dst_mask */
200          FALSE),                     /* pcrel_offset */
201
202 };
203
204 /* GNU extension to record C++ vtable hierarchy.  */
205 static reloc_howto_type iq2000_elf_vtinherit_howto =
206   HOWTO (R_IQ2000_GNU_VTINHERIT,    /* type */
207          0,                        /* rightshift */
208          2,                        /* size (0 = byte, 1 = short, 2 = long) */
209          0,                        /* bitsize */
210          FALSE,                    /* pc_relative */
211          0,                        /* bitpos */
212          complain_overflow_dont,   /* complain_on_overflow */
213          NULL,                     /* special_function */
214          "R_IQ2000_GNU_VTINHERIT",  /* name */
215          FALSE,                    /* partial_inplace */
216          0,                        /* src_mask */
217          0,                        /* dst_mask */
218          FALSE);                   /* pcrel_offset */
219
220 /* GNU extension to record C++ vtable member usage.  */
221 static reloc_howto_type iq2000_elf_vtentry_howto =
222   HOWTO (R_IQ2000_GNU_VTENTRY,     /* type */
223          0,                        /* rightshift */
224          2,                        /* size (0 = byte, 1 = short, 2 = long) */
225          0,                        /* bitsize */
226          FALSE,                    /* pc_relative */
227          0,                        /* bitpos */
228          complain_overflow_dont,   /* complain_on_overflow */
229          NULL,                     /* special_function */
230          "R_IQ2000_GNU_VTENTRY",    /* name */
231          FALSE,                    /* partial_inplace */
232          0,                        /* src_mask */
233          0,                        /* dst_mask */
234          FALSE);                   /* pcrel_offset */
235
236 \f
237 /* Map BFD reloc types to IQ2000 ELF reloc types.  */
238
239 struct iq2000_reloc_map
240 {
241   bfd_reloc_code_real_type bfd_reloc_val;
242   unsigned int iq2000_reloc_val;
243 };
244
245 static const struct iq2000_reloc_map iq2000_reloc_map [] =
246 {
247   { BFD_RELOC_NONE,            R_IQ2000_NONE },
248   { BFD_RELOC_16,              R_IQ2000_16 },
249   { BFD_RELOC_32,              R_IQ2000_32 },
250   { BFD_RELOC_MIPS_JMP,        R_IQ2000_26 },
251   { BFD_RELOC_16_PCREL_S2,     R_IQ2000_PC16 },
252   { BFD_RELOC_HI16,            R_IQ2000_HI16 },
253   { BFD_RELOC_LO16,            R_IQ2000_LO16 },
254   { BFD_RELOC_IQ2000_OFFSET_16,R_IQ2000_OFFSET_16 },
255   { BFD_RELOC_IQ2000_OFFSET_21,R_IQ2000_OFFSET_21 },
256   { BFD_RELOC_IQ2000_UHI16,    R_IQ2000_UHI16 },
257   { BFD_RELOC_VTABLE_INHERIT,  R_IQ2000_GNU_VTINHERIT },
258   { BFD_RELOC_VTABLE_ENTRY,    R_IQ2000_GNU_VTENTRY },
259 };
260
261 static bfd_reloc_status_type
262 iq2000_elf_howto_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
263                              arelent *reloc_entry,
264                              asymbol *symbol,
265                              void * data,
266                              asection *input_section,
267                              bfd *output_bfd,
268                              char **error_message ATTRIBUTE_UNUSED)
269 {
270   bfd_reloc_status_type ret;
271   bfd_vma relocation;
272
273   /* If we're relocating and this an external symbol,
274      we don't want to change anything.  */
275   if (output_bfd != (bfd *) NULL
276       && (symbol->flags & BSF_SECTION_SYM) == 0
277       && reloc_entry->addend == 0)
278     {
279       reloc_entry->address += input_section->output_offset;
280       return bfd_reloc_ok;
281     }
282
283   if (bfd_is_com_section (symbol->section))
284     relocation = 0;
285   else
286     relocation = symbol->value;
287
288   relocation += symbol->section->output_section->vma;
289   relocation += symbol->section->output_offset;
290   relocation += reloc_entry->addend;
291
292   /* If %lo will have sign-extension, compensate by add 0x10000 to hi portion.  */
293   if (relocation & 0x8000)
294     reloc_entry->addend += 0x10000;
295
296   /* Now do the reloc in the usual way.  */
297   ret = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
298                                 input_section, output_bfd, error_message);
299
300   /* Put it back the way it was.  */
301   if (relocation & 0x8000)
302     reloc_entry->addend -= 0x10000;
303
304   return ret;
305 }
306
307 static bfd_reloc_status_type
308 iq2000_elf_relocate_hi16 (bfd *input_bfd,
309                           Elf_Internal_Rela *relhi,
310                           bfd_byte *contents,
311                           bfd_vma value)
312 {
313   bfd_vma insn;
314
315   insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
316   
317   value += relhi->r_addend;
318   value &= 0x7fffffff; /* Mask off top-bit which is Harvard mask bit.  */
319
320   /* If top-bit of %lo value is on, this means that %lo will
321      sign-propagate and so we compensate by adding 1 to %hi value.  */
322   if (value & 0x8000)
323     value += 0x10000;
324
325   value >>= 16; 
326   insn = ((insn & ~0xFFFF) | value);
327
328   bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
329   return bfd_reloc_ok;
330 }
331
332 static reloc_howto_type *
333 iq2000_reloc_type_lookup (abfd, code)
334      bfd * abfd ATTRIBUTE_UNUSED;
335      bfd_reloc_code_real_type code;
336 {
337   /* Note that the iq2000_elf_howto_table is indxed by the R_
338      constants.  Thus, the order that the howto records appear in the
339      table *must* match the order of the relocation types defined in
340      include/elf/iq2000.h.  */
341
342   switch (code)
343     {
344     case BFD_RELOC_NONE:
345       return &iq2000_elf_howto_table[ (int) R_IQ2000_NONE];
346     case BFD_RELOC_16:
347       return &iq2000_elf_howto_table[ (int) R_IQ2000_16];
348     case BFD_RELOC_32:
349       return &iq2000_elf_howto_table[ (int) R_IQ2000_32];
350     case BFD_RELOC_MIPS_JMP:
351       return &iq2000_elf_howto_table[ (int) R_IQ2000_26];
352     case BFD_RELOC_IQ2000_OFFSET_16:
353       return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_16];
354     case BFD_RELOC_IQ2000_OFFSET_21:
355       return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_21];
356     case BFD_RELOC_16_PCREL_S2:
357       return &iq2000_elf_howto_table[ (int) R_IQ2000_PC16];
358     case BFD_RELOC_HI16:
359       return &iq2000_elf_howto_table[ (int) R_IQ2000_HI16];
360     case BFD_RELOC_IQ2000_UHI16:
361       return &iq2000_elf_howto_table[ (int) R_IQ2000_UHI16];
362     case BFD_RELOC_LO16:
363       return &iq2000_elf_howto_table[ (int) R_IQ2000_LO16];
364     case BFD_RELOC_VTABLE_INHERIT:
365       return &iq2000_elf_vtinherit_howto;
366     case BFD_RELOC_VTABLE_ENTRY:
367       return &iq2000_elf_vtentry_howto;
368     default:
369       /* Pacify gcc -Wall.  */
370       return NULL;
371     }
372   return NULL;
373 }
374
375 \f
376 /* Perform a single relocation.  By default we use the standard BFD
377    routines.  */
378
379 static bfd_reloc_status_type
380 iq2000_final_link_relocate (reloc_howto_type *  howto,
381                             bfd *               input_bfd,
382                             asection *          input_section,
383                             bfd_byte *          contents,
384                             Elf_Internal_Rela * rel,
385                             bfd_vma             relocation)
386 {
387   return _bfd_final_link_relocate (howto, input_bfd, input_section,
388                                    contents, rel->r_offset,
389                                    relocation, rel->r_addend);
390 }
391 \f
392 /* Set the howto pointer for a IQ2000 ELF reloc.  */
393
394 static void
395 iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
396                            arelent * cache_ptr,
397                            Elf_Internal_Rela * dst)
398 {
399   unsigned int r_type;
400
401   r_type = ELF32_R_TYPE (dst->r_info);
402   switch (r_type)
403     {
404     case R_IQ2000_GNU_VTINHERIT:
405       cache_ptr->howto = & iq2000_elf_vtinherit_howto;
406       break;
407
408     case R_IQ2000_GNU_VTENTRY:
409       cache_ptr->howto = & iq2000_elf_vtentry_howto;
410       break;
411
412     default:
413       cache_ptr->howto = & iq2000_elf_howto_table [r_type];
414       break;
415     }
416 }
417
418 /* Look through the relocs for a section during the first phase.
419    Since we don't do .gots or .plts, we just need to consider the
420    virtual table relocs for gc.  */
421  
422 static bfd_boolean
423 iq2000_elf_check_relocs (bfd *abfd,
424                          struct bfd_link_info *info,
425                          asection *sec,
426                          const Elf_Internal_Rela *relocs)
427 {
428   Elf_Internal_Shdr *symtab_hdr;
429   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
430   const Elf_Internal_Rela *rel;
431   const Elf_Internal_Rela *rel_end;
432   bfd_boolean changed = FALSE;
433   
434   if (info->relocatable)
435     return TRUE;
436   
437   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
438   sym_hashes = elf_sym_hashes (abfd);
439   sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
440   if (!elf_bad_symtab (abfd))
441     sym_hashes_end -= symtab_hdr->sh_info;
442   
443   rel_end = relocs + sec->reloc_count;
444   for (rel = relocs; rel < rel_end; rel++)
445     {
446       struct elf_link_hash_entry *h;
447       unsigned long r_symndx;
448       
449       r_symndx = ELF32_R_SYM (rel->r_info);
450       if (r_symndx < symtab_hdr->sh_info)
451         h = NULL;
452       else
453         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
454       
455       switch (ELF32_R_TYPE (rel->r_info))
456         {
457           /* This relocation describes the C++ object vtable
458              hierarchy.  Reconstruct it for later use during GC.  */
459         case R_IQ2000_GNU_VTINHERIT:
460           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
461             return FALSE;
462           break;
463           
464           /* This relocation describes which C++ vtable entries
465              are actually used.  Record for later use during GC.  */
466         case R_IQ2000_GNU_VTENTRY:
467           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
468             return FALSE;
469           break;
470
471         case R_IQ2000_32:
472           /* For debug section, change to special harvard-aware relocations.  */
473           if (memcmp (sec->name, ".debug", 6) == 0
474               || memcmp (sec->name, ".stab", 5) == 0
475               || memcmp (sec->name, ".eh_frame", 9) == 0)
476             {
477               ((Elf_Internal_Rela *) rel)->r_info
478                 = ELF32_R_INFO (ELF32_R_SYM (rel->r_info), R_IQ2000_32_DEBUG);
479               changed = TRUE;
480             }
481           break;
482         }
483     }
484
485   if (changed)
486     /* Note that we've changed relocs, otherwise if !info->keep_memory
487        we'll free the relocs and lose our changes.  */
488     elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
489
490   return TRUE;
491 }
492
493 \f
494 /* Relocate a IQ2000 ELF section.
495    There is some attempt to make this function usable for many architectures,
496    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
497    if only to serve as a learning tool.
498
499    The RELOCATE_SECTION function is called by the new ELF backend linker
500    to handle the relocations for a section.
501
502    The relocs are always passed as Rela structures; if the section
503    actually uses Rel structures, the r_addend field will always be
504    zero.
505
506    This function is responsible for adjusting the section contents as
507    necessary, and (if using Rela relocs and generating a relocatable
508    output file) adjusting the reloc addend as necessary.
509
510    This function does not have to worry about setting the reloc
511    address or the reloc symbol index.
512
513    LOCAL_SYMS is a pointer to the swapped in local symbols.
514
515    LOCAL_SECTIONS is an array giving the section in the input file
516    corresponding to the st_shndx field of each local symbol.
517
518    The global hash table entry for the global symbols can be found
519    via elf_sym_hashes (input_bfd).
520
521    When generating relocatable output, this function must handle
522    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
523    going to be the section symbol corresponding to the output
524    section, which means that the addend must be adjusted
525    accordingly.  */
526
527 static bfd_boolean
528 iq2000_elf_relocate_section (bfd *                   output_bfd ATTRIBUTE_UNUSED,
529                              struct bfd_link_info *  info,
530                              bfd *                   input_bfd,
531                              asection *              input_section,
532                              bfd_byte *              contents,
533                              Elf_Internal_Rela *     relocs,
534                              Elf_Internal_Sym *      local_syms,
535                              asection **             local_sections)
536 {
537   Elf_Internal_Shdr *           symtab_hdr;
538   struct elf_link_hash_entry ** sym_hashes;
539   Elf_Internal_Rela *           rel;
540   Elf_Internal_Rela *           relend;
541
542   if (info->relocatable)
543     return TRUE;
544
545   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
546   sym_hashes = elf_sym_hashes (input_bfd);
547   relend     = relocs + input_section->reloc_count;
548
549   for (rel = relocs; rel < relend; rel ++)
550     {
551       reloc_howto_type *           howto;
552       unsigned long                r_symndx;
553       Elf_Internal_Sym *           sym;
554       asection *                   sec;
555       struct elf_link_hash_entry * h;
556       bfd_vma                      relocation;
557       bfd_reloc_status_type        r;
558       const char *                 name = NULL;
559       int                          r_type;
560       
561       r_type = ELF32_R_TYPE (rel->r_info);
562       
563       if (   r_type == R_IQ2000_GNU_VTINHERIT
564           || r_type == R_IQ2000_GNU_VTENTRY)
565         continue;
566       
567       r_symndx = ELF32_R_SYM (rel->r_info);
568
569       /* This is a final link.  */
570       howto  = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
571       h      = NULL;
572       sym    = NULL;
573       sec    = NULL;
574       
575       if (r_symndx < symtab_hdr->sh_info)
576         {
577           sym = local_syms + r_symndx;
578           sec = local_sections [r_symndx];
579           relocation = (sec->output_section->vma
580                         + sec->output_offset
581                         + sym->st_value);
582           
583           name = bfd_elf_string_from_elf_section
584             (input_bfd, symtab_hdr->sh_link, sym->st_name);
585           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
586         }
587       else
588         {
589           bfd_boolean unresolved_reloc;
590           bfd_boolean warned;
591
592           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
593                                    r_symndx, symtab_hdr, sym_hashes,
594                                    h, sec, relocation,
595                                    unresolved_reloc, warned);
596
597           name = h->root.root.string;
598         }
599
600       switch (r_type)
601         {
602         case R_IQ2000_HI16:
603           r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
604           break;
605
606         case R_IQ2000_PC16:
607           rel->r_addend -= 4;
608           /* Fall through.  */
609
610         default:
611           r = iq2000_final_link_relocate (howto, input_bfd, input_section,
612                                          contents, rel, relocation);
613           break;
614         }
615
616       if (r != bfd_reloc_ok)
617         {
618           const char * msg = (const char *) NULL;
619
620           switch (r)
621             {
622             case bfd_reloc_overflow:
623               r = info->callbacks->reloc_overflow
624                 (info, (h ? &h->root : NULL), name, howto->name,
625                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
626               break;
627               
628             case bfd_reloc_undefined:
629               r = info->callbacks->undefined_symbol
630                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
631               break;
632               
633             case bfd_reloc_outofrange:
634               msg = _("internal error: out of range error");
635               break;
636
637             case bfd_reloc_notsupported:
638               msg = _("internal error: unsupported relocation error");
639               break;
640
641             case bfd_reloc_dangerous:
642               msg = _("internal error: dangerous relocation");
643               break;
644
645             default:
646               msg = _("internal error: unknown error");
647               break;
648             }
649
650           if (msg)
651             r = info->callbacks->warning
652               (info, msg, name, input_bfd, input_section, rel->r_offset);
653
654           if (! r)
655             return FALSE;
656         }
657     }
658
659   return TRUE;
660 }
661 \f
662
663 /* Update the got entry reference counts for the section being
664    removed.  */
665
666 static bfd_boolean
667 iq2000_elf_gc_sweep_hook (bfd *                     abfd ATTRIBUTE_UNUSED,
668                           struct bfd_link_info *    info ATTRIBUTE_UNUSED,
669                           asection *                sec ATTRIBUTE_UNUSED,
670                           const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
671 {
672   return TRUE;
673 }
674
675 /* Return the section that should be marked against GC for a given
676    relocation.  */
677
678 static asection *
679 iq2000_elf_gc_mark_hook (asection *                   sec,
680                          struct bfd_link_info *       info ATTRIBUTE_UNUSED,
681                          Elf_Internal_Rela *          rel,
682                          struct elf_link_hash_entry * h,
683                          Elf_Internal_Sym *           sym)
684 {
685   if (h == NULL)
686     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
687
688   switch (ELF32_R_TYPE (rel->r_info))
689     {
690     case R_IQ2000_GNU_VTINHERIT:
691     case R_IQ2000_GNU_VTENTRY:
692       break;
693           
694     default:
695       switch (h->root.type)
696         {
697         case bfd_link_hash_defined:
698         case bfd_link_hash_defweak:
699           return h->root.u.def.section;
700               
701         case bfd_link_hash_common:
702           return h->root.u.c.p->section;
703               
704         default:
705           break;
706         }
707     }
708
709   return NULL;
710 }
711
712 \f
713 /* Return the MACH for an e_flags value.  */
714
715 static int
716 elf32_iq2000_machine (bfd *abfd)
717 {
718   switch (elf_elfheader (abfd)->e_flags & EF_IQ2000_CPU_MASK)
719     {
720     case EF_IQ2000_CPU_IQ10:
721       return bfd_mach_iq10;
722
723     case EF_IQ2000_CPU_IQ2000:
724     default:
725       return bfd_mach_iq2000;
726     }
727 }
728
729 \f
730 /* Function to set the ELF flag bits.  */
731
732 static bfd_boolean
733 iq2000_elf_set_private_flags (bfd *abfd, flagword flags)
734 {
735   elf_elfheader (abfd)->e_flags = flags;
736   elf_flags_init (abfd) = TRUE;
737   return TRUE;
738 }
739
740 /* Copy backend specific data from one object module to another.  */
741
742 static bfd_boolean
743 iq2000_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
744 {
745   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
746       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
747     return TRUE;
748
749   BFD_ASSERT (!elf_flags_init (obfd)
750               || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
751
752   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
753   elf_flags_init (obfd) = TRUE;
754   return TRUE;
755 }
756
757 /* Merge backend specific data from an object
758    file to the output object file when linking.  */
759
760 static bfd_boolean
761 iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
762 {
763   flagword old_flags, old_partial;
764   flagword new_flags, new_partial;
765   bfd_boolean error = FALSE;
766   char new_opt[80];
767   char old_opt[80];
768
769   new_opt[0] = old_opt[0] = '\0';
770   new_flags = elf_elfheader (ibfd)->e_flags;
771   old_flags = elf_elfheader (obfd)->e_flags;
772
773   if (!elf_flags_init (obfd))
774     {
775       /* First call, no flags set.  */
776       elf_flags_init (obfd) = TRUE;
777       elf_elfheader (obfd)->e_flags = new_flags;
778     }
779
780   else if (new_flags != old_flags)
781     {
782       /* Warn if different cpu is used, but allow a
783          specific cpu to override the generic cpu.  */
784       new_partial = (new_flags & EF_IQ2000_CPU_MASK);
785       old_partial = (old_flags & EF_IQ2000_CPU_MASK);
786
787       if (new_partial != old_partial)
788         {
789           switch (new_partial)
790             {
791             case EF_IQ2000_CPU_IQ10:
792               strcat (new_opt, " -m10");
793               break;
794
795             default:
796             case EF_IQ2000_CPU_IQ2000:
797               strcat (new_opt, " -m2000");
798               break;
799             }
800
801           switch (old_partial)
802             {
803             case EF_IQ2000_CPU_IQ10:
804               strcat (old_opt, " -m10");
805               break;
806
807             default:
808             case EF_IQ2000_CPU_IQ2000:
809               strcat (old_opt, " -m2000");
810               break;
811             }
812         }
813       
814       /* Print out any mismatches from above.  */
815       if (new_opt[0])
816         {
817           error = TRUE;
818           _bfd_error_handler
819             (_("%s: compiled with %s and linked with modules compiled with %s"),
820              bfd_get_filename (ibfd), new_opt, old_opt);
821         }
822
823       new_flags &= ~ EF_IQ2000_ALL_FLAGS;
824       old_flags &= ~ EF_IQ2000_ALL_FLAGS;
825
826       /* Warn about any other mismatches.  */
827       if (new_flags != old_flags)
828         {
829           error = TRUE;
830
831           _bfd_error_handler
832             (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
833              bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
834         }
835     }
836
837   if (error)
838     bfd_set_error (bfd_error_bad_value);
839
840   return !error;
841 }
842
843 \f
844 static bfd_boolean
845 iq2000_elf_print_private_bfd_data (bfd *abfd, void * ptr)
846 {
847   FILE *file = (FILE *) ptr;
848   flagword flags;
849
850   BFD_ASSERT (abfd != NULL && ptr != NULL);
851
852   /* Print normal ELF private data.  */
853   _bfd_elf_print_private_bfd_data (abfd, ptr);
854
855   flags = elf_elfheader (abfd)->e_flags;
856   fprintf (file, _("private flags = 0x%lx:"), (long)flags);
857
858   switch (flags & EF_IQ2000_CPU_MASK)
859     {
860     case EF_IQ2000_CPU_IQ10:
861       fprintf (file, " -m10");
862       break;
863     case EF_IQ2000_CPU_IQ2000:
864       fprintf (file, " -m2000");
865       break;
866     default:
867       break;
868     }
869
870   fputc ('\n', file);
871   return TRUE;
872 }
873
874 static
875 bfd_boolean
876 iq2000_elf_object_p (bfd *abfd)
877 {
878   bfd_default_set_arch_mach (abfd, bfd_arch_iq2000,
879                              elf32_iq2000_machine (abfd));
880   return TRUE;
881 }
882
883 \f
884 #define ELF_ARCH                bfd_arch_iq2000
885 #define ELF_MACHINE_CODE        EM_IQ2000
886 #define ELF_MAXPAGESIZE         0x1000
887
888 #define TARGET_BIG_SYM          bfd_elf32_iq2000_vec
889 #define TARGET_BIG_NAME         "elf32-iq2000"
890
891 #define elf_info_to_howto_rel                   NULL
892 #define elf_info_to_howto                       iq2000_info_to_howto_rela
893 #define elf_backend_relocate_section            iq2000_elf_relocate_section
894 #define elf_backend_gc_mark_hook                iq2000_elf_gc_mark_hook
895 #define elf_backend_gc_sweep_hook               iq2000_elf_gc_sweep_hook
896 #define elf_backend_check_relocs                iq2000_elf_check_relocs
897 #define elf_backend_object_p                    iq2000_elf_object_p
898 #define elf_backend_rela_normal                 1
899
900 #define elf_backend_can_gc_sections             1
901
902 #define bfd_elf32_bfd_reloc_type_lookup         iq2000_reloc_type_lookup
903 #define bfd_elf32_bfd_set_private_flags         iq2000_elf_set_private_flags
904 #define bfd_elf32_bfd_copy_private_bfd_data     iq2000_elf_copy_private_bfd_data
905 #define bfd_elf32_bfd_merge_private_bfd_data    iq2000_elf_merge_private_bfd_data
906 #define bfd_elf32_bfd_print_private_bfd_data    iq2000_elf_print_private_bfd_data
907
908 #include "elf32-target.h"