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