* elf32-arm.c (elf32_arm_finish_dynamic_sections): Warning fix.
[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 (bfd *abfd ATTRIBUTE_UNUSED,
334                           bfd_reloc_code_real_type code)
335 {
336   /* Note that the iq2000_elf_howto_table is indxed by the R_
337      constants.  Thus, the order that the howto records appear in the
338      table *must* match the order of the relocation types defined in
339      include/elf/iq2000.h.  */
340
341   switch (code)
342     {
343     case BFD_RELOC_NONE:
344       return &iq2000_elf_howto_table[ (int) R_IQ2000_NONE];
345     case BFD_RELOC_16:
346       return &iq2000_elf_howto_table[ (int) R_IQ2000_16];
347     case BFD_RELOC_32:
348       return &iq2000_elf_howto_table[ (int) R_IQ2000_32];
349     case BFD_RELOC_MIPS_JMP:
350       return &iq2000_elf_howto_table[ (int) R_IQ2000_26];
351     case BFD_RELOC_IQ2000_OFFSET_16:
352       return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_16];
353     case BFD_RELOC_IQ2000_OFFSET_21:
354       return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_21];
355     case BFD_RELOC_16_PCREL_S2:
356       return &iq2000_elf_howto_table[ (int) R_IQ2000_PC16];
357     case BFD_RELOC_HI16:
358       return &iq2000_elf_howto_table[ (int) R_IQ2000_HI16];
359     case BFD_RELOC_IQ2000_UHI16:
360       return &iq2000_elf_howto_table[ (int) R_IQ2000_UHI16];
361     case BFD_RELOC_LO16:
362       return &iq2000_elf_howto_table[ (int) R_IQ2000_LO16];
363     case BFD_RELOC_VTABLE_INHERIT:
364       return &iq2000_elf_vtinherit_howto;
365     case BFD_RELOC_VTABLE_ENTRY:
366       return &iq2000_elf_vtentry_howto;
367     default:
368       /* Pacify gcc -Wall.  */
369       return NULL;
370     }
371   return NULL;
372 }
373
374 \f
375 /* Perform a single relocation.  By default we use the standard BFD
376    routines.  */
377
378 static bfd_reloc_status_type
379 iq2000_final_link_relocate (reloc_howto_type *  howto,
380                             bfd *               input_bfd,
381                             asection *          input_section,
382                             bfd_byte *          contents,
383                             Elf_Internal_Rela * rel,
384                             bfd_vma             relocation)
385 {
386   return _bfd_final_link_relocate (howto, input_bfd, input_section,
387                                    contents, rel->r_offset,
388                                    relocation, rel->r_addend);
389 }
390 \f
391 /* Set the howto pointer for a IQ2000 ELF reloc.  */
392
393 static void
394 iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
395                            arelent * cache_ptr,
396                            Elf_Internal_Rela * dst)
397 {
398   unsigned int r_type;
399
400   r_type = ELF32_R_TYPE (dst->r_info);
401   switch (r_type)
402     {
403     case R_IQ2000_GNU_VTINHERIT:
404       cache_ptr->howto = & iq2000_elf_vtinherit_howto;
405       break;
406
407     case R_IQ2000_GNU_VTENTRY:
408       cache_ptr->howto = & iq2000_elf_vtentry_howto;
409       break;
410
411     default:
412       cache_ptr->howto = & iq2000_elf_howto_table [r_type];
413       break;
414     }
415 }
416
417 /* Look through the relocs for a section during the first phase.
418    Since we don't do .gots or .plts, we just need to consider the
419    virtual table relocs for gc.  */
420  
421 static bfd_boolean
422 iq2000_elf_check_relocs (bfd *abfd,
423                          struct bfd_link_info *info,
424                          asection *sec,
425                          const Elf_Internal_Rela *relocs)
426 {
427   Elf_Internal_Shdr *symtab_hdr;
428   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
429   const Elf_Internal_Rela *rel;
430   const Elf_Internal_Rela *rel_end;
431   bfd_boolean changed = FALSE;
432   
433   if (info->relocatable)
434     return TRUE;
435   
436   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
437   sym_hashes = elf_sym_hashes (abfd);
438   sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
439   if (!elf_bad_symtab (abfd))
440     sym_hashes_end -= symtab_hdr->sh_info;
441   
442   rel_end = relocs + sec->reloc_count;
443   for (rel = relocs; rel < rel_end; rel++)
444     {
445       struct elf_link_hash_entry *h;
446       unsigned long r_symndx;
447       
448       r_symndx = ELF32_R_SYM (rel->r_info);
449       if (r_symndx < symtab_hdr->sh_info)
450         h = NULL;
451       else
452         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
453       
454       switch (ELF32_R_TYPE (rel->r_info))
455         {
456           /* This relocation describes the C++ object vtable
457              hierarchy.  Reconstruct it for later use during GC.  */
458         case R_IQ2000_GNU_VTINHERIT:
459           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
460             return FALSE;
461           break;
462           
463           /* This relocation describes which C++ vtable entries
464              are actually used.  Record for later use during GC.  */
465         case R_IQ2000_GNU_VTENTRY:
466           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
467             return FALSE;
468           break;
469
470         case R_IQ2000_32:
471           /* For debug section, change to special harvard-aware relocations.  */
472           if (memcmp (sec->name, ".debug", 6) == 0
473               || memcmp (sec->name, ".stab", 5) == 0
474               || memcmp (sec->name, ".eh_frame", 9) == 0)
475             {
476               ((Elf_Internal_Rela *) rel)->r_info
477                 = ELF32_R_INFO (ELF32_R_SYM (rel->r_info), R_IQ2000_32_DEBUG);
478               changed = TRUE;
479             }
480           break;
481         }
482     }
483
484   if (changed)
485     /* Note that we've changed relocs, otherwise if !info->keep_memory
486        we'll free the relocs and lose our changes.  */
487     elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
488
489   return TRUE;
490 }
491
492 \f
493 /* Relocate a IQ2000 ELF section.
494    There is some attempt to make this function usable for many architectures,
495    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
496    if only to serve as a learning tool.
497
498    The RELOCATE_SECTION function is called by the new ELF backend linker
499    to handle the relocations for a section.
500
501    The relocs are always passed as Rela structures; if the section
502    actually uses Rel structures, the r_addend field will always be
503    zero.
504
505    This function is responsible for adjusting the section contents as
506    necessary, and (if using Rela relocs and generating a relocatable
507    output file) adjusting the reloc addend as necessary.
508
509    This function does not have to worry about setting the reloc
510    address or the reloc symbol index.
511
512    LOCAL_SYMS is a pointer to the swapped in local symbols.
513
514    LOCAL_SECTIONS is an array giving the section in the input file
515    corresponding to the st_shndx field of each local symbol.
516
517    The global hash table entry for the global symbols can be found
518    via elf_sym_hashes (input_bfd).
519
520    When generating relocatable output, this function must handle
521    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
522    going to be the section symbol corresponding to the output
523    section, which means that the addend must be adjusted
524    accordingly.  */
525
526 static bfd_boolean
527 iq2000_elf_relocate_section (bfd *                   output_bfd ATTRIBUTE_UNUSED,
528                              struct bfd_link_info *  info,
529                              bfd *                   input_bfd,
530                              asection *              input_section,
531                              bfd_byte *              contents,
532                              Elf_Internal_Rela *     relocs,
533                              Elf_Internal_Sym *      local_syms,
534                              asection **             local_sections)
535 {
536   Elf_Internal_Shdr *           symtab_hdr;
537   struct elf_link_hash_entry ** sym_hashes;
538   Elf_Internal_Rela *           rel;
539   Elf_Internal_Rela *           relend;
540
541   if (info->relocatable)
542     return TRUE;
543
544   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
545   sym_hashes = elf_sym_hashes (input_bfd);
546   relend     = relocs + input_section->reloc_count;
547
548   for (rel = relocs; rel < relend; rel ++)
549     {
550       reloc_howto_type *           howto;
551       unsigned long                r_symndx;
552       Elf_Internal_Sym *           sym;
553       asection *                   sec;
554       struct elf_link_hash_entry * h;
555       bfd_vma                      relocation;
556       bfd_reloc_status_type        r;
557       const char *                 name = NULL;
558       int                          r_type;
559       
560       r_type = ELF32_R_TYPE (rel->r_info);
561       
562       if (   r_type == R_IQ2000_GNU_VTINHERIT
563           || r_type == R_IQ2000_GNU_VTENTRY)
564         continue;
565       
566       r_symndx = ELF32_R_SYM (rel->r_info);
567
568       /* This is a final link.  */
569       howto  = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
570       h      = NULL;
571       sym    = NULL;
572       sec    = NULL;
573       
574       if (r_symndx < symtab_hdr->sh_info)
575         {
576           sym = local_syms + r_symndx;
577           sec = local_sections [r_symndx];
578           relocation = (sec->output_section->vma
579                         + sec->output_offset
580                         + sym->st_value);
581           
582           name = bfd_elf_string_from_elf_section
583             (input_bfd, symtab_hdr->sh_link, sym->st_name);
584           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
585         }
586       else
587         {
588           bfd_boolean unresolved_reloc;
589           bfd_boolean warned;
590
591           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
592                                    r_symndx, symtab_hdr, sym_hashes,
593                                    h, sec, relocation,
594                                    unresolved_reloc, warned);
595
596           name = h->root.root.string;
597         }
598
599       switch (r_type)
600         {
601         case R_IQ2000_HI16:
602           r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
603           break;
604
605         case R_IQ2000_PC16:
606           rel->r_addend -= 4;
607           /* Fall through.  */
608
609         default:
610           r = iq2000_final_link_relocate (howto, input_bfd, input_section,
611                                          contents, rel, relocation);
612           break;
613         }
614
615       if (r != bfd_reloc_ok)
616         {
617           const char * msg = (const char *) NULL;
618
619           switch (r)
620             {
621             case bfd_reloc_overflow:
622               r = info->callbacks->reloc_overflow
623                 (info, (h ? &h->root : NULL), name, howto->name,
624                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
625               break;
626               
627             case bfd_reloc_undefined:
628               r = info->callbacks->undefined_symbol
629                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
630               break;
631               
632             case bfd_reloc_outofrange:
633               msg = _("internal error: out of range error");
634               break;
635
636             case bfd_reloc_notsupported:
637               msg = _("internal error: unsupported relocation error");
638               break;
639
640             case bfd_reloc_dangerous:
641               msg = _("internal error: dangerous relocation");
642               break;
643
644             default:
645               msg = _("internal error: unknown error");
646               break;
647             }
648
649           if (msg)
650             r = info->callbacks->warning
651               (info, msg, name, input_bfd, input_section, rel->r_offset);
652
653           if (! r)
654             return FALSE;
655         }
656     }
657
658   return TRUE;
659 }
660 \f
661
662 /* Update the got entry reference counts for the section being
663    removed.  */
664
665 static bfd_boolean
666 iq2000_elf_gc_sweep_hook (bfd *                     abfd ATTRIBUTE_UNUSED,
667                           struct bfd_link_info *    info ATTRIBUTE_UNUSED,
668                           asection *                sec ATTRIBUTE_UNUSED,
669                           const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
670 {
671   return TRUE;
672 }
673
674 /* Return the section that should be marked against GC for a given
675    relocation.  */
676
677 static asection *
678 iq2000_elf_gc_mark_hook (asection *                   sec,
679                          struct bfd_link_info *       info ATTRIBUTE_UNUSED,
680                          Elf_Internal_Rela *          rel,
681                          struct elf_link_hash_entry * h,
682                          Elf_Internal_Sym *           sym)
683 {
684   if (h == NULL)
685     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
686
687   switch (ELF32_R_TYPE (rel->r_info))
688     {
689     case R_IQ2000_GNU_VTINHERIT:
690     case R_IQ2000_GNU_VTENTRY:
691       break;
692           
693     default:
694       switch (h->root.type)
695         {
696         case bfd_link_hash_defined:
697         case bfd_link_hash_defweak:
698           return h->root.u.def.section;
699               
700         case bfd_link_hash_common:
701           return h->root.u.c.p->section;
702               
703         default:
704           break;
705         }
706     }
707
708   return NULL;
709 }
710
711 \f
712 /* Return the MACH for an e_flags value.  */
713
714 static int
715 elf32_iq2000_machine (bfd *abfd)
716 {
717   switch (elf_elfheader (abfd)->e_flags & EF_IQ2000_CPU_MASK)
718     {
719     case EF_IQ2000_CPU_IQ10:
720       return bfd_mach_iq10;
721
722     case EF_IQ2000_CPU_IQ2000:
723     default:
724       return bfd_mach_iq2000;
725     }
726 }
727
728 \f
729 /* Function to set the ELF flag bits.  */
730
731 static bfd_boolean
732 iq2000_elf_set_private_flags (bfd *abfd, flagword flags)
733 {
734   elf_elfheader (abfd)->e_flags = flags;
735   elf_flags_init (abfd) = TRUE;
736   return TRUE;
737 }
738
739 /* Copy backend specific data from one object module to another.  */
740
741 static bfd_boolean
742 iq2000_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
743 {
744   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
745       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
746     return TRUE;
747
748   BFD_ASSERT (!elf_flags_init (obfd)
749               || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
750
751   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
752   elf_flags_init (obfd) = TRUE;
753   return TRUE;
754 }
755
756 /* Merge backend specific data from an object
757    file to the output object file when linking.  */
758
759 static bfd_boolean
760 iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
761 {
762   flagword old_flags, old_partial;
763   flagword new_flags, new_partial;
764   bfd_boolean error = FALSE;
765   char new_opt[80];
766   char old_opt[80];
767
768   new_opt[0] = old_opt[0] = '\0';
769   new_flags = elf_elfheader (ibfd)->e_flags;
770   old_flags = elf_elfheader (obfd)->e_flags;
771
772   if (!elf_flags_init (obfd))
773     {
774       /* First call, no flags set.  */
775       elf_flags_init (obfd) = TRUE;
776       elf_elfheader (obfd)->e_flags = new_flags;
777     }
778
779   else if (new_flags != old_flags)
780     {
781       /* Warn if different cpu is used, but allow a
782          specific cpu to override the generic cpu.  */
783       new_partial = (new_flags & EF_IQ2000_CPU_MASK);
784       old_partial = (old_flags & EF_IQ2000_CPU_MASK);
785
786       if (new_partial != old_partial)
787         {
788           switch (new_partial)
789             {
790             case EF_IQ2000_CPU_IQ10:
791               strcat (new_opt, " -m10");
792               break;
793
794             default:
795             case EF_IQ2000_CPU_IQ2000:
796               strcat (new_opt, " -m2000");
797               break;
798             }
799
800           switch (old_partial)
801             {
802             case EF_IQ2000_CPU_IQ10:
803               strcat (old_opt, " -m10");
804               break;
805
806             default:
807             case EF_IQ2000_CPU_IQ2000:
808               strcat (old_opt, " -m2000");
809               break;
810             }
811         }
812       
813       /* Print out any mismatches from above.  */
814       if (new_opt[0])
815         {
816           error = TRUE;
817           _bfd_error_handler
818             (_("%s: compiled with %s and linked with modules compiled with %s"),
819              bfd_get_filename (ibfd), new_opt, old_opt);
820         }
821
822       new_flags &= ~ EF_IQ2000_ALL_FLAGS;
823       old_flags &= ~ EF_IQ2000_ALL_FLAGS;
824
825       /* Warn about any other mismatches.  */
826       if (new_flags != old_flags)
827         {
828           error = TRUE;
829
830           _bfd_error_handler
831             (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
832              bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
833         }
834     }
835
836   if (error)
837     bfd_set_error (bfd_error_bad_value);
838
839   return !error;
840 }
841
842 \f
843 static bfd_boolean
844 iq2000_elf_print_private_bfd_data (bfd *abfd, void * ptr)
845 {
846   FILE *file = (FILE *) ptr;
847   flagword flags;
848
849   BFD_ASSERT (abfd != NULL && ptr != NULL);
850
851   /* Print normal ELF private data.  */
852   _bfd_elf_print_private_bfd_data (abfd, ptr);
853
854   flags = elf_elfheader (abfd)->e_flags;
855   fprintf (file, _("private flags = 0x%lx:"), (long)flags);
856
857   switch (flags & EF_IQ2000_CPU_MASK)
858     {
859     case EF_IQ2000_CPU_IQ10:
860       fprintf (file, " -m10");
861       break;
862     case EF_IQ2000_CPU_IQ2000:
863       fprintf (file, " -m2000");
864       break;
865     default:
866       break;
867     }
868
869   fputc ('\n', file);
870   return TRUE;
871 }
872
873 static
874 bfd_boolean
875 iq2000_elf_object_p (bfd *abfd)
876 {
877   bfd_default_set_arch_mach (abfd, bfd_arch_iq2000,
878                              elf32_iq2000_machine (abfd));
879   return TRUE;
880 }
881
882 \f
883 #define ELF_ARCH                bfd_arch_iq2000
884 #define ELF_MACHINE_CODE        EM_IQ2000
885 #define ELF_MAXPAGESIZE         0x1000
886
887 #define TARGET_BIG_SYM          bfd_elf32_iq2000_vec
888 #define TARGET_BIG_NAME         "elf32-iq2000"
889
890 #define elf_info_to_howto_rel                   NULL
891 #define elf_info_to_howto                       iq2000_info_to_howto_rela
892 #define elf_backend_relocate_section            iq2000_elf_relocate_section
893 #define elf_backend_gc_mark_hook                iq2000_elf_gc_mark_hook
894 #define elf_backend_gc_sweep_hook               iq2000_elf_gc_sweep_hook
895 #define elf_backend_check_relocs                iq2000_elf_check_relocs
896 #define elf_backend_object_p                    iq2000_elf_object_p
897 #define elf_backend_rela_normal                 1
898
899 #define elf_backend_can_gc_sections             1
900
901 #define bfd_elf32_bfd_reloc_type_lookup         iq2000_reloc_type_lookup
902 #define bfd_elf32_bfd_set_private_flags         iq2000_elf_set_private_flags
903 #define bfd_elf32_bfd_copy_private_bfd_data     iq2000_elf_copy_private_bfd_data
904 #define bfd_elf32_bfd_merge_private_bfd_data    iq2000_elf_merge_private_bfd_data
905 #define bfd_elf32_bfd_print_private_bfd_data    iq2000_elf_print_private_bfd_data
906
907 #include "elf32-target.h"