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