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