Home | History | Annotate | Download | only in bfd
      1 /* ARC-specific support for 32-bit ELF
      2    Copyright (C) 1994-2016 Free Software Foundation, Inc.
      3    Contributed by Cupertino Miranda (cmiranda (at) synopsys.com).
      4 
      5    This file is part of BFD, the Binary File Descriptor library.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 #include "sysdep.h"
     23 #include "bfd.h"
     24 #include "libbfd.h"
     25 #include "elf-bfd.h"
     26 #include "elf/arc.h"
     27 #include "libiberty.h"
     28 #include "opcode/arc-func.h"
     29 #include "opcode/arc.h"
     30 #include "arc-plt.h"
     31 
     32 #ifdef DEBUG
     33 # define PR_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
     34 #else
     35 # define PR_DEBUG(fmt, args...)
     36 #endif
     37 
     38 /* #define ARC_ENABLE_DEBUG 1 */
     39 #ifndef ARC_ENABLE_DEBUG
     40 #define ARC_DEBUG(...)
     41 #else
     42 static char *
     43 name_for_global_symbol (struct elf_link_hash_entry *h)
     44 {
     45   static char *local_str = "(local)";
     46   if (h == NULL)
     47     return local_str;
     48   else
     49     return h->root.root.string;
     50 }
     51 #define ARC_DEBUG(args...) fprintf (stderr, ##args)
     52 #endif
     53 
     54 
     55 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND)		\
     56   {									\
     57     struct elf_link_hash_table *_htab = elf_hash_table (info);		\
     58     Elf_Internal_Rela _rel;						\
     59     bfd_byte * _loc;							\
     60 									\
     61     _loc = _htab->srel##SECTION->contents				\
     62       + ((_htab->srel##SECTION->reloc_count)				\
     63 	 * sizeof (Elf32_External_Rela));				\
     64     _htab->srel##SECTION->reloc_count++;				\
     65     _rel.r_addend = ADDEND;						\
     66     _rel.r_offset = (_htab->s##SECTION)->output_section->vma		\
     67       + (_htab->s##SECTION)->output_offset + OFFSET;			\
     68     BFD_ASSERT ((long) SYM_IDX != -1);					\
     69     _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE);				\
     70     bfd_elf32_swap_reloca_out (BFD, &_rel, _loc);			\
     71   }
     72 
     73 struct dynamic_sections
     74 {
     75   bfd_boolean	  initialized;
     76   asection *      sgot;
     77   asection *      srelgot;
     78   asection *      sgotplt;
     79   asection *      srelgotplt;
     80   asection *      sdyn;
     81   asection *      splt;
     82   asection *      srelplt;
     83 };
     84 
     85 enum dyn_section_types
     86 {
     87   got = 0,
     88   relgot,
     89   gotplt,
     90   dyn,
     91   plt,
     92   relplt,
     93   DYN_SECTION_TYPES_END
     94 };
     95 
     96 const char * dyn_section_names[DYN_SECTION_TYPES_END] =
     97 {
     98   ".got",
     99   ".rela.got",
    100   ".got.plt",
    101   ".dynamic",
    102   ".plt",
    103   ".rela.plt"
    104 };
    105 
    106 enum tls_type_e
    107 {
    108   GOT_UNKNOWN = 0,
    109   GOT_NORMAL,
    110   GOT_TLS_GD,
    111   GOT_TLS_IE,
    112   GOT_TLS_LE
    113 };
    114 
    115 enum tls_got_entries
    116 {
    117   TLS_GOT_NONE = 0,
    118   TLS_GOT_MOD,
    119   TLS_GOT_OFF,
    120   TLS_GOT_MOD_AND_OFF
    121 };
    122 
    123 struct got_entry
    124 {
    125   struct got_entry *next;
    126   enum tls_type_e type;
    127   bfd_vma offset;
    128   bfd_boolean processed;
    129   bfd_boolean created_dyn_relocation;
    130   enum tls_got_entries existing_entries;
    131 };
    132 
    133 static void
    134 new_got_entry_to_list (struct got_entry **list,
    135 		       enum tls_type_e type,
    136 		       bfd_vma offset,
    137 		       enum tls_got_entries existing_entries)
    138 {
    139   /* Find list end.  Avoid having multiple entries of the same
    140      type.  */
    141   struct got_entry **p = list;
    142   while (*p != NULL)
    143     {
    144       if ((*p)->type == type)
    145 	return;
    146       p = &((*p)->next);
    147     }
    148 
    149   struct got_entry *entry =
    150 		      (struct got_entry *) malloc (sizeof(struct got_entry));
    151 
    152   entry->type = type;
    153   entry->offset = offset;
    154   entry->next = NULL;
    155   entry->processed = FALSE;
    156   entry->created_dyn_relocation = FALSE;
    157   entry->existing_entries = existing_entries;
    158 
    159   /* Add the entry to the end of the list.  */
    160   *p = entry;
    161 }
    162 
    163 static bfd_boolean
    164 symbol_has_entry_of_type (struct got_entry *list, enum tls_type_e type)
    165 {
    166   while (list != NULL)
    167     {
    168       if (list->type == type)
    169 	return TRUE;
    170       list = list->next;
    171     }
    172 
    173   return FALSE;
    174 }
    175 
    176 /* The default symbols representing the init and fini dyn values.
    177    TODO: Check what is the relation of those strings with arclinux.em
    178    and DT_INIT.  */
    179 #define INIT_SYM_STRING "_init"
    180 #define FINI_SYM_STRING "_fini"
    181 
    182 char * init_str = INIT_SYM_STRING;
    183 char * fini_str = FINI_SYM_STRING;
    184 
    185 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    186       case VALUE: \
    187 	return "R_" #TYPE; \
    188 	break;
    189 
    190 static ATTRIBUTE_UNUSED const char *
    191 reloc_type_to_name (unsigned int type)
    192 {
    193   switch (type)
    194     {
    195       #include "elf/arc-reloc.def"
    196 
    197       default:
    198 	return "UNKNOWN";
    199 	break;
    200     }
    201 }
    202 #undef ARC_RELOC_HOWTO
    203 
    204 /* Try to minimize the amount of space occupied by relocation tables
    205    on the ROM (not that the ROM won't be swamped by other ELF overhead).  */
    206 
    207 #define USE_REL 1
    208 
    209 static ATTRIBUTE_UNUSED bfd_boolean
    210 is_reloc_PC_relative (reloc_howto_type *howto)
    211 {
    212   return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
    213 }
    214 
    215 static bfd_boolean
    216 is_reloc_SDA_relative (reloc_howto_type *howto)
    217 {
    218   return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
    219 }
    220 
    221 static bfd_boolean
    222 is_reloc_for_GOT (reloc_howto_type * howto)
    223 {
    224   if (strstr (howto->name, "TLS") != NULL)
    225     return FALSE;
    226   return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
    227 }
    228 
    229 static bfd_boolean
    230 is_reloc_for_PLT (reloc_howto_type * howto)
    231 {
    232   return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
    233 }
    234 
    235 static bfd_boolean
    236 is_reloc_for_TLS (reloc_howto_type *howto)
    237 {
    238   return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
    239 }
    240 
    241 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
    242 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
    243 #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
    244 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
    245 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
    246 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
    247 
    248 
    249 static bfd_reloc_status_type
    250 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    251 	       arelent *reloc_entry,
    252 	       asymbol *symbol_in,
    253 	       void *data ATTRIBUTE_UNUSED,
    254 	       asection *input_section,
    255 	       bfd *output_bfd,
    256 	       char ** error_message ATTRIBUTE_UNUSED)
    257 {
    258   if (output_bfd != NULL)
    259     {
    260       reloc_entry->address += input_section->output_offset;
    261 
    262       /* In case of relocateable link and if the reloc is against a
    263 	 section symbol, the addend needs to be adjusted according to
    264 	 where the section symbol winds up in the output section.  */
    265       if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
    266 	reloc_entry->addend += symbol_in->section->output_offset;
    267 
    268       return bfd_reloc_ok;
    269     }
    270 
    271   return bfd_reloc_continue;
    272 }
    273 
    274 
    275 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    276   TYPE = VALUE,
    277 enum howto_list
    278 {
    279 #include "elf/arc-reloc.def"
    280   HOWTO_LIST_LAST
    281 };
    282 #undef ARC_RELOC_HOWTO
    283 
    284 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    285   [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, "R_" #TYPE, FALSE, 0, 0, FALSE),
    286 
    287 static struct reloc_howto_struct elf_arc_howto_table[] =
    288 {
    289 #include "elf/arc-reloc.def"
    290 /* Example of what is generated by the preprocessor.  Currently kept as an
    291    example.
    292  HOWTO (R_ARC_NONE, // Type.
    293     0, // Rightshift.
    294     2, // Size (0 = byte, 1 = short, 2 = long).
    295     32, // Bitsize.
    296     FALSE, // PC_relative.
    297     0, // Bitpos.
    298     complain_overflow_bitfield, // Complain_on_overflow.
    299     bfd_elf_generic_reloc, // Special_function.
    300     "R_ARC_NONE", // Name.
    301     TRUE, // Partial_inplace.
    302     0, // Src_mask.
    303     0, // Dst_mask.
    304     FALSE), // PCrel_offset.
    305 */
    306 };
    307 #undef ARC_RELOC_HOWTO
    308 
    309 static void arc_elf_howto_init (void)
    310 {
    311 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    312   elf_arc_howto_table[TYPE].pc_relative = \
    313     (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
    314   elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
    315   /* Only 32 bit data relocations should be marked as ME.  */ \
    316   if (strstr (#FORMULA, " ME ") != NULL) \
    317     { \
    318       BFD_ASSERT (SIZE == 2); \
    319     }
    320 
    321 #include "elf/arc-reloc.def"
    322 
    323 }
    324 #undef ARC_RELOC_HOWTO
    325 
    326 
    327 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    328   [TYPE] = VALUE,
    329 const int howto_table_lookup[] =
    330 {
    331 #include "elf/arc-reloc.def"
    332 };
    333 #undef ARC_RELOC_HOWTO
    334 
    335 static reloc_howto_type *
    336 arc_elf_howto (unsigned int r_type)
    337 {
    338   if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
    339     arc_elf_howto_init ();
    340   return &elf_arc_howto_table[r_type];
    341 }
    342 
    343 /* Map BFD reloc types to ARC ELF reloc types.  */
    344 
    345 struct arc_reloc_map
    346 {
    347   bfd_reloc_code_real_type  bfd_reloc_val;
    348   unsigned char             elf_reloc_val;
    349 };
    350 
    351 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    352   { BFD_RELOC_##TYPE, R_##TYPE },
    353 static const struct arc_reloc_map arc_reloc_map[] =
    354 {
    355 #include "elf/arc-reloc.def"
    356 
    357   {BFD_RELOC_NONE,  R_ARC_NONE},
    358   {BFD_RELOC_8,  R_ARC_8},
    359   {BFD_RELOC_16, R_ARC_16},
    360   {BFD_RELOC_24, R_ARC_24},
    361   {BFD_RELOC_32, R_ARC_32},
    362 };
    363 #undef ARC_RELOC_HOWTO
    364 
    365 typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
    366 
    367 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    368   case TYPE: \
    369     func = (void *) RELOC_FUNCTION; \
    370     break;
    371 static replace_func
    372 get_replace_function (bfd *abfd, unsigned int r_type)
    373 {
    374   void *func = NULL;
    375 
    376   switch (r_type)
    377     {
    378       #include "elf/arc-reloc.def"
    379     }
    380 
    381   if (func == replace_bits24 && bfd_big_endian (abfd))
    382     return (replace_func) replace_bits24_be;
    383 
    384   return (replace_func) func;
    385 }
    386 #undef ARC_RELOC_HOWTO
    387 
    388 static reloc_howto_type *
    389 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    390 				 bfd_reloc_code_real_type code)
    391 {
    392   unsigned int i;
    393 
    394   for (i = ARRAY_SIZE (arc_reloc_map); i--;)
    395     {
    396       if (arc_reloc_map[i].bfd_reloc_val == code)
    397 	return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
    398     }
    399 
    400   return NULL;
    401 }
    402 
    403 /* Function to set the ELF flag bits.  */
    404 static bfd_boolean
    405 arc_elf_set_private_flags (bfd *abfd, flagword flags)
    406 {
    407   elf_elfheader (abfd)->e_flags = flags;
    408   elf_flags_init (abfd) = TRUE;
    409   return TRUE;
    410 }
    411 
    412 /* Print private flags.  */
    413 static bfd_boolean
    414 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
    415 {
    416   FILE *file = (FILE *) ptr;
    417   flagword flags;
    418 
    419   BFD_ASSERT (abfd != NULL && ptr != NULL);
    420 
    421   /* Print normal ELF private data.  */
    422   _bfd_elf_print_private_bfd_data (abfd, ptr);
    423 
    424   flags = elf_elfheader (abfd)->e_flags;
    425   fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
    426 
    427   switch (flags & EF_ARC_MACH_MSK)
    428     {
    429     case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS");    break;
    430     case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM");    break;
    431     case E_ARC_MACH_ARC600  : fprintf (file, " -mcpu=ARC600");     break;
    432     case E_ARC_MACH_ARC601  : fprintf (file, " -mcpu=ARC601");     break;
    433     case E_ARC_MACH_ARC700  : fprintf (file, " -mcpu=ARC700");     break;
    434     default:
    435       fprintf (file, "-mcpu=unknown");
    436       break;
    437     }
    438 
    439   switch (flags & EF_ARC_OSABI_MSK)
    440     {
    441     case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
    442     case E_ARC_OSABI_V2   : fprintf (file, " (ABI:v2)");     break;
    443     case E_ARC_OSABI_V3   : fprintf (file, " (ABI:v3)");     break;
    444     default:
    445       fprintf (file, "(ABI:unknown)");
    446       break;
    447     }
    448 
    449   fputc ('\n', file);
    450   return TRUE;
    451 }
    452 
    453 /* Copy backend specific data from one object module to another.  */
    454 
    455 static bfd_boolean
    456 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
    457 {
    458   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
    459       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    460     return TRUE;
    461 
    462   BFD_ASSERT (!elf_flags_init (obfd)
    463 	      || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
    464 
    465   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
    466   elf_flags_init (obfd) = TRUE;
    467 
    468   /* Copy object attributes.  */
    469   _bfd_elf_copy_obj_attributes (ibfd, obfd);
    470 
    471   return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
    472 }
    473 
    474 static reloc_howto_type *
    475 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    476 				 const char *r_name)
    477 {
    478   unsigned int i;
    479 
    480   for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
    481     if (elf_arc_howto_table[i].name != NULL
    482 	&& strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
    483       return arc_elf_howto (i);
    484 
    485   return NULL;
    486 }
    487 
    488 /* Set the howto pointer for an ARC ELF reloc.  */
    489 
    490 static void
    491 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
    492 		       arelent * cache_ptr,
    493 		       Elf_Internal_Rela * dst)
    494 {
    495   unsigned int r_type;
    496 
    497   r_type = ELF32_R_TYPE (dst->r_info);
    498   BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
    499   cache_ptr->howto = arc_elf_howto (r_type);
    500 }
    501 
    502 /* Merge backend specific data from an object file to the output
    503    object file when linking.  */
    504 
    505 static bfd_boolean
    506 arc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
    507 {
    508   unsigned short mach_ibfd;
    509   static unsigned short mach_obfd = EM_NONE;
    510   flagword out_flags;
    511   flagword in_flags;
    512   asection *sec;
    513 
    514    /* Check if we have the same endianess.  */
    515   if (! _bfd_generic_verify_endian_match (ibfd, obfd))
    516     {
    517       _bfd_error_handler (_("ERROR: Endian Match failed. Attempting to link "
    518 			    "%B with binary %s of opposite endian-ness"),
    519 			  ibfd, bfd_get_filename (obfd));
    520       return FALSE;
    521     }
    522 
    523   /* Collect ELF flags.  */
    524   in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
    525   out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
    526 
    527   if (!elf_flags_init (obfd)) /* First call, no flags set.  */
    528     {
    529       elf_flags_init (obfd) = TRUE;
    530       out_flags = in_flags;
    531     }
    532 
    533   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
    534       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    535     return TRUE;
    536 
    537   /* Check to see if the input BFD actually contains any sections.  Do
    538      not short-circuit dynamic objects; their section list may be
    539      emptied by elf_link_add_object_symbols.  */
    540   if (!(ibfd->flags & DYNAMIC))
    541     {
    542       bfd_boolean null_input_bfd = TRUE;
    543       bfd_boolean only_data_sections = TRUE;
    544 
    545       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
    546 	{
    547 	  if ((bfd_get_section_flags (ibfd, sec)
    548 	       & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
    549 	      == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
    550 	    only_data_sections = FALSE;
    551 
    552 	  null_input_bfd = FALSE;
    553 	}
    554 
    555       if (null_input_bfd || only_data_sections)
    556 	return TRUE;
    557     }
    558 
    559   /* Complain about various flag/architecture mismatches.  */
    560   mach_ibfd = elf_elfheader (ibfd)->e_machine;
    561   if (mach_obfd == EM_NONE)
    562     {
    563       mach_obfd = mach_ibfd;
    564     }
    565   else
    566     {
    567       if (mach_ibfd != mach_obfd)
    568 	{
    569 	  _bfd_error_handler (_("ERROR: Attempting to link %B "
    570 				"with a binary %s of different architecture"),
    571 			      ibfd, bfd_get_filename (obfd));
    572 	  return FALSE;
    573 	}
    574       else if (in_flags != out_flags)
    575 	{
    576 	  /* Warn if different flags.  */
    577 	  (*_bfd_error_handler)
    578 	    (_("%s: uses different e_flags (0x%lx) fields than "
    579 	       "previous modules (0x%lx)"),
    580 	     bfd_get_filename (ibfd), (long)in_flags, (long)out_flags);
    581 	  if (in_flags && out_flags)
    582 	    return FALSE;
    583 	  /* MWDT doesnt set the eflags hence make sure we choose the
    584 	     eflags set by gcc.  */
    585 	  in_flags = in_flags > out_flags ? in_flags : out_flags;
    586 	}
    587     }
    588 
    589   /* Update the flags.  */
    590   elf_elfheader (obfd)->e_flags = in_flags;
    591 
    592   if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
    593     {
    594       return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
    595     }
    596 
    597   return TRUE;
    598 }
    599 
    600 /* Set the right machine number for an ARC ELF file.  */
    601 static bfd_boolean
    602 arc_elf_object_p (bfd * abfd)
    603 {
    604   /* Make sure this is initialised, or you'll have the potential of passing
    605      garbage---or misleading values---into the call to
    606      bfd_default_set_arch_mach ().  */
    607   int		  mach = bfd_mach_arc_arc700;
    608   unsigned long   arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
    609   unsigned	  e_machine = elf_elfheader (abfd)->e_machine;
    610 
    611   if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
    612     {
    613       switch (arch)
    614 	{
    615 	  case E_ARC_MACH_ARC600:
    616 	    mach = bfd_mach_arc_arc600;
    617 	    break;
    618 	  case E_ARC_MACH_ARC601:
    619 	    mach = bfd_mach_arc_arc601;
    620 	    break;
    621 	  case E_ARC_MACH_ARC700:
    622 	    mach = bfd_mach_arc_arc700;
    623 	    break;
    624 	  case EF_ARC_CPU_ARCV2HS:
    625 	  case EF_ARC_CPU_ARCV2EM:
    626 	    mach = bfd_mach_arc_arcv2;
    627 	    break;
    628 	  default:
    629 	    mach = (e_machine == EM_ARC_COMPACT) ?
    630 	      bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
    631 	    break;
    632 	}
    633     }
    634   else
    635     {
    636       if (e_machine == EM_ARC)
    637 	{
    638 	  (*_bfd_error_handler)
    639 	    (_("Error: The ARC4 architecture is no longer supported.\n"));
    640 	  return FALSE;
    641 	}
    642       else
    643 	{
    644 	  (*_bfd_error_handler)
    645 	    (_("Warning: unset or old architecture flags. \n"
    646 	       "	       Use default machine.\n"));
    647 	}
    648     }
    649 
    650   return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
    651 }
    652 
    653 /* The final processing done just before writing out an ARC ELF object file.
    654    This gets the ARC architecture right based on the machine number.  */
    655 
    656 static void
    657 arc_elf_final_write_processing (bfd * abfd,
    658 				bfd_boolean linker ATTRIBUTE_UNUSED)
    659 {
    660   unsigned long emf;
    661 
    662   switch (bfd_get_mach (abfd))
    663     {
    664     case bfd_mach_arc_arc600:
    665       emf = EM_ARC_COMPACT;
    666       break;
    667     case bfd_mach_arc_arc601:
    668       emf = EM_ARC_COMPACT;
    669       break;
    670     case bfd_mach_arc_arc700:
    671       emf = EM_ARC_COMPACT;
    672       break;
    673     case bfd_mach_arc_arcv2:
    674       emf = EM_ARC_COMPACT2;
    675       break;
    676     default:
    677       goto DO_NOTHING;
    678     }
    679 
    680   elf_elfheader (abfd)->e_machine = emf;
    681 
    682   /* Record whatever is the current syscall ABI version.  */
    683   elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
    684 
    685 DO_NOTHING:
    686   return;
    687 }
    688 
    689 #define BFD_DEBUG_PIC(...)
    690 
    691 struct arc_relocation_data
    692 {
    693   bfd_signed_vma  reloc_offset;
    694   bfd_signed_vma  reloc_addend;
    695   bfd_signed_vma  got_offset_value;
    696 
    697   bfd_signed_vma  sym_value;
    698   asection *	  sym_section;
    699 
    700   reloc_howto_type *howto;
    701 
    702   asection *	  input_section;
    703 
    704   bfd_signed_vma  sdata_begin_symbol_vma;
    705   bfd_boolean	  sdata_begin_symbol_vma_set;
    706   bfd_signed_vma  got_symbol_vma;
    707 
    708   bfd_boolean	  should_relocate;
    709 
    710   const char *    symbol_name;
    711 };
    712 
    713 static void
    714 debug_arc_reloc (struct arc_relocation_data reloc_data)
    715 {
    716   PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
    717 	   reloc_data.howto->name,
    718 	   reloc_data.should_relocate ? "true" : "false");
    719   PR_DEBUG ("  offset = 0x%x, addend = 0x%x\n",
    720 	   (unsigned int) reloc_data.reloc_offset,
    721 	   (unsigned int) reloc_data.reloc_addend);
    722   PR_DEBUG (" Symbol:\n");
    723   PR_DEBUG ("  value = 0x%08x\n",
    724 	   (unsigned int) reloc_data.sym_value);
    725   if (reloc_data.sym_section != NULL)
    726     {
    727       PR_DEBUG (" Symbol Section:\n");
    728       PR_DEBUG (
    729 	       "  section name = %s, output_offset 0x%08x",
    730 	       reloc_data.sym_section->name,
    731 	       (unsigned int) reloc_data.sym_section->output_offset);
    732       if (reloc_data.sym_section->output_section != NULL)
    733 	{
    734 	  PR_DEBUG (
    735 		   ", output_section->vma = 0x%08x",
    736 		   ((unsigned int) reloc_data.sym_section->output_section->vma));
    737 	}
    738       PR_DEBUG ( "\n");
    739       PR_DEBUG ("  file: %s\n", reloc_data.sym_section->owner->filename);
    740     }
    741   else
    742     {
    743       PR_DEBUG ( "  symbol section is NULL\n");
    744     }
    745 
    746   PR_DEBUG ( " Input_section:\n");
    747   if (reloc_data.input_section != NULL)
    748     {
    749       PR_DEBUG (
    750 	       "  section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
    751 	       reloc_data.input_section->name,
    752 	       (unsigned int) reloc_data.input_section->output_offset,
    753 	       (unsigned int) reloc_data.input_section->output_section->vma);
    754       PR_DEBUG ( "  changed_address = 0x%08x\n",
    755 	       (unsigned int) (reloc_data.input_section->output_section->vma +
    756 	       reloc_data.input_section->output_offset +
    757 	       reloc_data.reloc_offset));
    758       PR_DEBUG ("  file: %s\n", reloc_data.input_section->owner->filename);
    759     }
    760   else
    761     {
    762       PR_DEBUG ( "	input section is NULL\n");
    763     }
    764 }
    765 
    766 static bfd_vma
    767 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
    768 {
    769   if (do_it)
    770     {
    771       insn =
    772 	((insn & 0xffff0000) >> 16) |
    773 	((insn & 0xffff) << 16);
    774     }
    775   return insn;
    776 }
    777 
    778 /* This function is called for relocations that are otherwise marked as NOT
    779    requiring overflow checks.  In here we perform non-standard checks of
    780    the relocation value.  */
    781 
    782 static inline bfd_reloc_status_type
    783 arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
    784                              bfd_signed_vma relocation,
    785 			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
    786 {
    787   switch (reloc_data.howto->type)
    788     {
    789     case R_ARC_NPS_CMEM16:
    790       if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
    791         {
    792           if (reloc_data.reloc_addend == 0)
    793             (*_bfd_error_handler)
    794               (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
    795                  "16 MSB should be 0x%04x (value is 0x%lx)"),
    796                reloc_data.input_section->owner,
    797                reloc_data.input_section,
    798                reloc_data.reloc_offset,
    799                reloc_data.symbol_name,
    800                NPS_CMEM_HIGH_VALUE,
    801                (relocation));
    802           else
    803             (*_bfd_error_handler)
    804               (_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
    805                  "16 MSB should be 0x%04x (value is 0x%lx)"),
    806                reloc_data.input_section->owner,
    807                reloc_data.input_section,
    808                reloc_data.reloc_offset,
    809                reloc_data.symbol_name,
    810                reloc_data.reloc_addend,
    811                NPS_CMEM_HIGH_VALUE,
    812                (relocation));
    813           return bfd_reloc_overflow;
    814         }
    815       break;
    816 
    817     default:
    818       break;
    819     }
    820 
    821   return bfd_reloc_ok;
    822 }
    823 
    824 #define ME(reloc) (reloc)
    825 
    826 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
    827 			    && (!bfd_big_endian (BFD)))
    828 
    829 #define S ((bfd_signed_vma) (reloc_data.sym_value			\
    830 	   + (reloc_data.sym_section->output_section != NULL ?		\
    831 	      (reloc_data.sym_section->output_offset			\
    832 	       + reloc_data.sym_section->output_section->vma) : 0)))
    833 #define L ((bfd_signed_vma) (reloc_data.sym_value			\
    834 	   + (reloc_data.sym_section->output_section != NULL ?		\
    835 	      (reloc_data.sym_section->output_offset			\
    836 	      + reloc_data.sym_section->output_section->vma) : 0)))
    837 #define A (reloc_data.reloc_addend)
    838 #define B (0)
    839 #define G (reloc_data.got_offset_value)
    840 #define GOT (reloc_data.got_symbol_vma)
    841 #define GOT_BEGIN (htab->sgot->output_section->vma)
    842 
    843 #define MES (0)
    844 	/* P: relative offset to PCL The offset should be to the
    845 	  current location aligned to 32 bits.  */
    846 #define P ((bfd_signed_vma) (						\
    847 	   (								\
    848 	    (reloc_data.input_section->output_section != NULL ?		\
    849 	     reloc_data.input_section->output_section->vma : 0)		\
    850 	    + reloc_data.input_section->output_offset			\
    851 	    + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)))	\
    852 	   & ~0x3))
    853 #define PDATA ((bfd_signed_vma) ( \
    854 	    (reloc_data.input_section->output_section->vma \
    855 	     + reloc_data.input_section->output_offset \
    856 	     + (reloc_data.reloc_offset))))
    857 #define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
    858 				    + reloc_data.sym_section->output_offset)
    859 
    860 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
    861 #define TLS_REL (bfd_signed_vma) \
    862   ((elf_hash_table (info))->tls_sec->output_section->vma)
    863 #define TLS_TBSS (8)
    864 #define TCB_SIZE (8)
    865 
    866 #define none (0)
    867 
    868 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
    869     {\
    870       asection *sym_section = reloc_data.sym_section; \
    871       asection *input_section = reloc_data.input_section; \
    872       ARC_DEBUG ("RELOC_TYPE = " TYPE "\n"); \
    873       ARC_DEBUG ("FORMULA = " FORMULA "\n"); \
    874       ARC_DEBUG ("S = 0x%x\n", S); \
    875       ARC_DEBUG ("A = 0x%x\n", A); \
    876       ARC_DEBUG ("L = 0x%x\n", L); \
    877       if (sym_section->output_section != NULL) \
    878 	{ \
    879 	  ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
    880 	     sym_section->output_section->vma + sym_section->output_offset); \
    881 	} \
    882       else \
    883 	{ \
    884 	  ARC_DEBUG ("symbol_section->vma = NULL\n"); \
    885 	} \
    886       if (input_section->output_section != NULL) \
    887 	{ \
    888 	  ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
    889 	     input_section->output_section->vma + input_section->output_offset); \
    890 	} \
    891       else \
    892 	{ \
    893 	  ARC_DEBUG ("symbol_section->vma = NULL\n"); \
    894 	} \
    895       ARC_DEBUG ("PCL = 0x%x\n", P); \
    896       ARC_DEBUG ("P = 0x%x\n", P); \
    897       ARC_DEBUG ("G = 0x%x\n", G); \
    898       ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
    899       ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
    900       ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
    901       ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
    902       ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
    903       ARC_DEBUG ("data   = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
    904     }
    905 
    906 #define PRINT_DEBUG_RELOC_INFO_AFTER \
    907     { \
    908       ARC_DEBUG ("after  = 0x%08x\n", (unsigned int) insn); \
    909     }
    910 
    911 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
    912   case R_##TYPE: \
    913     { \
    914       bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
    915       relocation = FORMULA  ; \
    916       PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \
    917       insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
    918       insn = (* get_replace_function (abfd, TYPE)) (insn, relocation); \
    919       insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
    920       PRINT_DEBUG_RELOC_INFO_AFTER \
    921     } \
    922     break;
    923 
    924 static bfd_reloc_status_type
    925 arc_do_relocation (bfd_byte * contents,
    926 		   struct arc_relocation_data reloc_data,
    927 		   struct bfd_link_info *info)
    928 {
    929   bfd_signed_vma relocation = 0;
    930   bfd_vma insn;
    931   bfd_vma orig_insn ATTRIBUTE_UNUSED;
    932   bfd * abfd = reloc_data.input_section->owner;
    933   struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
    934   bfd_reloc_status_type flag;
    935 
    936   if (reloc_data.should_relocate == FALSE)
    937     return bfd_reloc_ok;
    938 
    939   switch (reloc_data.howto->size)
    940     {
    941       case 2:
    942 	insn = arc_bfd_get_32 (abfd,
    943 			       contents + reloc_data.reloc_offset,
    944 			       reloc_data.input_section);
    945 	break;
    946       case 1:
    947 	insn = arc_bfd_get_16 (abfd,
    948 			       contents + reloc_data.reloc_offset,
    949 			       reloc_data.input_section);
    950 	break;
    951       case 0:
    952 	insn = arc_bfd_get_8 (abfd,
    953 			       contents + reloc_data.reloc_offset,
    954 			       reloc_data.input_section);
    955 	break;
    956       default:
    957 	insn = 0;
    958 	BFD_ASSERT (0);
    959 	break;
    960     }
    961 
    962   orig_insn = insn;
    963 
    964   switch (reloc_data.howto->type)
    965     {
    966 #include "elf/arc-reloc.def"
    967 
    968       default:
    969 	BFD_ASSERT (0);
    970 	break;
    971     }
    972 
    973   /* Check for relocation overflow.  */
    974   if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
    975     flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
    976                                reloc_data.howto->bitsize,
    977                                reloc_data.howto->rightshift,
    978                                bfd_arch_bits_per_address (abfd),
    979                                relocation);
    980   else
    981     flag = arc_special_overflow_checks (reloc_data, relocation, info);
    982 
    983 #undef  DEBUG_ARC_RELOC
    984 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
    985   if (flag != bfd_reloc_ok)
    986     {
    987       PR_DEBUG ( "Relocation overflows !!!!\n");
    988 
    989       DEBUG_ARC_RELOC (reloc_data);
    990 
    991       PR_DEBUG (
    992                 "Relocation value = signed -> %d, unsigned -> %u"
    993                 ", hex -> (0x%08x)\n",
    994                 (int) relocation,
    995                 (unsigned int) relocation,
    996                 (unsigned int) relocation);
    997       return flag;
    998     }
    999 #undef  DEBUG_ARC_RELOC
   1000 #define DEBUG_ARC_RELOC(A)
   1001 
   1002   /* Write updated instruction back to memory.  */
   1003   switch (reloc_data.howto->size)
   1004     {
   1005       case 2:
   1006 	arc_bfd_put_32 (abfd, insn,
   1007 		       contents + reloc_data.reloc_offset,
   1008 		       reloc_data.input_section);
   1009 	break;
   1010       case 1:
   1011 	arc_bfd_put_16 (abfd, insn,
   1012 		       contents + reloc_data.reloc_offset,
   1013 		       reloc_data.input_section);
   1014 	break;
   1015       case 0:
   1016 	arc_bfd_put_8 (abfd, insn,
   1017 		       contents + reloc_data.reloc_offset,
   1018 		       reloc_data.input_section);
   1019 	break;
   1020       default:
   1021 	ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
   1022 	BFD_ASSERT (0);
   1023 	break;
   1024     }
   1025 
   1026   return bfd_reloc_ok;
   1027 }
   1028 #undef S
   1029 #undef A
   1030 #undef B
   1031 #undef G
   1032 #undef GOT
   1033 #undef L
   1034 #undef MES
   1035 #undef P
   1036 #undef SECTSTAR
   1037 #undef SECTSTART
   1038 #undef _SDA_BASE_
   1039 #undef none
   1040 
   1041 #undef ARC_RELOC_HOWTO
   1042 
   1043 static struct got_entry **
   1044 arc_get_local_got_ents (bfd * abfd)
   1045 {
   1046   static struct got_entry **local_got_ents = NULL;
   1047 
   1048   if (local_got_ents == NULL)
   1049     {
   1050       size_t	   size;
   1051       Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
   1052 
   1053       size = symtab_hdr->sh_info * sizeof (bfd_vma);
   1054       local_got_ents = (struct got_entry **)
   1055 	bfd_alloc (abfd, sizeof(struct got_entry *) * size);
   1056       if (local_got_ents == NULL)
   1057 	return FALSE;
   1058 
   1059       memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
   1060       elf_local_got_ents (abfd) = local_got_ents;
   1061     }
   1062 
   1063   return local_got_ents;
   1064 }
   1065 
   1066 /* Relocate an arc ELF section.
   1067    Function : elf_arc_relocate_section
   1068    Brief    : Relocate an arc section, by handling all the relocations
   1069 	     appearing in that section.
   1070    Args     : output_bfd    : The bfd being written to.
   1071 	      info	    : Link information.
   1072 	      input_bfd     : The input bfd.
   1073 	      input_section : The section being relocated.
   1074 	      contents	    : contents of the section being relocated.
   1075 	      relocs	    : List of relocations in the section.
   1076 	      local_syms    : is a pointer to the swapped in local symbols.
   1077 	      local_section : is an array giving the section in the input file
   1078 			      corresponding to the st_shndx field of each
   1079 			      local symbol.  */
   1080 static bfd_boolean
   1081 elf_arc_relocate_section (bfd *		   output_bfd,
   1082 			  struct bfd_link_info *  info,
   1083 			  bfd *		   input_bfd,
   1084 			  asection *	      input_section,
   1085 			  bfd_byte *	      contents,
   1086 			  Elf_Internal_Rela *     relocs,
   1087 			  Elf_Internal_Sym *      local_syms,
   1088 			  asection **	     local_sections)
   1089 {
   1090   Elf_Internal_Shdr *	   symtab_hdr;
   1091   struct elf_link_hash_entry ** sym_hashes;
   1092   struct got_entry **	   local_got_ents;
   1093   Elf_Internal_Rela *	   rel;
   1094   Elf_Internal_Rela *	   wrel;
   1095   Elf_Internal_Rela *	   relend;
   1096   struct elf_link_hash_table *htab = elf_hash_table (info);
   1097 
   1098   symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
   1099   sym_hashes = elf_sym_hashes (input_bfd);
   1100 
   1101   rel = wrel = relocs;
   1102   relend = relocs + input_section->reloc_count;
   1103   for (; rel < relend; wrel++, rel++)
   1104     {
   1105       enum elf_arc_reloc_type       r_type;
   1106       reloc_howto_type *	    howto;
   1107       unsigned long		 r_symndx;
   1108       struct elf_link_hash_entry *  h;
   1109       Elf_Internal_Sym *	    sym;
   1110       asection *		    sec;
   1111       struct elf_link_hash_entry *h2;
   1112 
   1113       struct arc_relocation_data reloc_data =
   1114       {
   1115 	.reloc_offset = 0,
   1116 	.reloc_addend = 0,
   1117 	.got_offset_value = 0,
   1118 	.sym_value = 0,
   1119 	.sym_section = NULL,
   1120 	.howto = NULL,
   1121 	.input_section = NULL,
   1122 	.sdata_begin_symbol_vma = 0,
   1123 	.sdata_begin_symbol_vma_set = FALSE,
   1124 	.got_symbol_vma = 0,
   1125 	.should_relocate = FALSE
   1126       };
   1127 
   1128       r_type = ELF32_R_TYPE (rel->r_info);
   1129 
   1130       if (r_type >= (int) R_ARC_max)
   1131 	{
   1132 	  bfd_set_error (bfd_error_bad_value);
   1133 	  return FALSE;
   1134 	}
   1135       howto = arc_elf_howto (r_type);
   1136 
   1137       r_symndx = ELF32_R_SYM (rel->r_info);
   1138 
   1139       /* If we are generating another .o file and the symbol in not
   1140 	 local, skip this relocation.  */
   1141       if (bfd_link_relocatable (info))
   1142 	{
   1143 	  /* This is a relocateable link.  We don't have to change
   1144 	     anything, unless the reloc is against a section symbol,
   1145 	     in which case we have to adjust according to where the
   1146 	     section symbol winds up in the output section.  */
   1147 
   1148 	  /* Checks if this is a local symbol and thus the reloc
   1149 	     might (will??) be against a section symbol.  */
   1150 	  if (r_symndx < symtab_hdr->sh_info)
   1151 	    {
   1152 	      sym = local_syms + r_symndx;
   1153 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
   1154 		{
   1155 		  sec = local_sections[r_symndx];
   1156 
   1157 		  /* for RELA relocs.Just adjust the addend
   1158 		     value in the relocation entry.  */
   1159 		  rel->r_addend += sec->output_offset + sym->st_value;
   1160 
   1161 		  BFD_DEBUG_PIC (
   1162 		    PR_DEBUG ("local symbols reloc "
   1163 			      "(section=%d %s) seen in %s\n",
   1164 			      r_symndx,
   1165 			      local_sections[r_symndx]->name,
   1166 			      __PRETTY_FUNCTION__)
   1167 		  );
   1168 		}
   1169 	    }
   1170 	}
   1171 
   1172       h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
   1173 				 FALSE, FALSE, TRUE);
   1174 
   1175       if (reloc_data.sdata_begin_symbol_vma_set == FALSE
   1176 	    && h2 != NULL && h2->root.type != bfd_link_hash_undefined
   1177 	    && h2->root.u.def.section->output_section != NULL)
   1178 	/* TODO: Verify this condition.  */
   1179 	{
   1180 	  reloc_data.sdata_begin_symbol_vma =
   1181 	    (h2->root.u.def.value +
   1182 	     h2->root.u.def.section->output_section->vma);
   1183 	  reloc_data.sdata_begin_symbol_vma_set = TRUE;
   1184 	}
   1185 
   1186       reloc_data.input_section = input_section;
   1187       reloc_data.howto = howto;
   1188       reloc_data.reloc_offset = rel->r_offset;
   1189       reloc_data.reloc_addend = rel->r_addend;
   1190 
   1191       /* This is a final link.  */
   1192       h = NULL;
   1193       sym = NULL;
   1194       sec = NULL;
   1195 
   1196       if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
   1197 	{
   1198 	  sym = local_syms + r_symndx;
   1199 	  sec = local_sections[r_symndx];
   1200 	}
   1201       else
   1202 	{
   1203 	  /* TODO: This code is repeated from below.  We should
   1204 	     clean it and remove duplications.
   1205 	     Sec is used check for discarded sections.
   1206 	     Need to redesign code below.  */
   1207 
   1208 	  /* Get the symbol's entry in the symtab.  */
   1209 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1210 
   1211 	  while (h->root.type == bfd_link_hash_indirect
   1212 		 || h->root.type == bfd_link_hash_warning)
   1213 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1214 
   1215 	  /* If we have encountered a definition for this symbol.  */
   1216 	  if (h->root.type == bfd_link_hash_defined
   1217 	      || h->root.type == bfd_link_hash_defweak)
   1218 	    {
   1219 	      reloc_data.sym_value = h->root.u.def.value;
   1220 	      sec = h->root.u.def.section;
   1221 	    }
   1222 	}
   1223 
   1224       /* Clean relocs for symbols in discarded sections.  */
   1225       if (sec != NULL && discarded_section (sec))
   1226 	{
   1227 	  _bfd_clear_contents (howto, input_bfd, input_section,
   1228 			       contents + rel->r_offset);
   1229 	  rel->r_offset = rel->r_offset;
   1230 	  rel->r_info = 0;
   1231 	  rel->r_addend = 0;
   1232 
   1233 	  /* For ld -r, remove relocations in debug sections against
   1234 	     sections defined in discarded sections.  Not done for
   1235 	     eh_frame editing code expects to be present.  */
   1236 	   if (bfd_link_relocatable (info)
   1237 	       && (input_section->flags & SEC_DEBUGGING))
   1238 	     wrel--;
   1239 
   1240 	  continue;
   1241 	}
   1242 
   1243       if (bfd_link_relocatable (info))
   1244 	{
   1245 	  if (wrel != rel)
   1246 	    *wrel = *rel;
   1247 	  continue;
   1248 	}
   1249 
   1250       if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
   1251 	{
   1252 	  struct got_entry *entry;
   1253 
   1254 	  local_got_ents = arc_get_local_got_ents (output_bfd);
   1255 	  entry = local_got_ents[r_symndx];
   1256 
   1257 	  reloc_data.sym_value = sym->st_value;
   1258 	  reloc_data.sym_section = sec;
   1259 	  reloc_data.symbol_name =
   1260 	    bfd_elf_string_from_elf_section (input_bfd,
   1261 					     symtab_hdr->sh_link,
   1262 					     sym->st_name);
   1263 
   1264 	  /* Mergeable section handling.  */
   1265 	  if ((sec->flags & SEC_MERGE)
   1266 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
   1267 	    {
   1268 	      asection *msec;
   1269 	      msec = sec;
   1270 	      rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
   1271 						      &msec, rel->r_addend);
   1272 	      rel->r_addend -= (sec->output_section->vma
   1273 				+ sec->output_offset
   1274 				+ sym->st_value);
   1275 	      rel->r_addend += msec->output_section->vma + msec->output_offset;
   1276 
   1277 	      reloc_data.reloc_addend = rel->r_addend;
   1278 	    }
   1279 
   1280 	  if ((is_reloc_for_GOT (howto)
   1281 	       || is_reloc_for_TLS (howto)) && entry != NULL)
   1282 	    {
   1283 	      if (is_reloc_for_TLS (howto))
   1284 		while (entry->type == GOT_NORMAL && entry->next != NULL)
   1285 		  entry = entry->next;
   1286 
   1287 	      if (is_reloc_for_GOT (howto))
   1288 		while (entry->type != GOT_NORMAL && entry->next != NULL)
   1289 		  entry = entry->next;
   1290 
   1291 	      if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
   1292 		{
   1293 		  bfd_vma sym_vma = sym->st_value
   1294 				    + sec->output_section->vma
   1295 				    + sec->output_offset;
   1296 
   1297 		  /* Create dynamic relocation for local sym.  */
   1298 		  ADD_RELA (output_bfd, got, entry->offset, 0,
   1299 			    R_ARC_TLS_DTPMOD, 0);
   1300 		  ADD_RELA (output_bfd, got, entry->offset+4, 0,
   1301 			    R_ARC_TLS_DTPOFF, 0);
   1302 
   1303 		  bfd_vma sec_vma = sec->output_section->vma
   1304 				    + sec->output_offset;
   1305 		  bfd_put_32 (output_bfd, sym_vma - sec_vma,
   1306 			      htab->sgot->contents + entry->offset + 4);
   1307 
   1308 		  ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
   1309 			 "= 0x%x @ 0x%x, for symbol %s\n",
   1310 			 sym_vma - sec_vma,
   1311 			 htab->sgot->contents + entry->offset + 4,
   1312 			 "(local)");
   1313 
   1314 		  entry->processed = TRUE;
   1315 		}
   1316 	      if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
   1317 		{
   1318 		  bfd_vma sym_vma = sym->st_value
   1319 				    + sec->output_section->vma
   1320 				    + sec->output_offset;
   1321 		  bfd_vma sec_vma = htab->tls_sec->output_section->vma;
   1322 		  bfd_put_32 (output_bfd, sym_vma - sec_vma,
   1323 			      htab->sgot->contents + entry->offset);
   1324 		  /* TODO: Check if this type of relocs is the cause
   1325 		     for all the ARC_NONE dynamic relocs.  */
   1326 
   1327 		  ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
   1328 			 "0x%x @ 0x%x, for symbol %s\n",
   1329 			 sym_vma - sec_vma,
   1330 			 htab->sgot->contents + entry->offset,
   1331 			 "(local)");
   1332 
   1333 		  entry->processed = TRUE;
   1334 		}
   1335 	      if (entry->type == GOT_NORMAL && entry->processed == FALSE)
   1336 		{
   1337 		  bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
   1338 				    + reloc_data.sym_section->output_offset;
   1339 
   1340 		  bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
   1341 			      htab->sgot->contents + entry->offset);
   1342 
   1343 		  ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
   1344 			 "sym %s in got offset 0x%x\n",
   1345 			 reloc_data.sym_value + sec_vma,
   1346 			 htab->sgot->output_section->vma
   1347 			 + htab->sgot->output_offset + entry->offset,
   1348 			 "(local)",
   1349 			 entry->offset);
   1350 		  entry->processed = TRUE;
   1351 		}
   1352 
   1353 	      reloc_data.got_offset_value = entry->offset;
   1354 	      ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
   1355 		     "vma = 0x%x for symbol %s\n",
   1356 		     entry->type, entry->offset,
   1357 		     htab->sgot->output_section->vma
   1358 		     + htab->sgot->output_offset + entry->offset,
   1359 		     "(local)");
   1360 	    }
   1361 
   1362 	  BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
   1363 	  if (htab->sgot != NULL)
   1364 	    reloc_data.got_symbol_vma = htab->sgot->output_section->vma
   1365 					+ htab->sgot->output_offset;
   1366 
   1367 	  reloc_data.should_relocate = TRUE;
   1368 	}
   1369       else /* Global symbol.  */
   1370 	{
   1371 	  /* Get the symbol's entry in the symtab.  */
   1372 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1373 
   1374 	  while (h->root.type == bfd_link_hash_indirect
   1375 		 || h->root.type == bfd_link_hash_warning)
   1376 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1377 
   1378 	  /* TODO: Need to validate what was the intention.  */
   1379 	  /* BFD_ASSERT ((h->dynindx == -1) || (h->forced_local != 0)); */
   1380 	  reloc_data.symbol_name = h->root.root.string;
   1381 
   1382 	  /* If we have encountered a definition for this symbol.  */
   1383 	  if (h->root.type == bfd_link_hash_defined
   1384 	      || h->root.type == bfd_link_hash_defweak)
   1385 	    {
   1386 	      reloc_data.sym_value = h->root.u.def.value;
   1387 	      reloc_data.sym_section = h->root.u.def.section;
   1388 
   1389 	      reloc_data.should_relocate = TRUE;
   1390 
   1391 	      if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
   1392 		{
   1393 		  /* TODO: Change it to use arc_do_relocation with
   1394 		    ARC_32 reloc.  Try to use ADD_RELA macro.  */
   1395 		  bfd_vma relocation =
   1396 		    reloc_data.sym_value + reloc_data.reloc_addend
   1397 		    + (reloc_data.sym_section->output_section != NULL ?
   1398 			(reloc_data.sym_section->output_offset
   1399 			 + reloc_data.sym_section->output_section->vma)
   1400 		      : 0);
   1401 
   1402 		  BFD_ASSERT (h->got.glist);
   1403 		  bfd_vma got_offset = h->got.glist->offset;
   1404 		  bfd_put_32 (output_bfd, relocation,
   1405 			      htab->sgot->contents + got_offset);
   1406 		}
   1407 	      if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
   1408 		{
   1409 		  /* TODO: This is repeated up here.  */
   1410 		  reloc_data.sym_value = h->plt.offset;
   1411 		  reloc_data.sym_section = htab->splt;
   1412 		}
   1413 	    }
   1414 	  else if (h->root.type == bfd_link_hash_undefweak)
   1415 	    {
   1416 	      /* Is weak symbol and has no definition.  */
   1417 	      if (is_reloc_for_GOT (howto))
   1418 		{
   1419 		  reloc_data.sym_value = h->root.u.def.value;
   1420 		  reloc_data.sym_section = htab->sgot;
   1421 		  reloc_data.should_relocate = TRUE;
   1422 		}
   1423 	      else if (is_reloc_for_PLT (howto)
   1424 		       && h->plt.offset != (bfd_vma) -1)
   1425 		{
   1426 		  /* TODO: This is repeated up here.  */
   1427 		  reloc_data.sym_value = h->plt.offset;
   1428 		  reloc_data.sym_section = htab->splt;
   1429 		  reloc_data.should_relocate = TRUE;
   1430 		}
   1431 	      else
   1432 		continue;
   1433 	    }
   1434 	  else
   1435 	    {
   1436 	      if (is_reloc_for_GOT (howto))
   1437 		{
   1438 		  reloc_data.sym_value = h->root.u.def.value;
   1439 		  reloc_data.sym_section = htab->sgot;
   1440 
   1441 		  reloc_data.should_relocate = TRUE;
   1442 		}
   1443 	      else if (is_reloc_for_PLT (howto))
   1444 		{
   1445 		  /* Fail if it is linking for PIE and the symbol is
   1446 		     undefined.  */
   1447 		  if (bfd_link_executable (info))
   1448 		    (*info->callbacks->undefined_symbol)
   1449 		      (info, h->root.root.string, input_bfd, input_section,
   1450 		       rel->r_offset, TRUE);
   1451 		  reloc_data.sym_value = h->plt.offset;
   1452 		  reloc_data.sym_section = htab->splt;
   1453 
   1454 		  reloc_data.should_relocate = TRUE;
   1455 		}
   1456 	      else if (!bfd_link_pic (info))
   1457 		(*info->callbacks->undefined_symbol)
   1458 		  (info, h->root.root.string, input_bfd, input_section,
   1459 		   rel->r_offset, TRUE);
   1460 	    }
   1461 
   1462 	  if (h->got.glist != NULL)
   1463 	    {
   1464 	      struct got_entry *entry = h->got.glist;
   1465 
   1466 	      if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
   1467 		{
   1468 		  if (! elf_hash_table (info)->dynamic_sections_created
   1469 		      || (bfd_link_pic (info)
   1470 			  && SYMBOL_REFERENCES_LOCAL (info, h)))
   1471 		    {
   1472 		      reloc_data.sym_value = h->root.u.def.value;
   1473 		      reloc_data.sym_section = h->root.u.def.section;
   1474 
   1475 		      if (is_reloc_for_TLS (howto))
   1476 			while (entry->type == GOT_NORMAL && entry->next != NULL)
   1477 			  entry = entry->next;
   1478 
   1479 		      if (entry->processed == FALSE
   1480 			  && (entry->type == GOT_TLS_GD
   1481 			      || entry->type == GOT_TLS_IE))
   1482 			{
   1483 			  bfd_vma sym_value = h->root.u.def.value
   1484 			    + h->root.u.def.section->output_section->vma
   1485 			    + h->root.u.def.section->output_offset;
   1486 
   1487 			  bfd_vma sec_vma =
   1488 			    elf_hash_table (info)->tls_sec->output_section->vma;
   1489 
   1490 			  bfd_put_32 (output_bfd,
   1491 				      sym_value - sec_vma,
   1492 				      htab->sgot->contents + entry->offset
   1493 				      + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0));
   1494 
   1495 			  ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
   1496 				     "@ 0x%x, for symbol %s\n",
   1497 				     (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
   1498 				      "GOT_TLS_IE"),
   1499 				     sym_value - sec_vma,
   1500 				     htab->sgot->contents + entry->offset
   1501 				     + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0),
   1502 				     h->root.root.string);
   1503 
   1504 			  entry->processed = TRUE;
   1505 			}
   1506 
   1507 		      if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
   1508 			{
   1509 			  bfd_vma sec_vma = htab->tls_sec->output_section->vma;
   1510 			  bfd_put_32 (output_bfd,
   1511 				      reloc_data.sym_value - sec_vma,
   1512 				      htab->sgot->contents + entry->offset);
   1513 			}
   1514 
   1515 		      if (entry->type == GOT_NORMAL && entry->processed == FALSE)
   1516 			{
   1517 			  bfd_vma sec_vma =
   1518 			    reloc_data.sym_section->output_section->vma
   1519 			    + reloc_data.sym_section->output_offset;
   1520 
   1521 			  if (h->root.type != bfd_link_hash_undefweak)
   1522 			    {
   1523 			      bfd_put_32 (output_bfd,
   1524 					  reloc_data.sym_value + sec_vma,
   1525 					  htab->sgot->contents + entry->offset);
   1526 
   1527 			      ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
   1528 					 "@ 0x%08x for sym %s in got offset 0x%x\n",
   1529 					 reloc_data.sym_value + sec_vma,
   1530 					 htab->sgot->output_section->vma
   1531 					 + htab->sgot->output_offset + entry->offset,
   1532 					 h->root.root.string,
   1533 					 entry->offset);
   1534 			    }
   1535 			  else
   1536 			    {
   1537 			      ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
   1538 					 "@ 0x%08x for sym %s in got offset 0x%x "
   1539 					 "(is undefweak)\n",
   1540 					 htab->sgot->output_section->vma
   1541 					 + htab->sgot->output_offset + entry->offset,
   1542 					 h->root.root.string,
   1543 					 entry->offset);
   1544 			    }
   1545 
   1546 			  entry->processed = TRUE;
   1547 			}
   1548 		    }
   1549 		}
   1550 
   1551 	      reloc_data.got_offset_value = entry->offset;
   1552 
   1553 	      ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
   1554 			 "vma = 0x%x for symbol %s\n",
   1555 			 entry->type, entry->offset,
   1556 			 htab->sgot->output_section->vma
   1557 			 + htab->sgot->output_offset + entry->offset,
   1558 			 h->root.root.string);
   1559 	    }
   1560 
   1561 	  BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
   1562 	  if (htab->sgot != NULL)
   1563 	    reloc_data.got_symbol_vma = htab->sgot->output_section->vma
   1564 					+ htab->sgot->output_offset;
   1565 	}
   1566 
   1567       switch (r_type)
   1568 	{
   1569 	  case R_ARC_32:
   1570 	  case R_ARC_32_ME:
   1571 	  case R_ARC_PC32:
   1572 	  case R_ARC_32_PCREL:
   1573 	    if ((bfd_link_pic (info) || bfd_link_pie (info))
   1574 		&& ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
   1575 		    || (h != NULL
   1576 			&& h->dynindx != -1
   1577 			&& (!info->symbolic || !h->def_regular))))
   1578 	      {
   1579 		Elf_Internal_Rela outrel;
   1580 		bfd_byte *loc;
   1581 		bfd_boolean skip = FALSE;
   1582 		bfd_boolean relocate = FALSE;
   1583 		asection *sreloc = _bfd_elf_get_dynamic_reloc_section
   1584 				 (input_bfd, input_section,
   1585 				  /*RELA*/ TRUE);
   1586 
   1587 		BFD_ASSERT (sreloc != NULL);
   1588 
   1589 		outrel.r_offset = _bfd_elf_section_offset (output_bfd,
   1590 							   info,
   1591 							   input_section,
   1592 							   rel->r_offset);
   1593 		if (outrel.r_offset == (bfd_vma) -1)
   1594 		  skip = TRUE;
   1595 
   1596 		outrel.r_addend = rel->r_addend;
   1597 		outrel.r_offset += (input_section->output_section->vma
   1598 				    + input_section->output_offset);
   1599 
   1600 #define IS_ARC_PCREL_TYPE(TYPE) \
   1601   (   (TYPE == R_ARC_PC32) \
   1602    || (TYPE == R_ARC_32_PCREL))
   1603 		if (skip)
   1604 		  {
   1605 		    memset (&outrel, 0, sizeof outrel);
   1606 		    relocate = FALSE;
   1607 		  }
   1608 		else if (h != NULL
   1609 			 && h->dynindx != -1
   1610 			 && ((IS_ARC_PCREL_TYPE (r_type))
   1611 			 || !(bfd_link_executable (info)
   1612 			      || SYMBOLIC_BIND (info, h))
   1613 			 || ! h->def_regular))
   1614 		  {
   1615 		    BFD_ASSERT (h != NULL);
   1616 		    if ((input_section->flags & SEC_ALLOC) != 0)
   1617 		      relocate = FALSE;
   1618 		    else
   1619 		      relocate = TRUE;
   1620 
   1621 		    BFD_ASSERT (h->dynindx != -1);
   1622 		    outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
   1623 		  }
   1624 		else
   1625 		  {
   1626 		    /* Handle local symbols, they either do not have a
   1627 		       global hash table entry (h == NULL), or are
   1628 		       forced local due to a version script
   1629 		       (h->forced_local), or the third condition is
   1630 		       legacy, it appears to say something like, for
   1631 		       links where we are pre-binding the symbols, or
   1632 		       there's not an entry for this symbol in the
   1633 		       dynamic symbol table, and it's a regular symbol
   1634 		       not defined in a shared object, then treat the
   1635 		       symbol as local, resolve it now.  */
   1636 		    relocate = TRUE;
   1637 		    /* outrel.r_addend = 0; */
   1638 		    outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
   1639 		  }
   1640 
   1641 		BFD_ASSERT (sreloc->contents != 0);
   1642 
   1643 		loc = sreloc->contents;
   1644 		loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
   1645 		sreloc->reloc_count += 1;
   1646 
   1647 		bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
   1648 
   1649 		if (relocate == FALSE)
   1650 		  continue;
   1651 	      }
   1652 	    break;
   1653 	  default:
   1654 	    break;
   1655 	}
   1656 
   1657       if (is_reloc_SDA_relative (howto)
   1658 	  && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
   1659 	{
   1660 	  (*_bfd_error_handler)
   1661 	      ("Error: Linker symbol __SDATA_BEGIN__ not found");
   1662 	  bfd_set_error (bfd_error_bad_value);
   1663 	  return FALSE;
   1664 	}
   1665 
   1666       DEBUG_ARC_RELOC (reloc_data);
   1667 
   1668       /* Make sure we have with a dynamic linker.  In case of GOT and PLT
   1669          the sym_section should point to .got or .plt respectively.  */
   1670       if ((is_reloc_for_GOT (howto) || is_reloc_for_PLT (howto))
   1671 	  && reloc_data.sym_section == NULL)
   1672 	{
   1673 	  (*_bfd_error_handler)
   1674 	    (_("GOT and PLT relocations cannot be fixed with a non dynamic linker."));
   1675 	  bfd_set_error (bfd_error_bad_value);
   1676 	  return FALSE;
   1677 	}
   1678 
   1679       if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
   1680 	return FALSE;
   1681     }
   1682 
   1683   return TRUE;
   1684 }
   1685 
   1686 static struct dynamic_sections
   1687 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
   1688 {
   1689   struct elf_link_hash_table *htab;
   1690   bfd	 *dynobj;
   1691   struct dynamic_sections ds =
   1692     {
   1693       .initialized = FALSE,
   1694       .sgot = NULL,
   1695       .srelgot = NULL,
   1696       .sgotplt = NULL,
   1697       .srelgotplt = NULL,
   1698       .sdyn = NULL,
   1699       .splt = NULL,
   1700       .srelplt = NULL
   1701     };
   1702 
   1703   htab = elf_hash_table (info);
   1704   BFD_ASSERT (htab);
   1705 
   1706   /* Create dynamic sections for relocatable executables so that we
   1707      can copy relocations.  */
   1708   if (! htab->dynamic_sections_created && bfd_link_pic (info))
   1709     {
   1710       if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
   1711 	BFD_ASSERT (0);
   1712     }
   1713 
   1714   dynobj = (elf_hash_table (info))->dynobj;
   1715 
   1716   if (dynobj)
   1717     {
   1718       ds.sgot = htab->sgot;
   1719       ds.srelgot = htab->srelgot;
   1720 
   1721       ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
   1722       ds.srelgotplt = ds.srelplt;
   1723 
   1724       ds.splt = bfd_get_section_by_name (dynobj, ".plt");
   1725       ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
   1726     }
   1727 
   1728   if (htab->dynamic_sections_created)
   1729     {
   1730       ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
   1731     }
   1732 
   1733   ds.initialized = TRUE;
   1734 
   1735   return ds;
   1736 }
   1737 
   1738 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H)	\
   1739   htab->s##SECNAME->size;						\
   1740   {									\
   1741     if (COND_FOR_RELOC)							\
   1742       {									\
   1743 	htab->srel##SECNAME->size += sizeof (Elf32_External_Rela);	\
   1744 	  ARC_DEBUG ("arc_info: Added reloc space in "			\
   1745 		     #SECNAME " section at " __FILE__			\
   1746 		     ":%d for symbol\n",				\
   1747 		     __LINE__, name_for_global_symbol (H));		\
   1748       }									\
   1749     if (H)								\
   1750       if (h->dynindx == -1 && !h->forced_local)				\
   1751 	if (! bfd_elf_link_record_dynamic_symbol (info, H))		\
   1752 	  return FALSE;							\
   1753      htab->s##SECNAME->size += 4;			\
   1754    }
   1755 
   1756 static bfd_boolean
   1757 elf_arc_check_relocs (bfd *		         abfd,
   1758 		      struct bfd_link_info *     info,
   1759 		      asection *		 sec,
   1760 		      const Elf_Internal_Rela *  relocs)
   1761 {
   1762   Elf_Internal_Shdr *		symtab_hdr;
   1763   struct elf_link_hash_entry **	sym_hashes;
   1764   struct got_entry **		local_got_ents;
   1765   const Elf_Internal_Rela *	rel;
   1766   const Elf_Internal_Rela *	rel_end;
   1767   bfd *				dynobj;
   1768   asection *			sreloc = NULL;
   1769   struct elf_link_hash_table *  htab = elf_hash_table (info);
   1770 
   1771   if (bfd_link_relocatable (info))
   1772     return TRUE;
   1773 
   1774   dynobj = (elf_hash_table (info))->dynobj;
   1775   symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
   1776   sym_hashes = elf_sym_hashes (abfd);
   1777   local_got_ents = arc_get_local_got_ents (abfd);
   1778 
   1779   rel_end = relocs + sec->reloc_count;
   1780   for (rel = relocs; rel < rel_end; rel++)
   1781     {
   1782       enum elf_arc_reloc_type r_type;
   1783       reloc_howto_type *howto;
   1784       unsigned long   r_symndx;
   1785       struct elf_link_hash_entry *h;
   1786 
   1787       r_type = ELF32_R_TYPE (rel->r_info);
   1788 
   1789       if (r_type >= (int) R_ARC_max)
   1790 	{
   1791 	  bfd_set_error (bfd_error_bad_value);
   1792 	  return FALSE;
   1793 	}
   1794       howto = arc_elf_howto (r_type);
   1795 
   1796       if (dynobj == NULL
   1797 	  && (is_reloc_for_GOT (howto) == TRUE
   1798 	      || is_reloc_for_TLS (howto) == TRUE))
   1799 	{
   1800 	  dynobj = elf_hash_table (info)->dynobj = abfd;
   1801 	  if (! _bfd_elf_create_got_section (abfd, info))
   1802 	    return FALSE;
   1803 	}
   1804 
   1805       /* Load symbol information.  */
   1806       r_symndx = ELF32_R_SYM (rel->r_info);
   1807       if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol.  */
   1808 	h = NULL;
   1809       else /* Global one.  */
   1810 	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1811 
   1812       switch (r_type)
   1813 	{
   1814 	  case R_ARC_32:
   1815 	  case R_ARC_32_ME:
   1816 	    /* During shared library creation, these relocs should not
   1817 	       appear in a shared library (as memory will be read only
   1818 	       and the dynamic linker can not resolve these.  However
   1819 	       the error should not occur for e.g. debugging or
   1820 	       non-readonly sections.  */
   1821 	    if ((bfd_link_dll (info) && !bfd_link_pie (info))
   1822 		&& (sec->flags & SEC_ALLOC) != 0
   1823 		&& (sec->flags & SEC_READONLY) != 0
   1824 		&& ((sec->flags & SEC_CODE) != 0
   1825 		    || (sec->flags & SEC_DEBUGGING) != 0))
   1826 	      {
   1827 		const char *name;
   1828 		if (h)
   1829 		  name = h->root.root.string;
   1830 		else
   1831 		  /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
   1832 		  name = "UNKNOWN";
   1833 		(*_bfd_error_handler)
   1834 		  (_("\
   1835 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
   1836 		    abfd,
   1837 		    arc_elf_howto (r_type)->name,
   1838 		    name);
   1839 		bfd_set_error (bfd_error_bad_value);
   1840 		return FALSE;
   1841 	      }
   1842 
   1843 	    /* In some cases we are not setting the 'non_got_ref'
   1844 	       flag, even though the relocations don't require a GOT
   1845 	       access.  We should extend the testing in this area to
   1846 	       ensure that no significant cases are being missed.  */
   1847 	    if (h)
   1848 	      h->non_got_ref = 1;
   1849 	    /* FALLTHROUGH */
   1850 	  case R_ARC_PC32:
   1851 	  case R_ARC_32_PCREL:
   1852 	    if ((bfd_link_pic (info) || bfd_link_pie (info))
   1853 		&& ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
   1854 		    || (h != NULL
   1855 			&& h->dynindx != -1
   1856 			&& (!info->symbolic || !h->def_regular))))
   1857 	      {
   1858 		if (sreloc == NULL)
   1859 		  {
   1860 		    sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
   1861 								  2, abfd,
   1862 								  /*rela*/
   1863 								  TRUE);
   1864 
   1865 		    if (sreloc == NULL)
   1866 		      return FALSE;
   1867 		  }
   1868 		sreloc->size += sizeof (Elf32_External_Rela);
   1869 
   1870 	      }
   1871 	  default:
   1872 	    break;
   1873 	}
   1874 
   1875       if (is_reloc_for_PLT (howto) == TRUE)
   1876 	{
   1877 	  if (h == NULL)
   1878 	    continue;
   1879 	  else
   1880 	    h->needs_plt = 1;
   1881 	}
   1882 
   1883       if (is_reloc_for_GOT (howto) == TRUE)
   1884 	{
   1885 	  if (h == NULL)
   1886 	    {
   1887 	      /* Local symbol.  */
   1888 	      if (local_got_ents[r_symndx] == NULL)
   1889 		{
   1890 		  bfd_vma offset =
   1891 		    ADD_SYMBOL_REF_SEC_AND_RELOC (got,
   1892 						  bfd_link_pic (info),
   1893 						  NULL);
   1894 		  new_got_entry_to_list (&(local_got_ents[r_symndx]),
   1895 					 GOT_NORMAL, offset, TLS_GOT_NONE);
   1896 		}
   1897 	    }
   1898 	  else
   1899 	    {
   1900 	      /* Global symbol.  */
   1901 	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1902 	      if (h->got.glist == NULL)
   1903 		{
   1904 		  bfd_vma offset =
   1905 		    ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
   1906 		  new_got_entry_to_list (&h->got.glist,
   1907 					 GOT_NORMAL, offset, TLS_GOT_NONE);
   1908 		}
   1909 	    }
   1910 	}
   1911 
   1912       if (is_reloc_for_TLS (howto) == TRUE)
   1913 	{
   1914 	  enum tls_type_e type = GOT_UNKNOWN;
   1915 
   1916 	  switch (r_type)
   1917 	    {
   1918 	      case R_ARC_TLS_GD_GOT:
   1919 		type = GOT_TLS_GD;
   1920 		break;
   1921 	      case R_ARC_TLS_IE_GOT:
   1922 		type = GOT_TLS_IE;
   1923 		break;
   1924 	      default:
   1925 		break;
   1926 	    }
   1927 
   1928 	  struct got_entry **list = NULL;
   1929 	  if (h != NULL)
   1930 	    list = &(h->got.glist);
   1931 	  else
   1932 	    list = &(local_got_ents[r_symndx]);
   1933 
   1934 	  if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
   1935 	    {
   1936 	      enum tls_got_entries entries = TLS_GOT_NONE;
   1937 	      bfd_vma offset =
   1938 		ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
   1939 
   1940 	      if (type == GOT_TLS_GD)
   1941 		{
   1942 		  bfd_vma ATTRIBUTE_UNUSED notneeded =
   1943 		    ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
   1944 		  entries = TLS_GOT_MOD_AND_OFF;
   1945 		}
   1946 
   1947 	      if (entries == TLS_GOT_NONE)
   1948 		entries = TLS_GOT_OFF;
   1949 
   1950 	      new_got_entry_to_list (list, type, offset, entries);
   1951 	    }
   1952 	}
   1953     }
   1954 
   1955   return TRUE;
   1956 }
   1957 
   1958 #define ELF_DYNAMIC_INTERPRETER  "/sbin/ld-uClibc.so"
   1959 
   1960 static struct plt_version_t *
   1961 arc_get_plt_version (struct bfd_link_info *info)
   1962 {
   1963   int i;
   1964 
   1965   for (i = 0; i < 1; i++)
   1966     {
   1967       ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
   1968 		 plt_versions[i].entry_size,
   1969 		 plt_versions[i].elem_size);
   1970     }
   1971 
   1972   if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
   1973     {
   1974       if (bfd_link_pic (info))
   1975 	return &(plt_versions[ELF_ARCV2_PIC]);
   1976       else
   1977 	return &(plt_versions[ELF_ARCV2_ABS]);
   1978     }
   1979   else
   1980     {
   1981       if (bfd_link_pic (info))
   1982 	return &(plt_versions[ELF_ARC_PIC]);
   1983       else
   1984 	return &(plt_versions[ELF_ARC_ABS]);
   1985     }
   1986 }
   1987 
   1988 static bfd_vma
   1989 add_symbol_to_plt (struct bfd_link_info *info)
   1990 {
   1991   struct elf_link_hash_table *htab = elf_hash_table (info);
   1992   bfd_vma ret;
   1993 
   1994   struct plt_version_t *plt_data = arc_get_plt_version (info);
   1995 
   1996   /* If this is the first .plt entry, make room for the special first
   1997      entry.  */
   1998   if (htab->splt->size == 0)
   1999     htab->splt->size += plt_data->entry_size;
   2000 
   2001   ret = htab->splt->size;
   2002 
   2003   htab->splt->size += plt_data->elem_size;
   2004   ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
   2005 
   2006   htab->sgotplt->size += 4;
   2007   htab->srelplt->size += sizeof (Elf32_External_Rela);
   2008 
   2009   return ret;
   2010 }
   2011 
   2012 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS)	\
   2013   plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
   2014 
   2015 static void
   2016 plt_do_relocs_for_symbol (bfd *abfd,
   2017 			  struct elf_link_hash_table *htab,
   2018 			  const struct plt_reloc *reloc,
   2019 			  bfd_vma plt_offset,
   2020 			  bfd_vma symbol_got_offset)
   2021 {
   2022   while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
   2023     {
   2024       bfd_vma relocation = 0;
   2025 
   2026       switch (SYM_ONLY (reloc->symbol))
   2027 	{
   2028 	  case SGOT:
   2029 		relocation =
   2030 		    htab->sgotplt->output_section->vma +
   2031 		    htab->sgotplt->output_offset + symbol_got_offset;
   2032 		break;
   2033 	}
   2034       relocation += reloc->addend;
   2035 
   2036       if (IS_RELATIVE (reloc->symbol))
   2037 	{
   2038 	  bfd_vma reloc_offset = reloc->offset;
   2039 	  reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
   2040 	  reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
   2041 
   2042 	  relocation -= htab->splt->output_section->vma
   2043 			 + htab->splt->output_offset
   2044 			 + plt_offset + reloc_offset;
   2045 	}
   2046 
   2047       /* TODO: being ME is not a property of the relocation but of the
   2048 	 section of which is applying the relocation. */
   2049       if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd))
   2050 	{
   2051 	  relocation =
   2052 	      ((relocation & 0xffff0000) >> 16) |
   2053 	      ((relocation & 0xffff) << 16);
   2054 	}
   2055 
   2056       switch (reloc->size)
   2057 	{
   2058 	  case 32:
   2059 	    bfd_put_32 (htab->splt->output_section->owner,
   2060 			relocation,
   2061 			htab->splt->contents + plt_offset + reloc->offset);
   2062 	    break;
   2063 	}
   2064 
   2065       reloc = &(reloc[1]); /* Jump to next relocation.  */
   2066     }
   2067 }
   2068 
   2069 static void
   2070 relocate_plt_for_symbol (bfd *output_bfd,
   2071 			 struct bfd_link_info *info,
   2072 			 struct elf_link_hash_entry *h)
   2073 {
   2074   struct plt_version_t *plt_data = arc_get_plt_version (info);
   2075   struct elf_link_hash_table *htab = elf_hash_table (info);
   2076 
   2077   bfd_vma plt_index = (h->plt.offset  - plt_data->entry_size)
   2078 		      / plt_data->elem_size;
   2079   bfd_vma got_offset = (plt_index + 3) * 4;
   2080 
   2081   ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
   2082 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
   2083 	     h->plt.offset,
   2084 	     htab->splt->output_section->vma
   2085 	     + htab->splt->output_offset
   2086 	     + h->plt.offset,
   2087 	     got_offset,
   2088 	     htab->sgotplt->output_section->vma
   2089 	     + htab->sgotplt->output_offset
   2090 	     + got_offset,
   2091 	     h->root.root.string);
   2092 
   2093 
   2094   {
   2095     bfd_vma i = 0;
   2096     uint16_t *ptr = (uint16_t *) plt_data->elem;
   2097     for (i = 0; i < plt_data->elem_size/2; i++)
   2098       {
   2099 	uint16_t data = ptr[i];
   2100 	bfd_put_16 (output_bfd,
   2101 		    (bfd_vma) data,
   2102 		    htab->splt->contents + h->plt.offset + (i*2));
   2103       }
   2104   }
   2105 
   2106   plt_do_relocs_for_symbol (output_bfd, htab,
   2107 			    plt_data->elem_relocs,
   2108 			    h->plt.offset,
   2109 			    got_offset);
   2110 
   2111   /* Fill in the entry in the global offset table.  */
   2112   bfd_put_32 (output_bfd,
   2113 	      (bfd_vma) (htab->splt->output_section->vma
   2114 			 + htab->splt->output_offset),
   2115 	      htab->sgotplt->contents + got_offset);
   2116 
   2117   /* TODO: Fill in the entry in the .rela.plt section.  */
   2118   {
   2119     Elf_Internal_Rela rel;
   2120     bfd_byte *loc;
   2121 
   2122     rel.r_offset = (htab->sgotplt->output_section->vma
   2123 		    + htab->sgotplt->output_offset
   2124 		    + got_offset);
   2125     rel.r_addend = 0;
   2126 
   2127     BFD_ASSERT (h->dynindx != -1);
   2128     rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
   2129 
   2130     loc = htab->srelplt->contents;
   2131     loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
   2132     bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
   2133   }
   2134 }
   2135 
   2136 static void
   2137 relocate_plt_for_entry (bfd *abfd,
   2138 			struct bfd_link_info *info)
   2139 {
   2140   struct plt_version_t *plt_data = arc_get_plt_version (info);
   2141   struct elf_link_hash_table *htab = elf_hash_table (info);
   2142 
   2143   {
   2144     bfd_vma i = 0;
   2145     uint16_t *ptr = (uint16_t *) plt_data->entry;
   2146     for (i = 0; i < plt_data->entry_size/2; i++)
   2147       {
   2148 	uint16_t data = ptr[i];
   2149 	bfd_put_16 (abfd,
   2150 		    (bfd_vma) data,
   2151 		    htab->splt->contents + (i*2));
   2152       }
   2153   }
   2154   PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
   2155 }
   2156 
   2157 /* Desc : Adjust a symbol defined by a dynamic object and referenced
   2158    by a regular object.  The current definition is in some section of
   2159    the dynamic object, but we're not including those sections.  We
   2160    have to change the definition to something the rest of the link can
   2161    understand.  */
   2162 
   2163 static bfd_boolean
   2164 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
   2165 			      struct elf_link_hash_entry *h)
   2166 {
   2167   asection *s;
   2168   bfd *dynobj = (elf_hash_table (info))->dynobj;
   2169   struct elf_link_hash_table *htab = elf_hash_table (info);
   2170 
   2171   if (h->type == STT_FUNC
   2172       || h->type == STT_GNU_IFUNC
   2173       || h->needs_plt == 1)
   2174     {
   2175       if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
   2176 	{
   2177 	  /* This case can occur if we saw a PLT32 reloc in an input
   2178 	     file, but the symbol was never referred to by a dynamic
   2179 	     object.  In such a case, we don't actually need to build
   2180 	     a procedure linkage table, and we can just do a PC32
   2181 	     reloc instead.  */
   2182 	  BFD_ASSERT (h->needs_plt);
   2183 	  return TRUE;
   2184 	}
   2185 
   2186       /* Make sure this symbol is output as a dynamic symbol.  */
   2187       if (h->dynindx == -1 && !h->forced_local
   2188 	  && !bfd_elf_link_record_dynamic_symbol (info, h))
   2189 	return FALSE;
   2190 
   2191       if (bfd_link_pic (info)
   2192 	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
   2193 	{
   2194 	  bfd_vma loc = add_symbol_to_plt (info);
   2195 
   2196 	  if (!bfd_link_pic (info) && !h->def_regular)
   2197 	    {
   2198 	      h->root.u.def.section = htab->splt;
   2199 	      h->root.u.def.value = loc;
   2200 	    }
   2201 	  h->plt.offset = loc;
   2202 	}
   2203       else
   2204 	{
   2205 	  h->plt.offset = (bfd_vma) -1;
   2206 	  h->needs_plt = 0;
   2207 	}
   2208       return TRUE;
   2209     }
   2210 
   2211   /* If this is a weak symbol, and there is a real definition, the
   2212      processor independent code will have arranged for us to see the
   2213      real definition first, and we can just use the same value.  */
   2214   if (h->u.weakdef != NULL)
   2215     {
   2216       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
   2217 		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
   2218       h->root.u.def.section = h->u.weakdef->root.u.def.section;
   2219       h->root.u.def.value = h->u.weakdef->root.u.def.value;
   2220       return TRUE;
   2221     }
   2222 
   2223   /* This is a reference to a symbol defined by a dynamic object which
   2224      is not a function.  */
   2225 
   2226   /* If we are creating a shared library, we must presume that the
   2227      only references to the symbol are via the global offset table.
   2228      For such cases we need not do anything here; the relocations will
   2229      be handled correctly by relocate_section.  */
   2230   if (!bfd_link_executable (info))
   2231     return TRUE;
   2232 
   2233   /* If there are no non-GOT references, we do not need a copy
   2234      relocation.  */
   2235   if (!h->non_got_ref)
   2236     return TRUE;
   2237 
   2238   /* If -z nocopyreloc was given, we won't generate them either.  */
   2239   if (info->nocopyreloc)
   2240     {
   2241       h->non_got_ref = 0;
   2242       return TRUE;
   2243     }
   2244 
   2245   /* We must allocate the symbol in our .dynbss section, which will
   2246      become part of the .bss section of the executable.  There will be
   2247      an entry for this symbol in the .dynsym section.  The dynamic
   2248      object will contain position independent code, so all references
   2249      from the dynamic object to this symbol will go through the global
   2250      offset table.  The dynamic linker will use the .dynsym entry to
   2251      determine the address it must put in the global offset table, so
   2252      both the dynamic object and the regular object will refer to the
   2253      same memory location for the variable.  */
   2254 
   2255   if (htab == NULL)
   2256     return FALSE;
   2257 
   2258   /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
   2259      copy the initial value out of the dynamic object and into the
   2260      runtime process image.  We need to remember the offset into the
   2261      .rela.bss section we are going to use.  */
   2262   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
   2263     {
   2264       asection *srel;
   2265 
   2266       srel = bfd_get_section_by_name (dynobj, ".rela.bss");
   2267       BFD_ASSERT (srel != NULL);
   2268       srel->size += sizeof (Elf32_External_Rela);
   2269       h->needs_copy = 1;
   2270     }
   2271 
   2272   s = bfd_get_section_by_name (dynobj, ".dynbss");
   2273   BFD_ASSERT (s != NULL);
   2274 
   2275   return _bfd_elf_adjust_dynamic_copy (info, h, s);
   2276 }
   2277 
   2278 /* Function :  elf_arc_finish_dynamic_symbol
   2279    Brief    :  Finish up dynamic symbol handling.  We set the
   2280 	     contents of various dynamic sections here.
   2281    Args     :  output_bfd :
   2282 	       info	  :
   2283 	       h	  :
   2284 	       sym	  :
   2285    Returns  : True/False as the return status.  */
   2286 
   2287 static bfd_boolean
   2288 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
   2289 			       struct bfd_link_info *info,
   2290 			       struct elf_link_hash_entry *h,
   2291 			       Elf_Internal_Sym * sym)
   2292 {
   2293   if (h->plt.offset != (bfd_vma) -1)
   2294     {
   2295       relocate_plt_for_symbol (output_bfd, info, h);
   2296 
   2297       if (!h->def_regular)
   2298 	{
   2299 	  /* Mark the symbol as undefined, rather than as defined in
   2300 	     the .plt section.  Leave the value alone.  */
   2301 	  sym->st_shndx = SHN_UNDEF;
   2302 	}
   2303     }
   2304 
   2305   if (h->got.glist != NULL)
   2306     {
   2307       struct got_entry *list = h->got.glist;
   2308 
   2309       /* Traverse the list of got entries for this symbol.  */
   2310       while (list)
   2311 	{
   2312 	  bfd_vma got_offset = h->got.glist->offset;
   2313 
   2314 	  if (list->type == GOT_NORMAL
   2315 	      && list->created_dyn_relocation == FALSE)
   2316 	    {
   2317 	      if (bfd_link_pic (info)
   2318 		  && (info->symbolic || h->dynindx == -1)
   2319 		  && h->def_regular)
   2320 		{
   2321 		  ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
   2322 		}
   2323 	      /* Do not fully understand the side effects of this condition.
   2324 		 The relocation space might still being reserved.  Perhaps
   2325 		 I should clear its value.  */
   2326 	      else if (h->dynindx != -1)
   2327 		{
   2328 		  ADD_RELA (output_bfd, got, got_offset, h->dynindx,
   2329 			  R_ARC_GLOB_DAT, 0);
   2330 		}
   2331 	      list->created_dyn_relocation = TRUE;
   2332 	    }
   2333 	  else if (list->existing_entries != TLS_GOT_NONE)
   2334 	    {
   2335 	      struct elf_link_hash_table *htab = elf_hash_table (info);
   2336 	      enum tls_got_entries e = list->existing_entries;
   2337 
   2338 	      BFD_ASSERT (list->type != GOT_TLS_GD
   2339 			  || list->existing_entries == TLS_GOT_MOD_AND_OFF);
   2340 
   2341 	      bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
   2342 	      if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_MOD)
   2343 		{
   2344 		  ADD_RELA (output_bfd, got, got_offset, dynindx,
   2345 			    R_ARC_TLS_DTPMOD, 0);
   2346 		  ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
   2347 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
   2348 			     list->type,
   2349 			     got_offset,
   2350 			     htab->sgot->output_section->vma
   2351 			     + htab->sgot->output_offset + got_offset,
   2352 			     dynindx, 0);
   2353 		}
   2354 	      if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_OFF)
   2355 		{
   2356 		  bfd_vma addend = 0;
   2357 		  if (list->type == GOT_TLS_IE)
   2358 		    addend = bfd_get_32 (output_bfd,
   2359 					 htab->sgot->contents + got_offset);
   2360 
   2361 		  ADD_RELA (output_bfd, got,
   2362 			    got_offset + (e == TLS_GOT_MOD_AND_OFF ? 4 : 0),
   2363 			    dynindx,
   2364 			    (list->type == GOT_TLS_IE ?
   2365 			     R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
   2366 			    addend);
   2367 
   2368 		  ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
   2369 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
   2370 			     list->type,
   2371 			     got_offset,
   2372 			     htab->sgot->output_section->vma
   2373 			     + htab->sgot->output_offset + got_offset,
   2374 			     dynindx, addend);
   2375 		}
   2376 	    }
   2377 
   2378 	  list = list->next;
   2379 	}
   2380 
   2381       h->got.glist = NULL;
   2382     }
   2383 
   2384   if (h->needs_copy)
   2385     {
   2386       bfd_vma rel_offset = (h->root.u.def.value
   2387 			    + h->root.u.def.section->output_section->vma
   2388 			    + h->root.u.def.section->output_offset);
   2389 
   2390       asection *srelbss =
   2391 	bfd_get_section_by_name (h->root.u.def.section->owner,
   2392 				 ".rela.bss");
   2393 
   2394       bfd_byte * loc = srelbss->contents
   2395 	+ (srelbss->reloc_count * sizeof (Elf32_External_Rela));
   2396       srelbss->reloc_count++;
   2397 
   2398       Elf_Internal_Rela rel;
   2399       rel.r_addend = 0;
   2400       rel.r_offset = rel_offset;
   2401 
   2402       BFD_ASSERT (h->dynindx != -1);
   2403       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
   2404 
   2405       bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
   2406     }
   2407 
   2408   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
   2409   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
   2410       || strcmp (h->root.root.string, "__DYNAMIC") == 0
   2411       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
   2412     sym->st_shndx = SHN_ABS;
   2413 
   2414   return TRUE;
   2415 }
   2416 
   2417 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION)		\
   2418   case TAG:							\
   2419   if (SYMBOL != NULL)						\
   2420     h = elf_link_hash_lookup (elf_hash_table (info),		\
   2421 			      SYMBOL, FALSE, FALSE, TRUE);	\
   2422   else if (SECTION != NULL)					\
   2423     s = bfd_get_linker_section (dynobj, SECTION);		\
   2424   break;
   2425 
   2426 /* Function :  elf_arc_finish_dynamic_sections
   2427    Brief    :  Finish up the dynamic sections handling.
   2428    Args     :  output_bfd :
   2429 	       info	  :
   2430 	       h	  :
   2431 	       sym	  :
   2432    Returns  : True/False as the return status.  */
   2433 
   2434 static bfd_boolean
   2435 elf_arc_finish_dynamic_sections (bfd * output_bfd,
   2436 				 struct bfd_link_info *info)
   2437 {
   2438   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
   2439   struct elf_link_hash_table *htab = elf_hash_table (info);
   2440   bfd *dynobj = (elf_hash_table (info))->dynobj;
   2441 
   2442   if (ds.sdyn)
   2443     {
   2444       Elf32_External_Dyn *dyncon, *dynconend;
   2445 
   2446       dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
   2447       dynconend =
   2448 	(Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
   2449       for (; dyncon < dynconend; dyncon++)
   2450 	{
   2451 	  Elf_Internal_Dyn internal_dyn;
   2452 	  bfd_boolean	  do_it = FALSE;
   2453 
   2454 	  struct elf_link_hash_entry *h = NULL;
   2455 	  asection	 *s = NULL;
   2456 
   2457 	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
   2458 
   2459 	  switch (internal_dyn.d_tag)
   2460 	    {
   2461 	      GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL)
   2462 	      GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL)
   2463 	      GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt")
   2464 	      GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt")
   2465 	      GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt")
   2466 	      GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt")
   2467 	      GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version")
   2468 	      GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d")
   2469 	      GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r")
   2470 	      default:
   2471 		break;
   2472 	    }
   2473 
   2474 	  /* In case the dynamic symbols should be updated with a symbol.  */
   2475 	  if (h != NULL
   2476 	      && (h->root.type == bfd_link_hash_defined
   2477 		  || h->root.type == bfd_link_hash_defweak))
   2478 	    {
   2479 	      asection	     *asec_ptr;
   2480 
   2481 	      internal_dyn.d_un.d_val = h->root.u.def.value;
   2482 	      asec_ptr = h->root.u.def.section;
   2483 	      if (asec_ptr->output_section != NULL)
   2484 		{
   2485 		  internal_dyn.d_un.d_val +=
   2486 		    (asec_ptr->output_section->vma +
   2487 		     asec_ptr->output_offset);
   2488 		}
   2489 	      else
   2490 		{
   2491 		  /* The symbol is imported from another shared
   2492 		     library and does not apply to this one.  */
   2493 		  internal_dyn.d_un.d_val = 0;
   2494 		}
   2495 	      do_it = TRUE;
   2496 	    }
   2497 	  else if (s != NULL) /* With a section information.  */
   2498 	    {
   2499 	      switch (internal_dyn.d_tag)
   2500 		{
   2501 		  case DT_PLTGOT:
   2502 		  case DT_JMPREL:
   2503 		  case DT_VERSYM:
   2504 		  case DT_VERDEF:
   2505 		  case DT_VERNEED:
   2506 		    internal_dyn.d_un.d_ptr = (s->output_section->vma
   2507 					       + s->output_offset);
   2508 		    do_it = TRUE;
   2509 		    break;
   2510 
   2511 		  case DT_PLTRELSZ:
   2512 		    internal_dyn.d_un.d_val = s->size;
   2513 		    do_it = TRUE;
   2514 		    break;
   2515 
   2516 		  case DT_RELASZ:
   2517 		    if (s != NULL)
   2518 		      internal_dyn.d_un.d_val -= s->size;
   2519 		    do_it = TRUE;
   2520 		    break;
   2521 
   2522 		  default:
   2523 		    break;
   2524 		}
   2525 	    }
   2526 
   2527 	  if (do_it)
   2528 	    bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
   2529 	}
   2530 
   2531       if (htab->splt->size > 0)
   2532 	{
   2533 	  relocate_plt_for_entry (output_bfd, info);
   2534 	}
   2535 
   2536       /* TODO: Validate this.  */
   2537       elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
   2538 	= 0xc;
   2539     }
   2540 
   2541   /* Fill in the first three entries in the global offset table.  */
   2542   if (htab->sgot)
   2543     {
   2544       struct elf_link_hash_entry *h;
   2545       h = elf_link_hash_lookup (elf_hash_table (info), "_GLOBAL_OFFSET_TABLE_",
   2546 				 FALSE, FALSE, TRUE);
   2547 
   2548 	if (h != NULL && h->root.type != bfd_link_hash_undefined
   2549 	    && h->root.u.def.section != NULL)
   2550 	{
   2551 	  asection *sec = h->root.u.def.section;
   2552 
   2553 	  if (ds.sdyn == NULL)
   2554 	    bfd_put_32 (output_bfd, (bfd_vma) 0,
   2555 			sec->contents);
   2556 	  else
   2557 	    bfd_put_32 (output_bfd,
   2558 			ds.sdyn->output_section->vma + ds.sdyn->output_offset,
   2559 			sec->contents);
   2560 	  bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 4);
   2561 	  bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 8);
   2562 	}
   2563     }
   2564 
   2565   return TRUE;
   2566 }
   2567 
   2568 #define ADD_DYNAMIC_SYMBOL(NAME, TAG)					\
   2569   h =  elf_link_hash_lookup (elf_hash_table (info),			\
   2570 			     NAME, FALSE, FALSE, FALSE);		\
   2571   if ((h != NULL && (h->ref_regular || h->def_regular)))		\
   2572     if (! _bfd_elf_add_dynamic_entry (info, TAG, 0))			\
   2573       return FALSE;
   2574 
   2575 /* Set the sizes of the dynamic sections.  */
   2576 static bfd_boolean
   2577 elf_arc_size_dynamic_sections (bfd * output_bfd,
   2578 			       struct bfd_link_info *info)
   2579 {
   2580   bfd *	   dynobj;
   2581   asection *      s;
   2582   bfd_boolean	  relocs_exist = FALSE;
   2583   bfd_boolean	  reltext_exist = FALSE;
   2584   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
   2585   struct elf_link_hash_table *htab = elf_hash_table (info);
   2586 
   2587   dynobj = (elf_hash_table (info))->dynobj;
   2588   BFD_ASSERT (dynobj != NULL);
   2589 
   2590   if ((elf_hash_table (info))->dynamic_sections_created)
   2591     {
   2592       struct elf_link_hash_entry *h;
   2593 
   2594       /* Set the contents of the .interp section to the
   2595 	 interpreter.  */
   2596       if (!bfd_link_pic (info))
   2597 	{
   2598 	  s = bfd_get_section_by_name (dynobj, ".interp");
   2599 	  BFD_ASSERT (s != NULL);
   2600 	  s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
   2601 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
   2602 	}
   2603 
   2604       /* Add some entries to the .dynamic section.  We fill in some of
   2605 	 the values later, in elf_bfd_final_link, but we must add the
   2606 	 entries now so that we know the final size of the .dynamic
   2607 	 section.  Checking if the .init section is present.  We also
   2608 	 create DT_INIT and DT_FINI entries if the init_str has been
   2609 	 changed by the user.  */
   2610       ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
   2611       ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
   2612     }
   2613   else
   2614     {
   2615       /* We may have created entries in the .rela.got section.
   2616 	 However, if we are not creating the dynamic sections, we will
   2617 	 not actually use these entries.  Reset the size of .rela.got,
   2618 	 which will cause it to get stripped from the output file
   2619 	 below.  */
   2620       if (htab->srelgot != NULL)
   2621 	htab->srelgot->size = 0;
   2622     }
   2623 
   2624   if (htab->splt != NULL && htab->splt->size == 0)
   2625     htab->splt->flags |= SEC_EXCLUDE;
   2626   for (s = dynobj->sections; s != NULL; s = s->next)
   2627     {
   2628       if ((s->flags & SEC_LINKER_CREATED) == 0)
   2629 	continue;
   2630 
   2631       if (strncmp (s->name, ".rela", 5) == 0)
   2632 	{
   2633 	  if (s->size == 0)
   2634 	    {
   2635 	      s->flags |= SEC_EXCLUDE;
   2636 	    }
   2637 	  else
   2638 	    {
   2639 	      if (strcmp (s->name, ".rela.plt") != 0)
   2640 		{
   2641 		  const char *outname =
   2642 		    bfd_get_section_name (output_bfd,
   2643 					  htab->srelplt->output_section);
   2644 
   2645 		  asection *target = bfd_get_section_by_name (output_bfd,
   2646 							      outname + 4);
   2647 
   2648 		  relocs_exist = TRUE;
   2649 		  if (target != NULL && target->size != 0
   2650 		      && (target->flags & SEC_READONLY) != 0
   2651 		      && (target->flags & SEC_ALLOC) != 0)
   2652 		    reltext_exist = TRUE;
   2653 		}
   2654 	    }
   2655 
   2656 	  /* We use the reloc_count field as a counter if we need to
   2657 	     copy relocs into the output file.  */
   2658 	  s->reloc_count = 0;
   2659 	}
   2660 
   2661       if (strcmp (s->name, ".dynamic") == 0)
   2662 	continue;
   2663 
   2664       if (s->size != 0)
   2665 	s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
   2666 
   2667       if (s->contents == NULL && s->size != 0)
   2668 	return FALSE;
   2669     }
   2670 
   2671   if (ds.sdyn)
   2672     {
   2673       /* TODO: Check if this is needed.  */
   2674       if (!bfd_link_pic (info))
   2675 	if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
   2676 		return FALSE;
   2677 
   2678       if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
   2679 	if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
   2680 	    || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
   2681 	    || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
   2682 	    || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
   2683 	   )
   2684 	  return FALSE;
   2685 
   2686       if (relocs_exist == TRUE)
   2687 	if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
   2688 	    || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
   2689 	    || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
   2690 					    sizeof (Elf32_External_Rela))
   2691 	   )
   2692 	  return FALSE;
   2693 
   2694       if (reltext_exist == TRUE)
   2695 	if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
   2696 	  return FALSE;
   2697     }
   2698 
   2699   return TRUE;
   2700 }
   2701 
   2702 
   2703 /* Classify dynamic relocs such that -z combreloc can reorder and combine
   2704    them.  */
   2705 static enum elf_reloc_type_class
   2706 elf32_arc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
   2707 			    const asection *rel_sec ATTRIBUTE_UNUSED,
   2708 			    const Elf_Internal_Rela *rela)
   2709 {
   2710   switch ((int) ELF32_R_TYPE (rela->r_info))
   2711     {
   2712     case R_ARC_RELATIVE:
   2713       return reloc_class_relative;
   2714     case R_ARC_JMP_SLOT:
   2715       return reloc_class_plt;
   2716     case R_ARC_COPY:
   2717       return reloc_class_copy;
   2718     /* TODO: Needed in future to support ifunc.  */
   2719     /*
   2720     case R_ARC_IRELATIVE:
   2721       return reloc_class_ifunc;
   2722     */
   2723     default:
   2724       return reloc_class_normal;
   2725     }
   2726 }
   2727 
   2728 const struct elf_size_info arc_elf32_size_info =
   2729 {
   2730   sizeof (Elf32_External_Ehdr),
   2731   sizeof (Elf32_External_Phdr),
   2732   sizeof (Elf32_External_Shdr),
   2733   sizeof (Elf32_External_Rel),
   2734   sizeof (Elf32_External_Rela),
   2735   sizeof (Elf32_External_Sym),
   2736   sizeof (Elf32_External_Dyn),
   2737   sizeof (Elf_External_Note),
   2738   4,
   2739   1,
   2740   32, 2,
   2741   ELFCLASS32, EV_CURRENT,
   2742   bfd_elf32_write_out_phdrs,
   2743   bfd_elf32_write_shdrs_and_ehdr,
   2744   bfd_elf32_checksum_contents,
   2745   bfd_elf32_write_relocs,
   2746   bfd_elf32_swap_symbol_in,
   2747   bfd_elf32_swap_symbol_out,
   2748   bfd_elf32_slurp_reloc_table,
   2749   bfd_elf32_slurp_symbol_table,
   2750   bfd_elf32_swap_dyn_in,
   2751   bfd_elf32_swap_dyn_out,
   2752   bfd_elf32_swap_reloc_in,
   2753   bfd_elf32_swap_reloc_out,
   2754   bfd_elf32_swap_reloca_in,
   2755   bfd_elf32_swap_reloca_out
   2756 };
   2757 
   2758 #define elf_backend_size_info		arc_elf32_size_info
   2759 
   2760 static struct bfd_link_hash_table *
   2761 arc_elf_link_hash_table_create (bfd *abfd)
   2762 {
   2763   struct elf_link_hash_table *htab;
   2764 
   2765   htab = bfd_zmalloc (sizeof (*htab));
   2766   if (htab == NULL)
   2767     return NULL;
   2768 
   2769   if (!_bfd_elf_link_hash_table_init (htab, abfd,
   2770 				      _bfd_elf_link_hash_newfunc,
   2771 				      sizeof (struct elf_link_hash_entry),
   2772 				      GENERIC_ELF_DATA))
   2773     {
   2774       free (htab);
   2775       return NULL;
   2776     }
   2777 
   2778   htab->init_got_refcount.refcount = 0;
   2779   htab->init_got_refcount.glist = NULL;
   2780   htab->init_got_offset.offset = 0;
   2781   htab->init_got_offset.glist = NULL;
   2782   return (struct bfd_link_hash_table *) htab;
   2783 }
   2784 
   2785 /* Hook called by the linker routine which adds symbols from an object
   2786    file.  */
   2787 
   2788 static bfd_boolean
   2789 elf_arc_add_symbol_hook (bfd * abfd,
   2790 			 struct bfd_link_info * info,
   2791 			 Elf_Internal_Sym * sym,
   2792 			 const char ** namep ATTRIBUTE_UNUSED,
   2793 			 flagword * flagsp ATTRIBUTE_UNUSED,
   2794 			 asection ** secp ATTRIBUTE_UNUSED,
   2795 			 bfd_vma * valp ATTRIBUTE_UNUSED)
   2796 {
   2797   if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
   2798       && (abfd->flags & DYNAMIC) == 0
   2799       && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
   2800     elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
   2801 
   2802   return TRUE;
   2803 }
   2804 
   2805 #define TARGET_LITTLE_SYM   arc_elf32_le_vec
   2806 #define TARGET_LITTLE_NAME  "elf32-littlearc"
   2807 #define TARGET_BIG_SYM	    arc_elf32_be_vec
   2808 #define TARGET_BIG_NAME     "elf32-bigarc"
   2809 #define ELF_ARCH	    bfd_arch_arc
   2810 #define ELF_MACHINE_CODE    EM_ARC_COMPACT
   2811 #define ELF_MACHINE_ALT1    EM_ARC_COMPACT2
   2812 #define ELF_MAXPAGESIZE     0x2000
   2813 
   2814 #define bfd_elf32_bfd_link_hash_table_create	arc_elf_link_hash_table_create
   2815 
   2816 #define bfd_elf32_bfd_merge_private_bfd_data    arc_elf_merge_private_bfd_data
   2817 #define bfd_elf32_bfd_reloc_type_lookup		arc_elf32_bfd_reloc_type_lookup
   2818 #define bfd_elf32_bfd_set_private_flags		arc_elf_set_private_flags
   2819 #define bfd_elf32_bfd_print_private_bfd_data    arc_elf_print_private_bfd_data
   2820 #define bfd_elf32_bfd_copy_private_bfd_data     arc_elf_copy_private_bfd_data
   2821 
   2822 #define elf_info_to_howto_rel		     arc_info_to_howto_rel
   2823 #define elf_backend_object_p		     arc_elf_object_p
   2824 #define elf_backend_final_write_processing   arc_elf_final_write_processing
   2825 
   2826 #define elf_backend_relocate_section	     elf_arc_relocate_section
   2827 #define elf_backend_check_relocs	     elf_arc_check_relocs
   2828 #define elf_backend_create_dynamic_sections  _bfd_elf_create_dynamic_sections
   2829 
   2830 #define elf_backend_reloc_type_class		elf32_arc_reloc_type_class
   2831 
   2832 #define elf_backend_adjust_dynamic_symbol    elf_arc_adjust_dynamic_symbol
   2833 #define elf_backend_finish_dynamic_symbol    elf_arc_finish_dynamic_symbol
   2834 
   2835 #define elf_backend_finish_dynamic_sections  elf_arc_finish_dynamic_sections
   2836 #define elf_backend_size_dynamic_sections    elf_arc_size_dynamic_sections
   2837 #define elf_backend_add_symbol_hook          elf_arc_add_symbol_hook
   2838 
   2839 #define elf_backend_can_gc_sections	1
   2840 #define elf_backend_want_got_plt	1
   2841 #define elf_backend_plt_readonly	1
   2842 #define elf_backend_rela_plts_and_copies_p 1
   2843 #define elf_backend_want_plt_sym	0
   2844 #define elf_backend_got_header_size	12
   2845 
   2846 #define elf_backend_may_use_rel_p	0
   2847 #define elf_backend_may_use_rela_p	1
   2848 #define elf_backend_default_use_rela_p	1
   2849 
   2850 #define elf_backend_default_execstack	0
   2851 
   2852 #include "elf32-target.h"
   2853