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