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