Update my e-mail address.
[binutils-gdb.git] / bfd / elf32-pru.c
blob71a0829d2008a97a80048ba4d265ab28e821c395
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
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
23 /* This file handles TI PRU ELF targets. */
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"
34 #define SWAP_VALS(A,B) \
35 do { \
36 (A) ^= (B); \
37 (B) ^= (A); \
38 (A) ^= (B); \
39 } while (0)
41 /* Enable debugging printout at stdout with this variable. */
42 static bfd_boolean debug_relax = FALSE;
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 **);
56 /* Target vector. */
57 extern const bfd_target pru_elf32_vec;
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 */
76 HOWTO (R_PRU_16_PMEM,
78 1, /* short */
79 32,
80 FALSE,
82 complain_overflow_dont,
83 bfd_elf_generic_reloc,
84 "R_PRU_16_PMEM",
85 FALSE,
86 0, /* src_mask */
87 0xffff,
88 FALSE),
90 HOWTO (R_PRU_U16_PMEMIMM,
93 32,
94 FALSE,
96 complain_overflow_unsigned,
97 pru_elf32_pmem_relocate,
98 "R_PRU_U16_PMEMIMM",
99 FALSE,
100 0, /* src_mask */
101 0x00ffff00,
102 FALSE),
104 HOWTO (R_PRU_BFD_RELOC_16,
106 1, /* short */
108 FALSE,
110 complain_overflow_bitfield,
111 bfd_elf_generic_reloc,
112 "R_PRU_BFD_RELOC16",
113 FALSE,
114 0, /* src_mask */
115 0x0000ffff,
116 FALSE),
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 */
133 HOWTO (R_PRU_32_PMEM,
135 2, /* long */
137 FALSE,
139 complain_overflow_dont,
140 pru_elf32_pmem_relocate,
141 "R_PRU_32_PMEM",
142 FALSE,
143 0, /* src_mask */
144 0xffffffff,
145 FALSE),
147 HOWTO (R_PRU_BFD_RELOC_32,
149 2, /* long */
151 FALSE,
153 complain_overflow_dont,
154 bfd_elf_generic_reloc,
155 "R_PRU_BFD_RELOC32",
156 FALSE,
157 0, /* src_mask */
158 0xffffffff,
159 FALSE),
161 HOWTO (R_PRU_S10_PCREL,
165 TRUE,
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),
175 HOWTO (R_PRU_U8_PCREL,
179 TRUE,
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),
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 */
203 /* GNU-specific relocations. */
204 HOWTO (R_PRU_GNU_BFD_RELOC_8,
206 0, /* byte */
208 FALSE,
210 complain_overflow_bitfield,
211 bfd_elf_generic_reloc,
212 "R_PRU_BFD_RELOC8",
213 FALSE,
214 0, /* src_mask */
215 0x000000ff,
216 FALSE),
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 */
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 */
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 */
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 */
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 */
288 /* Add other relocations here. */
291 static unsigned char elf_code_to_howto_index[R_PRU_ILLEGAL + 1];
293 /* Return the howto for relocation RTYPE. */
294 static reloc_howto_type *
295 lookup_howto (unsigned int rtype)
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]));
302 if (!initialized)
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;
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;
318 /* Map for converting BFD reloc types to PRU reloc types. */
319 struct elf_reloc_map
321 bfd_reloc_code_real_type bfd_val;
322 enum elf_pru_reloc_type elf_val;
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},
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},
346 /* Assorted hash table functions. */
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)
353 /* Allocate the structure if it has not already been allocated by a
354 subclass. */
355 if (entry == NULL)
357 entry = bfd_hash_allocate (table,
358 sizeof (struct elf_link_hash_entry));
359 if (entry == NULL)
360 return entry;
363 /* Call the allocation method of the superclass. */
364 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
366 return entry;
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)
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;
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)
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];
399 return NULL;
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)
408 unsigned int r_type;
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);
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.
420 But why 1MB when internal Program Memory much smaller? We want to catch
421 unintended overflows.
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.
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)
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);
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)
451 bfd_byte *location;
452 bfd_vma x = 0;
453 bfd_vma qboff;
454 bfd_reloc_status_type flag = bfd_reloc_ok;
456 /* Sanity check the address. */
457 if (address > bfd_get_section_limit (input_bfd, input_section))
458 return bfd_reloc_outofrange;
460 BFD_ASSERT (howto->pc_relative);
461 BFD_ASSERT (howto->pcrel_offset);
463 relocation = relocation + addend - (input_section->output_section->vma
464 + input_section->output_offset) - address;
466 location = contents + address;
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);
472 qboff = GET_BROFF_SIGNED (x) << howto->rightshift;
473 relocation += qboff;
475 BFD_ASSERT (howto->complain_on_overflow == complain_overflow_bitfield);
477 if (relocation > 2047 && relocation < (bfd_vma)-2048l)
478 flag = bfd_reloc_overflow;
480 /* Check that target address is word-aligned. */
481 if (relocation & ((1 << howto->rightshift) - 1))
482 flag = bfd_reloc_outofrange;
484 relocation >>= (bfd_vma) howto->rightshift;
486 /* Fill-in the RELOCATION to the right bits of X. */
487 SET_BROFF_URAW (x, relocation);
489 bfd_put_32 (input_bfd, x, location);
491 return flag;
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)
500 bfd_vma relocation;
502 BFD_ASSERT (howto->pc_relative);
503 BFD_ASSERT (howto->pcrel_offset);
505 relocation = symbol_value + addend - (input_section->output_section->vma
506 + input_section->output_offset) - offset;
507 relocation >>= howto->rightshift;
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;
514 return _bfd_final_link_relocate (howto, abfd, input_section,
515 data, offset, symbol_value, addend);
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)
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;
530 /* A hacked-up version of _bfd_final_link_relocate() follows. */
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;
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;
543 BFD_ASSERT (!howto->pc_relative);
545 /* A hacked-up version of _bfd_relocate_contents() follows. */
546 location = data + offset * bfd_octets_per_byte (abfd);
548 BFD_ASSERT (!howto->pc_relative);
550 in1 = bfd_get_32 (abfd, location);
551 in2 = bfd_get_32 (abfd, location + 4);
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);
557 relocation += num;
559 SET_INSN_FIELD (IMM16, in1, relocation & 0xffff);
560 SET_INSN_FIELD (IMM16, in2, relocation >> 16);
562 bfd_put_32 (abfd, in1, location);
563 bfd_put_32 (abfd, in2, location + 4);
565 return bfd_reloc_ok;
568 /* HOWTO handlers for relocations that require special handling. */
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)
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);
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);
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)
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);
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);
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)
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);
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);
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)
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);
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);
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)
670 Elf_Internal_Shdr *symtab_hdr;
671 struct elf_link_hash_entry **sym_hashes;
672 Elf_Internal_Rela *rel;
673 Elf_Internal_Rela *relend;
675 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
676 sym_hashes = elf_sym_hashes (input_bfd);
677 relend = relocs + input_section->reloc_count;
679 for (rel = relocs; rel < relend; rel++)
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;
692 r_symndx = ELF32_R_SYM (rel->r_info);
694 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
695 h = NULL;
696 sym = NULL;
697 sec = NULL;
699 if (r_symndx < symtab_hdr->sh_info)
701 sym = local_syms + r_symndx;
702 sec = local_sections[r_symndx];
703 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
705 else
707 bfd_boolean warned, ignored;
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);
715 if (sec && discarded_section (sec))
716 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
717 rel, 1, relend, howto, 0, contents);
719 /* Nothing more to do unless this is a final link. */
720 if (bfd_link_relocatable (info))
721 continue;
723 if (howto)
725 switch (howto->type)
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;
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;
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;
783 else
784 r = bfd_reloc_notsupported;
786 if (r != bfd_reloc_ok)
788 if (h != NULL)
789 name = h->root.root.string;
790 else
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);
799 switch (r)
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;
808 case bfd_reloc_undefined:
809 (*info->callbacks->undefined_symbol) (info, name, input_bfd,
810 input_section,
811 rel->r_offset, TRUE);
812 break;
814 case bfd_reloc_outofrange:
815 if (msg == NULL)
816 msg = _("relocation out of range");
817 break;
819 case bfd_reloc_notsupported:
820 if (msg == NULL)
821 msg = _("unsupported relocation");
822 break;
824 case bfd_reloc_dangerous:
825 if (msg == NULL)
826 msg = _("dangerous relocation");
827 break;
829 default:
830 if (msg == NULL)
831 msg = _("unknown error");
832 break;
835 if (msg)
837 (*info->callbacks->warning) (info, msg, name, input_bfd,
838 input_section, rel->r_offset);
839 return FALSE;
843 return TRUE;
847 /* Perform a diff relocation. Nothing to do, as the difference value is
848 already written into the section's contents. */
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)
859 return bfd_reloc_ok;
863 /* Returns whether the relocation type passed is a diff reloc. */
865 static bfd_boolean
866 elf32_pru_is_diff_reloc (Elf_Internal_Rela *irel)
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);
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. */
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)
887 unsigned char *reloc_contents = NULL;
888 unsigned char *isec_contents = elf_section_data (isec)->this_hdr.contents;
889 if (isec_contents == NULL)
891 if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents))
892 return;
894 elf_section_data (isec)->this_hdr.contents = isec_contents;
897 reloc_contents = isec_contents + irel->r_offset;
899 /* Read value written in object file. */
900 bfd_signed_vma x = 0;
901 switch (ELF32_R_TYPE (irel->r_info))
903 case R_PRU_GNU_DIFF8:
905 x = bfd_get_signed_8 (abfd, reloc_contents);
906 break;
908 case R_PRU_GNU_DIFF16:
910 x = bfd_get_signed_16 (abfd, reloc_contents);
911 break;
913 case R_PRU_GNU_DIFF32:
915 x = bfd_get_signed_32 (abfd, reloc_contents);
916 break;
918 case R_PRU_GNU_DIFF16_PMEM:
920 x = bfd_get_signed_16 (abfd, reloc_contents) * 4;
921 break;
923 case R_PRU_GNU_DIFF32_PMEM:
925 x = bfd_get_signed_32 (abfd, reloc_contents) * 4;
926 break;
928 default:
930 BFD_FAIL ();
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. */
939 bfd_vma end_address = symval + irel->r_addend;
940 bfd_vma start_address = end_address - x;
942 /* Shrink the absolute DIFF value (get the to labels "closer"
943 together), because we have removed data between labels. */
944 if (x < 0)
946 x += count;
947 /* In case the signed x is negative, restore order. */
948 SWAP_VALS (end_address, start_address);
950 else
952 x -= count;
955 /* Reduce the diff value by count bytes and write it back into section
956 contents. */
958 if (shrinked_insn_address >= start_address
959 && shrinked_insn_address <= end_address)
961 switch (ELF32_R_TYPE (irel->r_info))
963 case R_PRU_GNU_DIFF8:
965 bfd_put_signed_8 (abfd, x & 0xFF, reloc_contents);
966 break;
968 case R_PRU_GNU_DIFF16:
970 bfd_put_signed_16 (abfd, x & 0xFFFF, reloc_contents);
971 break;
973 case R_PRU_GNU_DIFF32:
975 bfd_put_signed_32 (abfd, x & 0xFFFFFFFF, reloc_contents);
976 break;
978 case R_PRU_GNU_DIFF16_PMEM:
980 bfd_put_signed_16 (abfd, (x / 4) & 0xFFFF, reloc_contents);
981 break;
983 case R_PRU_GNU_DIFF32_PMEM:
985 bfd_put_signed_32 (abfd, (x / 4) & 0xFFFFFFFF, reloc_contents);
986 break;
988 default:
990 BFD_FAIL ();
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.
1002 Idea copied from the AVR port. */
1004 static bfd_boolean
1005 pru_elf_relax_delete_bytes (bfd *abfd,
1006 asection *sec,
1007 bfd_vma addr,
1008 int count)
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;
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;
1025 toaddr = sec->size;
1027 irel = elf_section_data (sec)->relocs;
1028 irelend = irel + sec->reloc_count;
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;
1036 /* Adjust all the reloc addresses. */
1037 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1039 bfd_vma old_reloc_address;
1041 old_reloc_address = (sec->output_section->vma
1042 + sec->output_offset + irel->r_offset);
1044 /* Get the new reloc address. */
1045 if ((irel->r_offset > addr
1046 && irel->r_offset < toaddr))
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));
1055 irel->r_offset -= count;
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.
1066 The most common case where this happens are relocs relative to
1067 the section-start symbol.
1069 This step needs to be done for all of the sections of the bfd. */
1072 struct bfd_section *isec;
1074 for (isec = abfd->sections; isec; isec = isec->next)
1076 bfd_vma symval;
1077 bfd_vma shrinked_insn_address;
1079 if (isec->reloc_count == 0)
1080 continue;
1082 shrinked_insn_address = (sec->output_section->vma
1083 + sec->output_offset + addr - count);
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);
1090 for (irelend = irel + isec->reloc_count;
1091 irel < irelend;
1092 irel++)
1094 /* Read this BFD's local symbols if we haven't done
1095 so already. */
1096 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
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;
1107 /* Get the value of the symbol referred to by the reloc. */
1108 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1110 /* A local symbol. */
1111 asection *sym_sec;
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)
1120 symval += sym_sec->output_section->vma
1121 + sym_sec->output_offset;
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);
1133 /* Shrink the special DIFF relocations. */
1134 if (elf32_pru_is_diff_reloc (irel))
1136 elf32_pru_adjust_diff_reloc_value (abfd, isec, irel,
1137 symval,
1138 shrinked_insn_address,
1139 count);
1142 /* Fix the addend, if it is affected. */
1143 if (symval <= shrinked_insn_address
1144 && (symval + irel->r_addend) > shrinked_insn_address)
1147 irel->r_addend -= count;
1149 if (debug_relax)
1150 printf ("Relocation's addend needed to be fixed \n");
1153 /* else...Reference symbol is absolute.
1154 No adjustment needed. */
1156 /* else...Reference symbol is extern. No need for adjusting
1157 the addend. */
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)
1167 Elf_Internal_Sym *isymend;
1169 isymend = isym + symtab_hdr->sh_info;
1170 for (; isym < isymend; isym++)
1172 if (isym->st_shndx == sec_shndx)
1174 if (isym->st_value > addr
1175 && isym->st_value <= toaddr)
1176 isym->st_value -= count;
1178 if (isym->st_value <= addr
1179 && isym->st_value + isym->st_size > addr)
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;
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++)
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)
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;
1207 if (sym_hash->root.u.def.value <= addr
1208 && (sym_hash->root.u.def.value + sym_hash->size > addr))
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;
1220 return TRUE;
1223 static bfd_boolean
1224 pru_elf32_relax_section (bfd * abfd, asection * sec,
1225 struct bfd_link_info * link_info,
1226 bfd_boolean * again)
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;
1235 /* Assume nothing changes. */
1236 *again = FALSE;
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;
1246 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
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;
1254 /* Walk through them looking for relaxing opportunities. */
1255 irelend = internal_relocs + sec->reloc_count;
1257 for (irel = internal_relocs; irel < irelend; irel++)
1259 bfd_vma symval;
1261 /* Get the section contents if we haven't done so already. */
1262 if (contents == NULL)
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;
1271 /* Read this BFD's local symbols if we haven't done so already. */
1272 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
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;
1283 /* Get the value of the symbol referred to by the reloc. */
1284 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1286 /* A local symbol. */
1287 Elf_Internal_Sym *isym;
1288 asection *sym_sec;
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);
1302 else
1304 unsigned long indx;
1305 struct elf_link_hash_entry *h;
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);
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;
1319 symval = (h->root.u.def.value
1320 + h->root.u.def.section->output_section->vma
1321 + h->root.u.def.section->output_offset);
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. */
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)
1336 bfd_vma value = symval + irel->r_addend;
1338 if (debug_relax)
1339 printf ("R_PRU_LDI32 with value=0x%lx\n", (long) value);
1341 if ((long) value >> 16 == 0)
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;
1348 /* Delete bytes. */
1349 if (!pru_elf_relax_delete_bytes (abfd, sec, irel->r_offset + 4, 4))
1350 goto error_return;
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);
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;
1366 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
1368 if (!link_info->keep_memory)
1369 free (isymbuf);
1370 else
1372 /* Cache the symbols for elf_link_input_bfd. */
1373 symtab_hdr->contents = (unsigned char *) isymbuf;
1377 if (contents != NULL
1378 && elf_section_data (sec)->this_hdr.contents != contents)
1380 if (!link_info->keep_memory)
1381 free (contents);
1382 else
1384 /* Cache the section contents for elf_link_input_bfd. */
1385 elf_section_data (sec)->this_hdr.contents = contents;
1389 if (internal_relocs != NULL
1390 && elf_section_data (sec)->relocs != internal_relocs)
1391 free (internal_relocs);
1393 return TRUE;
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);
1405 return FALSE;
1408 /* Free the derived linker hash table. */
1409 static void
1410 pru_elf32_link_hash_table_free (bfd *obfd)
1412 _bfd_elf_link_hash_table_free (obfd);
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)
1419 struct elf_link_hash_table *ret;
1420 bfd_size_type amt = sizeof (struct elf_link_hash_table);
1422 ret = bfd_zmalloc (amt);
1423 if (ret == NULL)
1424 return NULL;
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))
1432 free (ret);
1433 return NULL;
1436 ret->root.hash_table_free = pru_elf32_link_hash_table_free;
1438 return &ret->root;
1441 #define ELF_ARCH bfd_arch_pru
1442 #define ELF_TARGET_ID PRU_ELF_DATA
1443 #define ELF_MACHINE_CODE EM_TI_PRU
1445 #define ELF_MAXPAGESIZE 1
1447 #define bfd_elf32_bfd_link_hash_table_create \
1448 pru_elf32_link_hash_table_create
1450 /* Relocation table lookup macros. */
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
1455 /* elf_info_to_howto (using RELA relocations). */
1457 #define elf_info_to_howto pru_elf32_info_to_howto
1459 /* elf backend functions. */
1461 #define elf_backend_rela_normal 1
1463 #define elf_backend_relocate_section pru_elf32_relocate_section
1464 #define bfd_elf32_bfd_relax_section pru_elf32_relax_section
1466 #define TARGET_LITTLE_SYM pru_elf32_vec
1467 #define TARGET_LITTLE_NAME "elf32-pru"
1469 #include "elf32-target.h"