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