Home | History | Annotate | Line # | Download | only in bfd
elf32-pru.c revision 1.1.1.3
      1 /* 32-bit ELF support for TI PRU.
      2    Copyright (C) 2014-2020 Free Software Foundation, Inc.
      3    Contributed by Dimitar Dimitrov <dimitar (at) dinux.eu>
      4    Based on elf32-nios2.c
      5 
      6    This file is part of BFD, the Binary File Descriptor library.
      7 
      8    This program is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3 of the License, or
     11    (at your option) any later version.
     12 
     13    This program is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program; if not, write to the Free Software
     20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21    MA 02110-1301, USA.  */
     22 
     23 /* This file handles TI PRU ELF targets.  */
     24 
     25 #include "sysdep.h"
     26 #include "bfd.h"
     27 #include "libbfd.h"
     28 #include "bfdlink.h"
     29 #include "genlink.h"
     30 #include "elf-bfd.h"
     31 #include "elf/pru.h"
     32 #include "opcode/pru.h"
     33 #include "libiberty.h"
     34 
     35 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
     36 #define OCTETS_PER_BYTE(ABFD, SEC) 1
     37 
     38 #define SWAP_VALS(A,B)		      \
     39   do {				      \
     40       (A) ^= (B);		      \
     41       (B) ^= (A);		      \
     42       (A) ^= (B);		      \
     43   } while (0)
     44 
     45 /* Enable debugging printout at stdout with this variable.  */
     46 static bfd_boolean debug_relax = FALSE;
     47 
     48 /* Forward declarations.  */
     49 static bfd_reloc_status_type pru_elf32_pmem_relocate
     50   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     51 static bfd_reloc_status_type pru_elf32_s10_pcrel_relocate
     52   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     53 static bfd_reloc_status_type pru_elf32_u8_pcrel_relocate
     54   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     55 static bfd_reloc_status_type pru_elf32_ldi32_relocate
     56   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     57 static bfd_reloc_status_type bfd_elf_pru_diff_relocate
     58   (bfd *, arelent *, asymbol *, void *,	asection *, bfd *, char **);
     59 
     60 /* Target vector.  */
     61 extern const bfd_target pru_elf32_vec;
     62 
     63 /* The relocation table used for SHT_REL sections.  */
     64 static reloc_howto_type elf_pru_howto_table_rel[] = {
     65   /* No relocation.  */
     66   HOWTO (R_PRU_NONE,		/* type */
     67 	 0,			/* rightshift */
     68 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
     69 	 3,			/* bitsize */
     70 	 FALSE,			/* pc_relative */
     71 	 0,			/* bitpos */
     72 	 complain_overflow_dont,/* complain_on_overflow */
     73 	 bfd_elf_generic_reloc,	/* special_function */
     74 	 "R_PRU_NONE",		/* name */
     75 	 FALSE,			/* partial_inplace */
     76 	 0,			/* src_mask */
     77 	 0,			/* dst_mask */
     78 	 FALSE),		/* pcrel_offset */
     79 
     80   HOWTO (R_PRU_16_PMEM,
     81 	 2,
     82 	 1,			/* short */
     83 	 32,
     84 	 FALSE,
     85 	 0,
     86 	 complain_overflow_dont,
     87 	 bfd_elf_generic_reloc,
     88 	 "R_PRU_16_PMEM",
     89 	 FALSE,
     90 	 0,			/* src_mask */
     91 	 0xffff,
     92 	 FALSE),
     93 
     94   HOWTO (R_PRU_U16_PMEMIMM,
     95 	 2,
     96 	 2,
     97 	 32,
     98 	 FALSE,
     99 	 8,
    100 	 complain_overflow_unsigned,
    101 	 pru_elf32_pmem_relocate,
    102 	 "R_PRU_U16_PMEMIMM",
    103 	 FALSE,
    104 	 0,			/* src_mask */
    105 	 0x00ffff00,
    106 	 FALSE),
    107 
    108   HOWTO (R_PRU_BFD_RELOC_16,
    109 	 0,
    110 	 1,			/* short */
    111 	 16,
    112 	 FALSE,
    113 	 0,
    114 	 complain_overflow_bitfield,
    115 	 bfd_elf_generic_reloc,
    116 	 "R_PRU_BFD_RELOC16",
    117 	 FALSE,
    118 	 0,			/* src_mask */
    119 	 0x0000ffff,
    120 	 FALSE),
    121 
    122   /* 16-bit unsigned immediate relocation.  */
    123   HOWTO (R_PRU_U16,		/* type */
    124 	 0,			/* rightshift */
    125 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    126 	 16,			/* bitsize */
    127 	 FALSE,			/* pc_relative */
    128 	 8,			/* bitpos */
    129 	 complain_overflow_unsigned,	/* complain on overflow */
    130 	 bfd_elf_generic_reloc,	/* special function */
    131 	 "R_PRU_U16",		/* name */
    132 	 FALSE,			/* partial_inplace */
    133 	 0,			/* src_mask */
    134 	 0x00ffff00,		/* dest_mask */
    135 	 FALSE),		/* pcrel_offset */
    136 
    137   HOWTO (R_PRU_32_PMEM,
    138 	 2,
    139 	 2,			/* long */
    140 	 32,
    141 	 FALSE,
    142 	 0,
    143 	 complain_overflow_dont,
    144 	 pru_elf32_pmem_relocate,
    145 	 "R_PRU_32_PMEM",
    146 	 FALSE,
    147 	 0,			/* src_mask */
    148 	 0xffffffff,
    149 	 FALSE),
    150 
    151   HOWTO (R_PRU_BFD_RELOC_32,
    152 	 0,
    153 	 2,			/* long */
    154 	 32,
    155 	 FALSE,
    156 	 0,
    157 	 complain_overflow_dont,
    158 	 bfd_elf_generic_reloc,
    159 	 "R_PRU_BFD_RELOC32",
    160 	 FALSE,
    161 	 0,			/* src_mask */
    162 	 0xffffffff,
    163 	 FALSE),
    164 
    165   HOWTO (R_PRU_S10_PCREL,
    166 	 2,
    167 	 2,
    168 	 10,
    169 	 TRUE,
    170 	 0,
    171 	 complain_overflow_bitfield,
    172 	 pru_elf32_s10_pcrel_relocate,
    173 	 "R_PRU_S10_PCREL",
    174 	 FALSE,
    175 	 0,			/* src_mask */
    176 	 0x060000ff,
    177 	 TRUE),
    178 
    179   HOWTO (R_PRU_U8_PCREL,
    180 	 2,
    181 	 2,
    182 	 8,
    183 	 TRUE,
    184 	 0,
    185 	 complain_overflow_unsigned,
    186 	 pru_elf32_u8_pcrel_relocate,
    187 	 "R_PRU_U8_PCREL",
    188 	 FALSE,
    189 	 0,			/* src_mask */
    190 	 0x000000ff,
    191 	 TRUE),
    192 
    193   HOWTO (R_PRU_LDI32,
    194 	 0,			/* rightshift */
    195 	 4,			/* size (4 = 8bytes) */
    196 	 32,			/* bitsize */
    197 	 FALSE,			/* pc_relative */
    198 	 0,			/* bitpos */
    199 	 complain_overflow_unsigned, /* complain on overflow */
    200 	 pru_elf32_ldi32_relocate, /* special function */
    201 	 "R_PRU_LDI32",		/* name */
    202 	 FALSE,			/* partial_inplace */
    203 	 0,			/* src_mask */
    204 	 0xffffffff,		/* dest_mask */
    205 	 FALSE),		/* pcrel_offset */
    206 
    207   /* GNU-specific relocations.  */
    208   HOWTO (R_PRU_GNU_BFD_RELOC_8,
    209 	 0,
    210 	 0,			/* byte */
    211 	 8,
    212 	 FALSE,
    213 	 0,
    214 	 complain_overflow_bitfield,
    215 	 bfd_elf_generic_reloc,
    216 	 "R_PRU_BFD_RELOC8",
    217 	 FALSE,
    218 	 0,			/* src_mask */
    219 	 0x000000ff,
    220 	 FALSE),
    221 
    222   HOWTO (R_PRU_GNU_DIFF8,	/* type */
    223 	 0,			/* rightshift */
    224 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
    225 	 8,			/* bitsize */
    226 	 FALSE,			/* pc_relative */
    227 	 0,			/* bitpos */
    228 	 complain_overflow_bitfield, /* complain_on_overflow */
    229 	 bfd_elf_pru_diff_relocate, /* special_function */
    230 	 "R_PRU_DIFF8",		/* name */
    231 	 FALSE,			/* partial_inplace */
    232 	 0,			/* src_mask */
    233 	 0xff,			/* dst_mask */
    234 	 FALSE),		/* pcrel_offset */
    235 
    236   HOWTO (R_PRU_GNU_DIFF16,	/* type */
    237 	 0,			/* rightshift */
    238 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
    239 	 16,			/* bitsize */
    240 	 FALSE,			/* pc_relative */
    241 	 0,			/* bitpos */
    242 	 complain_overflow_bitfield, /* complain_on_overflow */
    243 	 bfd_elf_pru_diff_relocate,/* special_function */
    244 	 "R_PRU_DIFF16",	/* name */
    245 	 FALSE,			/* partial_inplace */
    246 	 0,			/* src_mask */
    247 	 0xffff,		/* dst_mask */
    248 	 FALSE),		/* pcrel_offset */
    249 
    250   HOWTO (R_PRU_GNU_DIFF32,	/* type */
    251 	 0,			/* rightshift */
    252 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    253 	 32,			/* bitsize */
    254 	 FALSE,			/* pc_relative */
    255 	 0,			/* bitpos */
    256 	 complain_overflow_bitfield, /* complain_on_overflow */
    257 	 bfd_elf_pru_diff_relocate,/* special_function */
    258 	 "R_PRU_DIFF32",	/* name */
    259 	 FALSE,			/* partial_inplace */
    260 	 0,			/* src_mask */
    261 	 0xffffffff,		/* dst_mask */
    262 	 FALSE),		/* pcrel_offset */
    263 
    264   HOWTO (R_PRU_GNU_DIFF16_PMEM,	/* type */
    265 	 0,			/* rightshift */
    266 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
    267 	 16,			/* bitsize */
    268 	 FALSE,			/* pc_relative */
    269 	 0,			/* bitpos */
    270 	 complain_overflow_bitfield, /* complain_on_overflow */
    271 	 bfd_elf_pru_diff_relocate,/* special_function */
    272 	 "R_PRU_DIFF16_PMEM",	/* name */
    273 	 FALSE,			/* partial_inplace */
    274 	 0,			/* src_mask */
    275 	 0xffff,		/* dst_mask */
    276 	 FALSE),		/* pcrel_offset */
    277 
    278   HOWTO (R_PRU_GNU_DIFF32_PMEM, /* type */
    279 	 0,			/* rightshift */
    280 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    281 	 32,			/* bitsize */
    282 	 FALSE,			/* pc_relative */
    283 	 0,			/* bitpos */
    284 	 complain_overflow_bitfield, /* complain_on_overflow */
    285 	 bfd_elf_pru_diff_relocate,/* special_function */
    286 	 "R_PRU_DIFF32_PMEM",	/* name */
    287 	 FALSE,			/* partial_inplace */
    288 	 0,			/* src_mask */
    289 	 0xffffffff,		/* dst_mask */
    290 	 FALSE),		/* pcrel_offset */
    291 
    292 /* Add other relocations here.  */
    293 };
    294 
    295 static unsigned char elf_code_to_howto_index[R_PRU_ILLEGAL + 1];
    296 
    297 /* Return the howto for relocation RTYPE.  */
    298 
    299 static reloc_howto_type *
    300 lookup_howto (unsigned int rtype)
    301 {
    302   static bfd_boolean initialized = FALSE;
    303   int i;
    304   int howto_tbl_size = (int) (sizeof (elf_pru_howto_table_rel)
    305 			      / sizeof (elf_pru_howto_table_rel[0]));
    306 
    307   if (! initialized)
    308     {
    309       initialized = TRUE;
    310       memset (elf_code_to_howto_index, 0xff,
    311 	      sizeof (elf_code_to_howto_index));
    312       for (i = 0; i < howto_tbl_size; i++)
    313 	elf_code_to_howto_index[elf_pru_howto_table_rel[i].type] = i;
    314     }
    315 
    316   if (rtype > R_PRU_ILLEGAL)
    317     return NULL;
    318   i = elf_code_to_howto_index[rtype];
    319   if (i >= howto_tbl_size)
    320     return NULL;
    321   return elf_pru_howto_table_rel + i;
    322 }
    323 
    324 /* Map for converting BFD reloc types to PRU reloc types.  */
    325 
    326 struct elf_reloc_map
    327 {
    328   bfd_reloc_code_real_type bfd_val;
    329   enum elf_pru_reloc_type elf_val;
    330 };
    331 
    332 static const struct elf_reloc_map pru_reloc_map[] =
    333 {
    334   {BFD_RELOC_NONE, R_PRU_NONE},
    335   {BFD_RELOC_PRU_16_PMEM, R_PRU_16_PMEM},
    336   {BFD_RELOC_PRU_U16_PMEMIMM, R_PRU_U16_PMEMIMM},
    337   {BFD_RELOC_16, R_PRU_BFD_RELOC_16},
    338   {BFD_RELOC_PRU_U16, R_PRU_U16},
    339   {BFD_RELOC_PRU_32_PMEM, R_PRU_32_PMEM},
    340   {BFD_RELOC_32, R_PRU_BFD_RELOC_32},
    341   {BFD_RELOC_PRU_S10_PCREL, R_PRU_S10_PCREL},
    342   {BFD_RELOC_PRU_U8_PCREL, R_PRU_U8_PCREL},
    343   {BFD_RELOC_PRU_LDI32, R_PRU_LDI32},
    344 
    345   {BFD_RELOC_8, R_PRU_GNU_BFD_RELOC_8},
    346   {BFD_RELOC_PRU_GNU_DIFF8, R_PRU_GNU_DIFF8},
    347   {BFD_RELOC_PRU_GNU_DIFF16, R_PRU_GNU_DIFF16},
    348   {BFD_RELOC_PRU_GNU_DIFF32, R_PRU_GNU_DIFF32},
    349   {BFD_RELOC_PRU_GNU_DIFF16_PMEM, R_PRU_GNU_DIFF16_PMEM},
    350   {BFD_RELOC_PRU_GNU_DIFF32_PMEM, R_PRU_GNU_DIFF32_PMEM},
    351 };
    352 
    353 
    354 /* Assorted hash table functions.  */
    355 
    356 /* Create an entry in a PRU ELF linker hash table.  */
    357 
    358 static struct bfd_hash_entry *
    359 link_hash_newfunc (struct bfd_hash_entry *entry,
    360 		   struct bfd_hash_table *table, const char *string)
    361 {
    362   /* Allocate the structure if it has not already been allocated by a
    363      subclass.  */
    364   if (entry == NULL)
    365     {
    366       entry = bfd_hash_allocate (table,
    367 				 sizeof (struct elf_link_hash_entry));
    368       if (entry == NULL)
    369 	return entry;
    370     }
    371 
    372   /* Call the allocation method of the superclass.  */
    373   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
    374 
    375   return entry;
    376 }
    377 
    378 /* Implement bfd_elf32_bfd_reloc_type_lookup:
    379    Given a BFD reloc type, return a howto structure.  */
    380 
    381 static reloc_howto_type *
    382 pru_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    383 				   bfd_reloc_code_real_type code)
    384 {
    385   unsigned int i;
    386 
    387   for (i = 0; i < ARRAY_SIZE (pru_reloc_map); ++i)
    388     if (pru_reloc_map[i].bfd_val == code)
    389       return lookup_howto ((unsigned int) pru_reloc_map[i].elf_val);
    390   return NULL;
    391 }
    392 
    393 /* Implement bfd_elf32_bfd_reloc_name_lookup:
    394    Given a reloc name, return a howto structure.  */
    395 
    396 static reloc_howto_type *
    397 pru_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    398 				   const char *r_name)
    399 {
    400   unsigned int i;
    401 
    402   for (i = 0; i < ARRAY_SIZE (elf_pru_howto_table_rel); i++)
    403     if (elf_pru_howto_table_rel[i].name
    404 	&& strcasecmp (elf_pru_howto_table_rel[i].name, r_name) == 0)
    405       return &elf_pru_howto_table_rel[i];
    406 
    407   return NULL;
    408 }
    409 
    410 /* Implement elf_info_to_howto:
    411    Given a ELF32 relocation, fill in a arelent structure.  */
    412 
    413 static bfd_boolean
    414 pru_elf32_info_to_howto (bfd *abfd, arelent *cache_ptr,
    415 			 Elf_Internal_Rela *dst)
    416 {
    417   unsigned int r_type;
    418 
    419   r_type = ELF32_R_TYPE (dst->r_info);
    420   if (r_type >= R_PRU_ILLEGAL)
    421     {
    422       /* xgettext:c-format */
    423       _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type);
    424       bfd_set_error (bfd_error_bad_value);
    425       return FALSE;
    426     }
    427 
    428   cache_ptr->howto = lookup_howto (r_type);
    429   return cache_ptr->howto != NULL;
    430 }
    431 
    432 /* Do the relocations that require special handling.  */
    433 /* Produce a word address for program memory.  Linker scripts will put .text
    434    at a high offset in order to differentiate it from .data.  So here we also
    435    mask the high bits of PMEM address.
    436 
    437    But why 1MB when internal Program Memory much smaller? We want to catch
    438    unintended overflows.
    439 
    440    Why not use (1<<31) as an offset and a mask? Sitara DDRAM usually resides
    441    there, and users might want to put some shared carveout memory region in
    442    their linker scripts.  So 0x80000000 might be a valid .data address.
    443 
    444    Note that we still keep and pass down the original howto.  This way we
    445    can reuse this function for several different relocations.  */
    446 static bfd_reloc_status_type
    447 pru_elf32_do_pmem_relocate (bfd *abfd, reloc_howto_type *howto,
    448 			    asection *input_section,
    449 			    bfd_byte *data, bfd_vma offset,
    450 			    bfd_vma symbol_value, bfd_vma addend)
    451 {
    452   symbol_value = symbol_value + addend;
    453   addend = 0;
    454   symbol_value &= 0x3fffff;
    455   return _bfd_final_link_relocate (howto, abfd, input_section,
    456 				   data, offset, symbol_value, addend);
    457 }
    458 
    459 /* Direct copy of _bfd_final_link_relocate, but with special
    460    "fill-in".  This copy-paste mumbo jumbo is only needed because BFD
    461    cannot deal correctly with non-contiguous bit fields.  */
    462 static bfd_reloc_status_type
    463 pru_elf32_do_s10_pcrel_relocate (bfd *input_bfd, reloc_howto_type *howto,
    464 				 asection *input_section,
    465 				 bfd_byte *contents, bfd_vma address,
    466 				 bfd_vma relocation, bfd_vma addend)
    467 {
    468   bfd_byte *location;
    469   bfd_vma x = 0;
    470   bfd_vma qboff;
    471   bfd_reloc_status_type flag = bfd_reloc_ok;
    472 
    473   /* Sanity check the address.  */
    474   if (address > bfd_get_section_limit (input_bfd, input_section))
    475     return bfd_reloc_outofrange;
    476 
    477   BFD_ASSERT (howto->pc_relative);
    478   BFD_ASSERT (howto->pcrel_offset);
    479 
    480   relocation = relocation + addend - (input_section->output_section->vma
    481 		+ input_section->output_offset) - address;
    482 
    483   location = contents + address;
    484 
    485   /* Get the value we are going to relocate.  */
    486   BFD_ASSERT (bfd_get_reloc_size (howto) == 4);
    487   x = bfd_get_32 (input_bfd, location);
    488 
    489   qboff = GET_BROFF_SIGNED (x) << howto->rightshift;
    490   relocation += qboff;
    491 
    492   BFD_ASSERT (howto->complain_on_overflow == complain_overflow_bitfield);
    493 
    494   if (relocation > 2047 && relocation < (bfd_vma)-2048l)
    495     flag = bfd_reloc_overflow;
    496 
    497   /* Check that target address is word-aligned.  */
    498   if (relocation & ((1 << howto->rightshift) - 1))
    499     flag = bfd_reloc_outofrange;
    500 
    501   relocation >>= (bfd_vma) howto->rightshift;
    502 
    503   /* Fill-in the RELOCATION to the right bits of X.  */
    504   SET_BROFF_URAW (x, relocation);
    505 
    506   bfd_put_32 (input_bfd, x, location);
    507 
    508   return flag;
    509 }
    510 
    511 static bfd_reloc_status_type
    512 pru_elf32_do_u8_pcrel_relocate (bfd *abfd, reloc_howto_type *howto,
    513 				asection *input_section,
    514 				bfd_byte *data, bfd_vma offset,
    515 				bfd_vma symbol_value, bfd_vma addend)
    516 {
    517   bfd_vma relocation;
    518 
    519   BFD_ASSERT (howto->pc_relative);
    520   BFD_ASSERT (howto->pcrel_offset);
    521 
    522   relocation = symbol_value + addend - (input_section->output_section->vma
    523 		+ input_section->output_offset) - offset;
    524   relocation >>= howto->rightshift;
    525 
    526   /* 0 and 1 are invalid target labels for LOOP.  We cannot
    527      encode this info in HOWTO, so catch such cases here.  */
    528   if (relocation < 2)
    529       return bfd_reloc_outofrange;
    530 
    531   return _bfd_final_link_relocate (howto, abfd, input_section,
    532 				   data, offset, symbol_value, addend);
    533 }
    534 
    535 /* Idea and code taken from elf32-d30v.  */
    536 static bfd_reloc_status_type
    537 pru_elf32_do_ldi32_relocate (bfd *abfd, reloc_howto_type *howto,
    538 			     asection *input_section,
    539 			     bfd_byte *data, bfd_vma offset,
    540 			     bfd_vma symbol_value, bfd_vma addend)
    541 {
    542   bfd_vma relocation;
    543   bfd_size_type octets = offset * OCTETS_PER_BYTE (abfd, input_section);
    544   bfd_byte *location;
    545   unsigned long in1, in2;
    546 
    547   /* A hacked-up version of _bfd_final_link_relocate() follows.  */
    548 
    549   /* Sanity check the address.  */
    550   if (octets + bfd_get_reloc_size (howto)
    551       > bfd_get_section_limit_octets (abfd, input_section))
    552     return bfd_reloc_outofrange;
    553 
    554   /* This function assumes that we are dealing with a basic relocation
    555      against a symbol.  We want to compute the value of the symbol to
    556      relocate to.  This is just VALUE, the value of the symbol, plus
    557      ADDEND, any addend associated with the reloc.  */
    558   relocation = symbol_value + addend;
    559 
    560   BFD_ASSERT (!howto->pc_relative);
    561 
    562   /* A hacked-up version of _bfd_relocate_contents() follows.  */
    563   location = data + octets;
    564 
    565   BFD_ASSERT (!howto->pc_relative);
    566 
    567   in1 = bfd_get_32 (abfd, location);
    568   in2 = bfd_get_32 (abfd, location + 4);
    569 
    570   SET_INSN_FIELD (IMM16, in1, relocation >> 16);
    571   SET_INSN_FIELD (IMM16, in2, relocation & 0xffff);
    572 
    573   bfd_put_32 (abfd, in1, location);
    574   bfd_put_32 (abfd, in2, location + 4);
    575 
    576   /* Old GAS and LD versions have a bug, where the two
    577      LDI instructions are swapped.  Detect such object
    578      files and bail.  */
    579   if (GET_INSN_FIELD (RDSEL, in1) != RSEL_31_16)
    580     {
    581       /* xgettext:c-format */
    582       _bfd_error_handler (_("error: %pB: old incompatible object file detected"),
    583 			  abfd);
    584       return bfd_reloc_notsupported;
    585     }
    586 
    587   return bfd_reloc_ok;
    588 }
    589 
    590 /* HOWTO handlers for relocations that require special handling.  */
    591 
    592 static bfd_reloc_status_type
    593 pru_elf32_pmem_relocate (bfd *abfd, arelent *reloc_entry,
    594 			 asymbol *symbol, void *data,
    595 			 asection *input_section, bfd *output_bfd,
    596 			 char **error_message)
    597 {
    598   /* If this is a relocatable link (output_bfd test tells us), just
    599      call the generic function.  Any adjustment will be done at final
    600      link time.  */
    601   if (output_bfd != NULL)
    602     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    603 				  input_section, output_bfd, error_message);
    604 
    605   BFD_ASSERT (0);
    606   return pru_elf32_do_pmem_relocate (abfd, reloc_entry->howto,
    607 				     input_section,
    608 				     data, reloc_entry->address,
    609 				     (symbol->value
    610 				      + symbol->section->output_section->vma
    611 				      + symbol->section->output_offset),
    612 				     reloc_entry->addend);
    613 }
    614 
    615 static bfd_reloc_status_type
    616 pru_elf32_s10_pcrel_relocate (bfd *abfd, arelent *reloc_entry,
    617 				 asymbol *symbol, void *data,
    618 				 asection *input_section, bfd *output_bfd,
    619 				 char **error_message)
    620 {
    621   /* If this is a relocatable link (output_bfd test tells us), just
    622      call the generic function.  Any adjustment will be done at final
    623      link time.  */
    624   if (output_bfd != NULL)
    625     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    626 				  input_section, output_bfd, error_message);
    627 
    628   return pru_elf32_do_s10_pcrel_relocate (abfd, reloc_entry->howto,
    629 					  input_section, data,
    630 					  reloc_entry->address,
    631 					  (symbol->value
    632 					   + symbol->section->output_section->vma
    633 					   + symbol->section->output_offset),
    634 					  reloc_entry->addend);
    635 }
    636 
    637 static bfd_reloc_status_type
    638 pru_elf32_u8_pcrel_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
    639 			     void *data, asection *input_section,
    640 			     bfd *output_bfd,
    641 			     char **error_message)
    642 {
    643   /* If this is a relocatable link (output_bfd test tells us), just
    644      call the generic function.  Any adjustment will be done at final
    645      link time.  */
    646   if (output_bfd != NULL)
    647     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    648 				  input_section, output_bfd, error_message);
    649 
    650   return pru_elf32_do_u8_pcrel_relocate (abfd, reloc_entry->howto,
    651 					 input_section,
    652 					 data, reloc_entry->address,
    653 					 (symbol->value
    654 					  + symbol->section->output_section->vma
    655 					  + symbol->section->output_offset),
    656 					 reloc_entry->addend);
    657 }
    658 
    659 static bfd_reloc_status_type
    660 pru_elf32_ldi32_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
    661 			  void *data, asection *input_section,
    662 			  bfd *output_bfd,
    663 			  char **error_message)
    664 {
    665   /* If this is a relocatable link (output_bfd test tells us), just
    666      call the generic function.  Any adjustment will be done at final
    667      link time.  */
    668   if (output_bfd != NULL)
    669     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    670 				  input_section, output_bfd, error_message);
    671 
    672   return pru_elf32_do_ldi32_relocate (abfd, reloc_entry->howto,
    673 				      input_section,
    674 				      data, reloc_entry->address,
    675 				      (symbol->value
    676 				       + symbol->section->output_section->vma
    677 				       + symbol->section->output_offset),
    678 				      reloc_entry->addend);
    679 }
    680 
    681 
    682 /* Implement elf_backend_relocate_section.  */
    683 static bfd_boolean
    684 pru_elf32_relocate_section (bfd *output_bfd,
    685 			    struct bfd_link_info *info,
    686 			    bfd *input_bfd,
    687 			    asection *input_section,
    688 			    bfd_byte *contents,
    689 			    Elf_Internal_Rela *relocs,
    690 			    Elf_Internal_Sym *local_syms,
    691 			    asection **local_sections)
    692 {
    693   struct bfd_elf_section_data * esd = elf_section_data (input_section);
    694   Elf_Internal_Shdr *symtab_hdr;
    695   struct elf_link_hash_entry **sym_hashes;
    696   Elf_Internal_Rela *rel;
    697   Elf_Internal_Rela *relend;
    698   bfd_boolean is_rel_reloc;
    699 
    700   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    701   sym_hashes = elf_sym_hashes (input_bfd);
    702   relend = relocs + input_section->reloc_count;
    703 
    704   /* See if we have a REL type relocation.  */
    705   is_rel_reloc = (esd->rel.hdr != NULL);
    706   /* Sanity check - only one type of relocation per section.
    707      FIXME: Theoretically it is possible to have both types,
    708      but if that happens how can we distinguish between the two ?  */
    709   BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr);
    710 
    711   for (rel = relocs; rel < relend; rel++)
    712     {
    713       reloc_howto_type *howto;
    714       unsigned long r_symndx;
    715       Elf_Internal_Sym *sym;
    716       asection *sec;
    717       struct elf_link_hash_entry *h;
    718       bfd_vma relocation;
    719       bfd_reloc_status_type r = bfd_reloc_ok;
    720       const char *name = NULL;
    721       const char* msg = (const char*) NULL;
    722       bfd_boolean unresolved_reloc;
    723       bfd_vma addend;
    724 
    725       /* If we are using a REL relocation then the addend should be empty.  */
    726       BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0);
    727 
    728       r_symndx = ELF32_R_SYM (rel->r_info);
    729 
    730       howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
    731       h = NULL;
    732       sym = NULL;
    733       sec = NULL;
    734 
    735       if (r_symndx < symtab_hdr->sh_info)
    736 	{
    737 	  sym = local_syms + r_symndx;
    738 	  sec = local_sections[r_symndx];
    739 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
    740 	}
    741       else
    742 	{
    743 	  bfd_boolean warned, ignored;
    744 
    745 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    746 				   r_symndx, symtab_hdr, sym_hashes,
    747 				   h, sec, relocation,
    748 				   unresolved_reloc, warned, ignored);
    749 	}
    750 
    751       if (sec && discarded_section (sec))
    752 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    753 					 rel, 1, relend, howto, 0, contents);
    754 
    755       /* Nothing more to do unless this is a final link.  */
    756       if (bfd_link_relocatable (info))
    757 	continue;
    758 
    759       if (howto)
    760 	{
    761 	  switch (howto->type)
    762 	    {
    763 	    case R_PRU_NONE:
    764 	      /* We don't need to find a value for this symbol.  It's just a
    765 		 marker.  */
    766 	      r = bfd_reloc_ok;
    767 	      break;
    768 
    769 	    case R_PRU_U16:
    770 	      if (is_rel_reloc)
    771 		{
    772 		  unsigned long insn;
    773 		  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
    774 		  addend = GET_INSN_FIELD (IMM16, insn);
    775 		}
    776 	      else
    777 		addend = rel->r_addend;
    778 	      r = _bfd_final_link_relocate (howto, input_bfd,
    779 					    input_section, contents,
    780 					    rel->r_offset, relocation,
    781 					    addend);
    782 	      break;
    783 
    784 	    case R_PRU_U16_PMEMIMM:
    785 	    case R_PRU_32_PMEM:
    786 	    case R_PRU_16_PMEM:
    787 	      if (is_rel_reloc && howto->type == R_PRU_U16_PMEMIMM)
    788 		{
    789 		  unsigned long insn;
    790 		  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
    791 		  addend = GET_INSN_FIELD (IMM16, insn) << 2;
    792 		}
    793 	      else if (is_rel_reloc && howto->type == R_PRU_32_PMEM)
    794 		{
    795 		  addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
    796 		  addend <<= 2;
    797 		}
    798 	      else if (is_rel_reloc && howto->type == R_PRU_16_PMEM)
    799 		{
    800 		  addend = bfd_get_16 (input_bfd, contents + rel->r_offset);
    801 		  addend <<= 2;
    802 		}
    803 	      else
    804 		{
    805 		  BFD_ASSERT (!is_rel_reloc);
    806 		  addend = rel->r_addend;
    807 		}
    808 	      r = pru_elf32_do_pmem_relocate (input_bfd, howto,
    809 						input_section,
    810 						contents, rel->r_offset,
    811 						relocation, addend);
    812 	      break;
    813 	    case R_PRU_S10_PCREL:
    814 	      BFD_ASSERT (! is_rel_reloc);
    815 	      r = pru_elf32_do_s10_pcrel_relocate (input_bfd, howto,
    816 						      input_section,
    817 						      contents,
    818 						      rel->r_offset,
    819 						      relocation,
    820 						      rel->r_addend);
    821 	      break;
    822 	    case R_PRU_U8_PCREL:
    823 	      BFD_ASSERT (! is_rel_reloc);
    824 	      r = pru_elf32_do_u8_pcrel_relocate (input_bfd, howto,
    825 						      input_section,
    826 						      contents,
    827 						      rel->r_offset,
    828 						      relocation,
    829 						      rel->r_addend);
    830 	      break;
    831 	    case R_PRU_LDI32:
    832 	      if (is_rel_reloc)
    833 		{
    834 		  unsigned long in1, in2;
    835 		  in1 = bfd_get_32 (input_bfd, contents + rel->r_offset);
    836 		  in2 = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
    837 		  addend = (GET_INSN_FIELD (IMM16, in1) << 16)
    838 			    | GET_INSN_FIELD (IMM16, in2);
    839 		}
    840 	      else
    841 		{
    842 		  addend = rel->r_addend;
    843 		}
    844 	      r = pru_elf32_do_ldi32_relocate (input_bfd, howto,
    845 					       input_section,
    846 					       contents,
    847 					       rel->r_offset,
    848 					       relocation,
    849 					       addend);
    850 	      break;
    851 	    case R_PRU_GNU_DIFF8:
    852 	    case R_PRU_GNU_DIFF16:
    853 	    case R_PRU_GNU_DIFF32:
    854 	    case R_PRU_GNU_DIFF16_PMEM:
    855 	    case R_PRU_GNU_DIFF32_PMEM:
    856 	      /* GNU extensions support only rela.  */
    857 	      BFD_ASSERT (! is_rel_reloc);
    858 	      /* Nothing to do here, as contents already contain the
    859 		 diff value.  */
    860 	      r = bfd_reloc_ok;
    861 	      break;
    862 
    863 	    case R_PRU_BFD_RELOC_16:
    864 	      if (is_rel_reloc)
    865 		addend = bfd_get_16 (input_bfd, contents + rel->r_offset);
    866 	      else
    867 		addend = rel->r_addend;
    868 	      r = _bfd_final_link_relocate (howto, input_bfd,
    869 					    input_section, contents,
    870 					    rel->r_offset, relocation,
    871 					    addend);
    872 	      break;
    873 
    874 	    case R_PRU_BFD_RELOC_32:
    875 	      if (is_rel_reloc)
    876 		addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
    877 	      else
    878 		addend = rel->r_addend;
    879 	      r = _bfd_final_link_relocate (howto, input_bfd,
    880 					    input_section, contents,
    881 					    rel->r_offset, relocation,
    882 					    addend);
    883 	      break;
    884 
    885 	    case R_PRU_GNU_BFD_RELOC_8:
    886 	      BFD_ASSERT (! is_rel_reloc);
    887 	      r = _bfd_final_link_relocate (howto, input_bfd,
    888 					    input_section, contents,
    889 					    rel->r_offset, relocation,
    890 					    rel->r_addend);
    891 	      break;
    892 
    893 	    default:
    894 	      BFD_ASSERT (0);
    895 	      break;
    896 	    }
    897 	}
    898       else
    899 	r = bfd_reloc_notsupported;
    900 
    901       if (r != bfd_reloc_ok)
    902 	{
    903 	  if (h != NULL)
    904 	    name = h->root.root.string;
    905 	  else
    906 	    {
    907 	      name = bfd_elf_string_from_elf_section (input_bfd,
    908 						      symtab_hdr->sh_link,
    909 						      sym->st_name);
    910 	      if (name == NULL || *name == '\0')
    911 		name = bfd_section_name (sec);
    912 	    }
    913 
    914 	  switch (r)
    915 	    {
    916 	    case bfd_reloc_overflow:
    917 	      (*info->callbacks->reloc_overflow) (info, NULL, name,
    918 						  howto->name, (bfd_vma) 0,
    919 						  input_bfd, input_section,
    920 						  rel->r_offset);
    921 	      break;
    922 
    923 	    case bfd_reloc_undefined:
    924 	      (*info->callbacks->undefined_symbol) (info, name, input_bfd,
    925 						    input_section,
    926 						    rel->r_offset, TRUE);
    927 	      break;
    928 
    929 	    case bfd_reloc_outofrange:
    930 	      if (msg == NULL)
    931 		msg = _("relocation out of range");
    932 	      break;
    933 
    934 	    case bfd_reloc_notsupported:
    935 	      if (msg == NULL)
    936 		msg = _("unsupported relocation");
    937 	      break;
    938 
    939 	    case bfd_reloc_dangerous:
    940 	      if (msg == NULL)
    941 		msg = _("dangerous relocation");
    942 	      break;
    943 
    944 	    default:
    945 	      if (msg == NULL)
    946 		msg = _("unknown error");
    947 	      break;
    948 	    }
    949 
    950 	  if (msg)
    951 	    {
    952 	      (*info->callbacks->warning) (info, msg, name, input_bfd,
    953 					   input_section, rel->r_offset);
    954 	      return FALSE;
    955 	    }
    956 	}
    957     }
    958   return TRUE;
    959 }
    960 
    961 
    962 /* Perform a diff relocation.  Nothing to do, as the difference value is
    964    already written into the section's contents.  */
    965 
    966 static bfd_reloc_status_type
    967 bfd_elf_pru_diff_relocate (bfd *abfd ATTRIBUTE_UNUSED,
    968 			   arelent *reloc_entry ATTRIBUTE_UNUSED,
    969 			   asymbol *symbol ATTRIBUTE_UNUSED,
    970 			   void *data ATTRIBUTE_UNUSED,
    971 			   asection *input_section ATTRIBUTE_UNUSED,
    972 			   bfd *output_bfd ATTRIBUTE_UNUSED,
    973 			   char **error_message ATTRIBUTE_UNUSED)
    974 {
    975   return bfd_reloc_ok;
    976 }
    977 
    978 
    979 /* Returns whether the relocation type passed is a diff reloc.  */
    980 
    981 static bfd_boolean
    982 elf32_pru_is_diff_reloc (Elf_Internal_Rela *irel)
    983 {
    984   return (ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF8
    985 	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF16
    986 	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF32
    987 	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF16_PMEM
    988 	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF32_PMEM);
    989 }
    990 
    991 /* Reduce the diff value written in the section by count if the shrinked
    992    insn address happens to fall between the two symbols for which this
    993    diff reloc was emitted.  */
    994 
    995 static void
    996 elf32_pru_adjust_diff_reloc_value (bfd *abfd,
    997 				   struct bfd_section *isec,
    998 				   Elf_Internal_Rela *irel,
    999 				   bfd_vma symval,
   1000 				   bfd_vma shrinked_insn_address,
   1001 				   int count)
   1002 {
   1003   unsigned char *reloc_contents = NULL;
   1004   unsigned char *isec_contents = elf_section_data (isec)->this_hdr.contents;
   1005   if (isec_contents == NULL)
   1006   {
   1007     if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents))
   1008       return;
   1009 
   1010     elf_section_data (isec)->this_hdr.contents = isec_contents;
   1011   }
   1012 
   1013   reloc_contents = isec_contents + irel->r_offset;
   1014 
   1015   /* Read value written in object file.  */
   1016   bfd_signed_vma x = 0;
   1017   switch (ELF32_R_TYPE (irel->r_info))
   1018   {
   1019   case R_PRU_GNU_DIFF8:
   1020     {
   1021       x = bfd_get_signed_8 (abfd, reloc_contents);
   1022       break;
   1023     }
   1024   case R_PRU_GNU_DIFF16:
   1025     {
   1026       x = bfd_get_signed_16 (abfd, reloc_contents);
   1027       break;
   1028     }
   1029   case R_PRU_GNU_DIFF32:
   1030     {
   1031       x = bfd_get_signed_32 (abfd, reloc_contents);
   1032       break;
   1033     }
   1034   case R_PRU_GNU_DIFF16_PMEM:
   1035     {
   1036       x = bfd_get_signed_16 (abfd, reloc_contents) * 4;
   1037       break;
   1038     }
   1039   case R_PRU_GNU_DIFF32_PMEM:
   1040     {
   1041       x = bfd_get_signed_32 (abfd, reloc_contents) * 4;
   1042       break;
   1043     }
   1044   default:
   1045     {
   1046       BFD_FAIL ();
   1047     }
   1048   }
   1049 
   1050   /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written
   1051      into the object file at the reloc offset.  sym2's logical value is
   1052      symval (<start_of_section>) + reloc addend.  Compute the start and end
   1053      addresses and check if the shrinked insn falls between sym1 and sym2.  */
   1054 
   1055   bfd_vma end_address = symval + irel->r_addend;
   1056   bfd_vma start_address = end_address - x;
   1057 
   1058   /* Shrink the absolute DIFF value (get the to labels "closer"
   1059      together), because we have removed data between labels.  */
   1060   if (x < 0)
   1061     {
   1062       x += count;
   1063       /* In case the signed x is negative, restore order.  */
   1064       SWAP_VALS (end_address, start_address);
   1065     }
   1066   else
   1067     {
   1068       x -= count;
   1069     }
   1070 
   1071   /* Reduce the diff value by count bytes and write it back into section
   1072     contents.  */
   1073 
   1074   if (shrinked_insn_address >= start_address
   1075       && shrinked_insn_address <= end_address)
   1076   {
   1077     switch (ELF32_R_TYPE (irel->r_info))
   1078     {
   1079     case R_PRU_GNU_DIFF8:
   1080       {
   1081 	bfd_put_signed_8 (abfd, x & 0xFF, reloc_contents);
   1082 	break;
   1083       }
   1084     case R_PRU_GNU_DIFF16:
   1085       {
   1086 	bfd_put_signed_16 (abfd, x & 0xFFFF, reloc_contents);
   1087 	break;
   1088       }
   1089     case R_PRU_GNU_DIFF32:
   1090       {
   1091 	bfd_put_signed_32 (abfd, x & 0xFFFFFFFF, reloc_contents);
   1092 	break;
   1093       }
   1094     case R_PRU_GNU_DIFF16_PMEM:
   1095       {
   1096 	bfd_put_signed_16 (abfd, (x / 4) & 0xFFFF, reloc_contents);
   1097 	break;
   1098       }
   1099     case R_PRU_GNU_DIFF32_PMEM:
   1100       {
   1101 	bfd_put_signed_32 (abfd, (x / 4) & 0xFFFFFFFF, reloc_contents);
   1102 	break;
   1103       }
   1104     default:
   1105       {
   1106 	BFD_FAIL ();
   1107       }
   1108     }
   1109 
   1110   }
   1111 }
   1112 
   1113 /* Delete some bytes from a section while changing the size of an instruction.
   1114    The parameter "addr" denotes the section-relative offset pointing just
   1115    behind the shrinked instruction. "addr+count" point at the first
   1116    byte just behind the original unshrinked instruction.
   1117 
   1118    Idea copied from the AVR port.  */
   1119 
   1120 static bfd_boolean
   1121 pru_elf_relax_delete_bytes (bfd *abfd,
   1122 			    asection *sec,
   1123 			    bfd_vma addr,
   1124 			    int count)
   1125 {
   1126   Elf_Internal_Shdr *symtab_hdr;
   1127   unsigned int sec_shndx;
   1128   bfd_byte *contents;
   1129   Elf_Internal_Rela *irel, *irelend;
   1130   Elf_Internal_Sym *isym;
   1131   Elf_Internal_Sym *isymbuf = NULL;
   1132   bfd_vma toaddr;
   1133   struct elf_link_hash_entry **sym_hashes;
   1134   struct elf_link_hash_entry **end_hashes;
   1135   unsigned int symcount;
   1136 
   1137   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1138   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   1139   contents = elf_section_data (sec)->this_hdr.contents;
   1140 
   1141   toaddr = sec->size;
   1142 
   1143   irel = elf_section_data (sec)->relocs;
   1144   irelend = irel + sec->reloc_count;
   1145 
   1146   /* Actually delete the bytes.  */
   1147   if (toaddr - addr - count > 0)
   1148     memmove (contents + addr, contents + addr + count,
   1149 	     (size_t) (toaddr - addr - count));
   1150   sec->size -= count;
   1151 
   1152   /* Adjust all the reloc addresses.  */
   1153   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
   1154     {
   1155       bfd_vma old_reloc_address;
   1156 
   1157       old_reloc_address = (sec->output_section->vma
   1158 			   + sec->output_offset + irel->r_offset);
   1159 
   1160       /* Get the new reloc address.  */
   1161       if ((irel->r_offset > addr
   1162 	   && irel->r_offset < toaddr))
   1163 	{
   1164 	  if (debug_relax)
   1165 	    printf ("Relocation at address 0x%x needs to be moved.\n"
   1166 		    "Old section offset: 0x%x, New section offset: 0x%x \n",
   1167 		    (unsigned int) old_reloc_address,
   1168 		    (unsigned int) irel->r_offset,
   1169 		    (unsigned int) ((irel->r_offset) - count));
   1170 
   1171 	  irel->r_offset -= count;
   1172 	}
   1173 
   1174     }
   1175 
   1176    /* The reloc's own addresses are now ok.  However, we need to readjust
   1177       the reloc's addend, i.e. the reloc's value if two conditions are met:
   1178       1.) the reloc is relative to a symbol in this section that
   1179 	  is located in front of the shrinked instruction
   1180       2.) symbol plus addend end up behind the shrinked instruction.
   1181 
   1182       The most common case where this happens are relocs relative to
   1183       the section-start symbol.
   1184 
   1185       This step needs to be done for all of the sections of the bfd.  */
   1186 
   1187   {
   1188     struct bfd_section *isec;
   1189 
   1190     for (isec = abfd->sections; isec; isec = isec->next)
   1191      {
   1192        bfd_vma symval;
   1193        bfd_vma shrinked_insn_address;
   1194 
   1195        if (isec->reloc_count == 0)
   1196 	 continue;
   1197 
   1198        shrinked_insn_address = (sec->output_section->vma
   1199 				+ sec->output_offset + addr);
   1200 
   1201        irel = elf_section_data (isec)->relocs;
   1202        /* PR 12161: Read in the relocs for this section if necessary.  */
   1203        if (irel == NULL)
   1204 	 irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);
   1205 
   1206        for (irelend = irel + isec->reloc_count;
   1207 	    irel < irelend;
   1208 	    irel++)
   1209 	 {
   1210 	   /* Read this BFD's local symbols if we haven't done
   1211 	      so already.  */
   1212 	   if (isymbuf == NULL && symtab_hdr->sh_info != 0)
   1213 	     {
   1214 	       isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1215 	       if (isymbuf == NULL)
   1216 		 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
   1217 						 symtab_hdr->sh_info, 0,
   1218 						 NULL, NULL, NULL);
   1219 	       if (isymbuf == NULL)
   1220 		 return FALSE;
   1221 	     }
   1222 
   1223 	   /* Get the value of the symbol referred to by the reloc.  */
   1224 	   if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
   1225 	     {
   1226 	       /* A local symbol.  */
   1227 	       asection *sym_sec;
   1228 
   1229 	       isym = isymbuf + ELF32_R_SYM (irel->r_info);
   1230 	       sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
   1231 	       symval = isym->st_value;
   1232 	       /* If the reloc is absolute, it will not have
   1233 		  a symbol or section associated with it.  */
   1234 	       if (sym_sec == sec)
   1235 		 {
   1236 		   symval += sym_sec->output_section->vma
   1237 		     + sym_sec->output_offset;
   1238 
   1239 		   if (debug_relax)
   1240 		     printf ("Checking if the relocation's "
   1241 			     "addend needs corrections.\n"
   1242 			     "Address of anchor symbol: 0x%x \n"
   1243 			     "Address of relocation target: 0x%x \n"
   1244 			     "Address of relaxed insn: 0x%x \n",
   1245 			     (unsigned int) symval,
   1246 			     (unsigned int) (symval + irel->r_addend),
   1247 			     (unsigned int) shrinked_insn_address);
   1248 
   1249 		   /* Shrink the special DIFF relocations.  */
   1250 		   if (elf32_pru_is_diff_reloc (irel))
   1251 		     {
   1252 		       elf32_pru_adjust_diff_reloc_value (abfd, isec, irel,
   1253 							  symval,
   1254 							  shrinked_insn_address,
   1255 							  count);
   1256 		     }
   1257 
   1258 		   /* Fix the addend, if it is affected.  */
   1259 		   if (symval <= shrinked_insn_address
   1260 		       && (symval + irel->r_addend) > shrinked_insn_address)
   1261 		     {
   1262 
   1263 		       irel->r_addend -= count;
   1264 
   1265 		       if (debug_relax)
   1266 			 printf ("Relocation's addend needed to be fixed \n");
   1267 		     }
   1268 		 }
   1269 	       /* else...Reference symbol is absolute.
   1270 		  No adjustment needed.  */
   1271 	     }
   1272 	   /* else...Reference symbol is extern.  No need for adjusting
   1273 	      the addend.  */
   1274 	 }
   1275      }
   1276   }
   1277 
   1278   /* Adjust the local symbols defined in this section.  */
   1279   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
   1280   /* Fix PR 9841, there may be no local symbols.  */
   1281   if (isym != NULL)
   1282     {
   1283       Elf_Internal_Sym *isymend;
   1284 
   1285       isymend = isym + symtab_hdr->sh_info;
   1286       for (; isym < isymend; isym++)
   1287 	{
   1288 	  if (isym->st_shndx == sec_shndx)
   1289 	    {
   1290 	      if (isym->st_value > addr
   1291 		  && isym->st_value <= toaddr)
   1292 		isym->st_value -= count;
   1293 
   1294 	      if (isym->st_value <= addr
   1295 		  && isym->st_value + isym->st_size > addr)
   1296 		{
   1297 		  /* If this assert fires then we have a symbol that ends
   1298 		     part way through an instruction.  Does that make
   1299 		     sense?  */
   1300 		  BFD_ASSERT (isym->st_value + isym->st_size >= addr + count);
   1301 		  isym->st_size -= count;
   1302 		}
   1303 	    }
   1304 	}
   1305     }
   1306 
   1307   /* Now adjust the global symbols defined in this section.  */
   1308   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
   1309 	      - symtab_hdr->sh_info);
   1310   sym_hashes = elf_sym_hashes (abfd);
   1311   end_hashes = sym_hashes + symcount;
   1312   for (; sym_hashes < end_hashes; sym_hashes++)
   1313     {
   1314       struct elf_link_hash_entry *sym_hash = *sym_hashes;
   1315       if ((sym_hash->root.type == bfd_link_hash_defined
   1316 	   || sym_hash->root.type == bfd_link_hash_defweak)
   1317 	  && sym_hash->root.u.def.section == sec)
   1318 	{
   1319 	  if (sym_hash->root.u.def.value > addr
   1320 	      && sym_hash->root.u.def.value <= toaddr)
   1321 	    sym_hash->root.u.def.value -= count;
   1322 
   1323 	  if (sym_hash->root.u.def.value <= addr
   1324 	      && (sym_hash->root.u.def.value + sym_hash->size > addr))
   1325 	    {
   1326 	      /* If this assert fires then we have a symbol that ends
   1327 		 part way through an instruction.  Does that make
   1328 		 sense?  */
   1329 	      BFD_ASSERT (sym_hash->root.u.def.value + sym_hash->size
   1330 			  >= addr + count);
   1331 	      sym_hash->size -= count;
   1332 	    }
   1333 	}
   1334     }
   1335 
   1336   return TRUE;
   1337 }
   1338 
   1339 static bfd_boolean
   1340 pru_elf32_relax_section (bfd * abfd, asection * sec,
   1341 			  struct bfd_link_info * link_info,
   1342 			  bfd_boolean * again)
   1343 {
   1344   Elf_Internal_Shdr * symtab_hdr;
   1345   Elf_Internal_Rela * internal_relocs;
   1346   Elf_Internal_Rela * irel;
   1347   Elf_Internal_Rela * irelend;
   1348   bfd_byte *	      contents = NULL;
   1349   Elf_Internal_Sym *  isymbuf = NULL;
   1350 
   1351   /* Assume nothing changes.  */
   1352   *again = FALSE;
   1353 
   1354   /* We don't have to do anything for a relocatable link, if
   1355      this section does not have relocs, or if this is not a
   1356      code section.  */
   1357   if (bfd_link_relocatable (link_info)
   1358     || (sec->flags & SEC_RELOC) == 0
   1359     || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
   1360     return TRUE;
   1361 
   1362   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
   1363 
   1364   /* Get a copy of the native relocations.  */
   1365   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
   1366 					       link_info->keep_memory);
   1367   if (internal_relocs == NULL)
   1368     goto error_return;
   1369 
   1370   /* Walk through them looking for relaxing opportunities.  */
   1371   irelend = internal_relocs + sec->reloc_count;
   1372 
   1373   for (irel = internal_relocs; irel < irelend; irel++)
   1374     {
   1375       bfd_vma symval;
   1376 
   1377       /* Get the section contents if we haven't done so already.  */
   1378       if (contents == NULL)
   1379 	{
   1380 	  /* Get cached copy if it exists.  */
   1381 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
   1382 	    contents = elf_section_data (sec)->this_hdr.contents;
   1383 	  else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
   1384 	    goto error_return;
   1385 	}
   1386 
   1387       /* Read this BFD's local symbols if we haven't done so already.  */
   1388       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
   1389 	{
   1390 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1391 	  if (isymbuf == NULL)
   1392 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
   1393 					    symtab_hdr->sh_info, 0,
   1394 					    NULL, NULL, NULL);
   1395 	  if (isymbuf == NULL)
   1396 	    goto error_return;
   1397 	}
   1398 
   1399       /* Get the value of the symbol referred to by the reloc.  */
   1400       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
   1401 	{
   1402 	  /* A local symbol.  */
   1403 	  Elf_Internal_Sym *isym;
   1404 	  asection *sym_sec;
   1405 
   1406 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
   1407 	  if (isym->st_shndx == SHN_UNDEF)
   1408 	    sym_sec = bfd_und_section_ptr;
   1409 	  else if (isym->st_shndx == SHN_ABS)
   1410 	    sym_sec = bfd_abs_section_ptr;
   1411 	  else if (isym->st_shndx == SHN_COMMON)
   1412 	    sym_sec = bfd_com_section_ptr;
   1413 	  else
   1414 	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
   1415 	  symval = (isym->st_value
   1416 		    + sym_sec->output_section->vma + sym_sec->output_offset);
   1417 	}
   1418       else
   1419 	{
   1420 	  unsigned long indx;
   1421 	  struct elf_link_hash_entry *h;
   1422 
   1423 	  /* An external symbol.  */
   1424 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
   1425 	  h = elf_sym_hashes (abfd)[indx];
   1426 	  BFD_ASSERT (h != NULL);
   1427 
   1428 	  if (h->root.type != bfd_link_hash_defined
   1429 	      && h->root.type != bfd_link_hash_defweak)
   1430 	    /* This appears to be a reference to an undefined
   1431 	       symbol.  Just ignore it--it will be caught by the
   1432 	       regular reloc processing.  */
   1433 	    continue;
   1434 
   1435 	  symval = (h->root.u.def.value
   1436 		    + h->root.u.def.section->output_section->vma
   1437 		    + h->root.u.def.section->output_offset);
   1438 	}
   1439 
   1440       /* For simplicity of coding, we are going to modify the section
   1441 	 contents, the section relocs, and the BFD symbol table.  We
   1442 	 must tell the rest of the code not to free up this
   1443 	 information.  It would be possible to instead create a table
   1444 	 of changes which have to be made, as is done in coff-mips.c;
   1445 	 that would be more work, but would require less memory when
   1446 	 the linker is run.  */
   1447 
   1448       /* Check if we can remove an LDI instruction from the LDI32
   1449 	 pseudo instruction if the upper 16 operand bits are zero.  */
   1450       if (ELF32_R_TYPE (irel->r_info) == (int) R_PRU_LDI32)
   1451 	{
   1452 	  bfd_vma value = symval + irel->r_addend;
   1453 
   1454 	  if (debug_relax)
   1455 	    printf ("R_PRU_LDI32 with value=0x%lx\n", (long) value);
   1456 
   1457 	  if ((long) value >> 16 == 0)
   1458 	    {
   1459 	      unsigned long insn;
   1460 
   1461 	      /* Note that we've changed the relocs, section contents.  */
   1462 	      elf_section_data (sec)->relocs = internal_relocs;
   1463 	      elf_section_data (sec)->this_hdr.contents = contents;
   1464 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1465 
   1466 	      /* Make the second instruction load the 16-bit constant
   1467 		 into the full 32-bit register.  */
   1468 	      insn = bfd_get_32 (abfd, contents + irel->r_offset + 4);
   1469 
   1470 	      /* Old GAS and LD versions have a bug, where the two
   1471 		 LDI instructions are swapped.  Detect such object
   1472 		 files and bail.  */
   1473 	      if (GET_INSN_FIELD (RDSEL, insn) != RSEL_15_0)
   1474 		{
   1475 		  /* xgettext:c-format */
   1476 		  _bfd_error_handler (_("error: %pB: old incompatible object file detected"),
   1477 				      abfd);
   1478 		  goto error_return;
   1479 		}
   1480 
   1481 	      SET_INSN_FIELD (RDSEL, insn, RSEL_31_0);
   1482 	      bfd_put_32 (abfd, insn, contents + irel->r_offset + 4);
   1483 
   1484 	      /* Delete the first LDI instruction.  Note that there should
   1485 		 be no relocations or symbols pointing to the second LDI
   1486 		 instruction.  */
   1487 	      if (!pru_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 4))
   1488 		goto error_return;
   1489 
   1490 	      /* We're done with deletion of the first instruction.
   1491 		 Set a regular LDI relocation for the second instruction
   1492 		 we left to load the 16-bit value into the 32-bit
   1493 		 register.  */
   1494 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1495 					   R_PRU_U16);
   1496 
   1497 	      /* That will change things, so, we should relax again.
   1498 		 Note that this is not required, and it may be slow.  */
   1499 	      *again = TRUE;
   1500 	    }
   1501 	}
   1502     }
   1503 
   1504   if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
   1505     {
   1506       if (!link_info->keep_memory)
   1507 	free (isymbuf);
   1508       else
   1509 	{
   1510 	  /* Cache the symbols for elf_link_input_bfd.  */
   1511 	  symtab_hdr->contents = (unsigned char *) isymbuf;
   1512 	}
   1513     }
   1514 
   1515   if (contents != NULL
   1516       && elf_section_data (sec)->this_hdr.contents != contents)
   1517     {
   1518       if (!link_info->keep_memory)
   1519 	free (contents);
   1520       else
   1521 	{
   1522 	  /* Cache the section contents for elf_link_input_bfd.  */
   1523 	  elf_section_data (sec)->this_hdr.contents = contents;
   1524 	}
   1525     }
   1526 
   1527   if (elf_section_data (sec)->relocs != internal_relocs)
   1528     free (internal_relocs);
   1529 
   1530   return TRUE;
   1531 
   1532  error_return:
   1533   if (symtab_hdr->contents != (unsigned char *) isymbuf)
   1534     free (isymbuf);
   1535   if (elf_section_data (sec)->this_hdr.contents != contents)
   1536     free (contents);
   1537   if (elf_section_data (sec)->relocs != internal_relocs)
   1538     free (internal_relocs);
   1539 
   1540   return FALSE;
   1541 }
   1542 
   1543 /* Free the derived linker hash table.  */
   1544 static void
   1545 pru_elf32_link_hash_table_free (bfd *obfd)
   1546 {
   1547   _bfd_elf_link_hash_table_free (obfd);
   1548 }
   1549 
   1550 /* Implement bfd_elf32_bfd_link_hash_table_create.  */
   1551 static struct bfd_link_hash_table *
   1552 pru_elf32_link_hash_table_create (bfd *abfd)
   1553 {
   1554   struct elf_link_hash_table *ret;
   1555   size_t amt = sizeof (struct elf_link_hash_table);
   1556 
   1557   ret = bfd_zmalloc (amt);
   1558   if (ret == NULL)
   1559     return NULL;
   1560 
   1561   if (!_bfd_elf_link_hash_table_init (ret, abfd,
   1562 				      link_hash_newfunc,
   1563 				      sizeof (struct
   1564 					      elf_link_hash_entry),
   1565 				      PRU_ELF_DATA))
   1566     {
   1567       free (ret);
   1568       return NULL;
   1569     }
   1570 
   1571   ret->root.hash_table_free = pru_elf32_link_hash_table_free;
   1572 
   1573   return &ret->root;
   1574 }
   1575 
   1576 #define ELF_ARCH			bfd_arch_pru
   1577 #define ELF_TARGET_ID			PRU_ELF_DATA
   1578 #define ELF_MACHINE_CODE		EM_TI_PRU
   1579 
   1580 #define ELF_MAXPAGESIZE			1
   1581 
   1582 #define bfd_elf32_bfd_link_hash_table_create \
   1583 					  pru_elf32_link_hash_table_create
   1584 
   1585 /* Relocation table lookup macros.  */
   1586 
   1587 #define bfd_elf32_bfd_reloc_type_lookup	  pru_elf32_bfd_reloc_type_lookup
   1588 #define bfd_elf32_bfd_reloc_name_lookup	  pru_elf32_bfd_reloc_name_lookup
   1589 
   1590 #define elf_info_to_howto		pru_elf32_info_to_howto
   1591 #define elf_info_to_howto_rel		NULL
   1592 
   1593 /* elf backend functions.  */
   1594 
   1595 /* TI folks like to use a mix of REL and RELA relocations.  See also
   1596    the MSP430 and TI C6X backends.  */
   1597 #define elf_backend_may_use_rel_p  1
   1598 #define elf_backend_may_use_rela_p 1
   1599 #define elf_backend_default_use_rela_p 1
   1600 
   1601 #define elf_backend_rela_normal		1
   1602 
   1603 #define elf_backend_relocate_section	pru_elf32_relocate_section
   1604 #define bfd_elf32_bfd_relax_section	pru_elf32_relax_section
   1605 
   1606 #define TARGET_LITTLE_SYM		pru_elf32_vec
   1607 #define TARGET_LITTLE_NAME		"elf32-pru"
   1608 
   1609 #include "elf32-target.h"
   1610