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