1 /* 32-bit ELF support for TI PRU.
2 Copyright (C) 2014-2019 Free Software Foundation, Inc.
3 Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
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. */
32 #include "opcode/pru.h"
33 #include "libiberty.h"
35 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
36 #define OCTETS_PER_BYTE(ABFD, SEC) 1
38 #define SWAP_VALS(A,B) \
45 /* Enable debugging printout at stdout with this variable. */
46 static bfd_boolean debug_relax
= FALSE
;
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 **);
61 extern const bfd_target pru_elf32_vec
;
63 /* The relocation table used for SHT_REL sections. */
64 static reloc_howto_type elf_pru_howto_table_rel
[] = {
66 HOWTO (R_PRU_NONE
, /* type */
68 0, /* size (0 = byte, 1 = short, 2 = long) */
70 FALSE
, /* pc_relative */
72 complain_overflow_dont
,/* complain_on_overflow */
73 bfd_elf_generic_reloc
, /* special_function */
74 "R_PRU_NONE", /* name */
75 FALSE
, /* partial_inplace */
78 FALSE
), /* pcrel_offset */
86 complain_overflow_dont
,
87 bfd_elf_generic_reloc
,
94 HOWTO (R_PRU_U16_PMEMIMM
,
100 complain_overflow_unsigned
,
101 pru_elf32_pmem_relocate
,
108 HOWTO (R_PRU_BFD_RELOC_16
,
114 complain_overflow_bitfield
,
115 bfd_elf_generic_reloc
,
122 /* 16-bit unsigned immediate relocation. */
123 HOWTO (R_PRU_U16
, /* type */
125 2, /* size (0 = byte, 1 = short, 2 = long) */
127 FALSE
, /* pc_relative */
129 complain_overflow_unsigned
, /* complain on overflow */
130 bfd_elf_generic_reloc
, /* special function */
131 "R_PRU_U16", /* name */
132 FALSE
, /* partial_inplace */
134 0x00ffff00, /* dest_mask */
135 FALSE
), /* pcrel_offset */
137 HOWTO (R_PRU_32_PMEM
,
143 complain_overflow_dont
,
144 pru_elf32_pmem_relocate
,
151 HOWTO (R_PRU_BFD_RELOC_32
,
157 complain_overflow_dont
,
158 bfd_elf_generic_reloc
,
165 HOWTO (R_PRU_S10_PCREL
,
171 complain_overflow_bitfield
,
172 pru_elf32_s10_pcrel_relocate
,
179 HOWTO (R_PRU_U8_PCREL
,
185 complain_overflow_unsigned
,
186 pru_elf32_u8_pcrel_relocate
,
195 4, /* size (4 = 8bytes) */
197 FALSE
, /* pc_relative */
199 complain_overflow_unsigned
, /* complain on overflow */
200 pru_elf32_ldi32_relocate
, /* special function */
201 "R_PRU_LDI32", /* name */
202 FALSE
, /* partial_inplace */
204 0xffffffff, /* dest_mask */
205 FALSE
), /* pcrel_offset */
207 /* GNU-specific relocations. */
208 HOWTO (R_PRU_GNU_BFD_RELOC_8
,
214 complain_overflow_bitfield
,
215 bfd_elf_generic_reloc
,
222 HOWTO (R_PRU_GNU_DIFF8
, /* type */
224 0, /* size (0 = byte, 1 = short, 2 = long) */
226 FALSE
, /* pc_relative */
228 complain_overflow_bitfield
, /* complain_on_overflow */
229 bfd_elf_pru_diff_relocate
, /* special_function */
230 "R_PRU_DIFF8", /* name */
231 FALSE
, /* partial_inplace */
234 FALSE
), /* pcrel_offset */
236 HOWTO (R_PRU_GNU_DIFF16
, /* type */
238 1, /* size (0 = byte, 1 = short, 2 = long) */
240 FALSE
, /* pc_relative */
242 complain_overflow_bitfield
, /* complain_on_overflow */
243 bfd_elf_pru_diff_relocate
,/* special_function */
244 "R_PRU_DIFF16", /* name */
245 FALSE
, /* partial_inplace */
247 0xffff, /* dst_mask */
248 FALSE
), /* pcrel_offset */
250 HOWTO (R_PRU_GNU_DIFF32
, /* type */
252 2, /* size (0 = byte, 1 = short, 2 = long) */
254 FALSE
, /* pc_relative */
256 complain_overflow_bitfield
, /* complain_on_overflow */
257 bfd_elf_pru_diff_relocate
,/* special_function */
258 "R_PRU_DIFF32", /* name */
259 FALSE
, /* partial_inplace */
261 0xffffffff, /* dst_mask */
262 FALSE
), /* pcrel_offset */
264 HOWTO (R_PRU_GNU_DIFF16_PMEM
, /* type */
266 1, /* size (0 = byte, 1 = short, 2 = long) */
268 FALSE
, /* pc_relative */
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 */
275 0xffff, /* dst_mask */
276 FALSE
), /* pcrel_offset */
278 HOWTO (R_PRU_GNU_DIFF32_PMEM
, /* type */
280 2, /* size (0 = byte, 1 = short, 2 = long) */
282 FALSE
, /* pc_relative */
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 */
289 0xffffffff, /* dst_mask */
290 FALSE
), /* pcrel_offset */
292 /* Add other relocations here. */
295 static unsigned char elf_code_to_howto_index
[R_PRU_ILLEGAL
+ 1];
297 /* Return the howto for relocation RTYPE. */
299 static reloc_howto_type
*
300 lookup_howto (unsigned int rtype
)
302 static bfd_boolean initialized
= FALSE
;
304 int howto_tbl_size
= (int) (sizeof (elf_pru_howto_table_rel
)
305 / sizeof (elf_pru_howto_table_rel
[0]));
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
;
316 if (rtype
> R_PRU_ILLEGAL
)
318 i
= elf_code_to_howto_index
[rtype
];
319 if (i
>= howto_tbl_size
)
321 return elf_pru_howto_table_rel
+ i
;
324 /* Map for converting BFD reloc types to PRU reloc types. */
328 bfd_reloc_code_real_type bfd_val
;
329 enum elf_pru_reloc_type elf_val
;
332 static const struct elf_reloc_map pru_reloc_map
[] =
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
},
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
},
354 /* Assorted hash table functions. */
356 /* Create an entry in a PRU ELF linker hash table. */
358 static struct bfd_hash_entry
*
359 link_hash_newfunc (struct bfd_hash_entry
*entry
,
360 struct bfd_hash_table
*table
, const char *string
)
362 /* Allocate the structure if it has not already been allocated by a
366 entry
= bfd_hash_allocate (table
,
367 sizeof (struct elf_link_hash_entry
));
372 /* Call the allocation method of the superclass. */
373 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
378 /* Implement bfd_elf32_bfd_reloc_type_lookup:
379 Given a BFD reloc type, return a howto structure. */
381 static reloc_howto_type
*
382 pru_elf32_bfd_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
383 bfd_reloc_code_real_type code
)
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
);
393 /* Implement bfd_elf32_bfd_reloc_name_lookup:
394 Given a reloc name, return a howto structure. */
396 static reloc_howto_type
*
397 pru_elf32_bfd_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
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
];
410 /* Implement elf_info_to_howto:
411 Given a ELF32 relocation, fill in a arelent structure. */
414 pru_elf32_info_to_howto (bfd
*abfd
, arelent
*cache_ptr
,
415 Elf_Internal_Rela
*dst
)
419 r_type
= ELF32_R_TYPE (dst
->r_info
);
420 if (r_type
>= R_PRU_ILLEGAL
)
422 /* xgettext:c-format */
423 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd
, r_type
);
424 bfd_set_error (bfd_error_bad_value
);
428 cache_ptr
->howto
= lookup_howto (r_type
);
429 return cache_ptr
->howto
!= NULL
;
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.
437 But why 1MB when internal Program Memory much smaller? We want to catch
438 unintended overflows.
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.
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
)
452 symbol_value
= symbol_value
+ addend
;
454 symbol_value
&= 0x3fffff;
455 return _bfd_final_link_relocate (howto
, abfd
, input_section
,
456 data
, offset
, symbol_value
, addend
);
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
)
471 bfd_reloc_status_type flag
= bfd_reloc_ok
;
473 /* Sanity check the address. */
474 if (address
> bfd_get_section_limit (input_bfd
, input_section
))
475 return bfd_reloc_outofrange
;
477 BFD_ASSERT (howto
->pc_relative
);
478 BFD_ASSERT (howto
->pcrel_offset
);
480 relocation
= relocation
+ addend
- (input_section
->output_section
->vma
481 + input_section
->output_offset
) - address
;
483 location
= contents
+ address
;
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
);
489 qboff
= GET_BROFF_SIGNED (x
) << howto
->rightshift
;
492 BFD_ASSERT (howto
->complain_on_overflow
== complain_overflow_bitfield
);
494 if (relocation
> 2047 && relocation
< (bfd_vma
)-2048l)
495 flag
= bfd_reloc_overflow
;
497 /* Check that target address is word-aligned. */
498 if (relocation
& ((1 << howto
->rightshift
) - 1))
499 flag
= bfd_reloc_outofrange
;
501 relocation
>>= (bfd_vma
) howto
->rightshift
;
503 /* Fill-in the RELOCATION to the right bits of X. */
504 SET_BROFF_URAW (x
, relocation
);
506 bfd_put_32 (input_bfd
, x
, location
);
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
)
519 BFD_ASSERT (howto
->pc_relative
);
520 BFD_ASSERT (howto
->pcrel_offset
);
522 relocation
= symbol_value
+ addend
- (input_section
->output_section
->vma
523 + input_section
->output_offset
) - offset
;
524 relocation
>>= howto
->rightshift
;
526 /* 0 and 1 are invalid target labels for LOOP. We cannot
527 encode this info in HOWTO, so catch such cases here. */
529 return bfd_reloc_outofrange
;
531 return _bfd_final_link_relocate (howto
, abfd
, input_section
,
532 data
, offset
, symbol_value
, addend
);
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
)
542 bfd_signed_vma relocation
;
543 bfd_size_type octets
= offset
* OCTETS_PER_BYTE (abfd
, input_section
);
545 unsigned long in1
, in2
;
547 /* A hacked-up version of _bfd_final_link_relocate() follows. */
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
;
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
;
560 BFD_ASSERT (!howto
->pc_relative
);
562 /* A hacked-up version of _bfd_relocate_contents() follows. */
563 location
= data
+ octets
;
565 BFD_ASSERT (!howto
->pc_relative
);
567 in1
= bfd_get_32 (abfd
, location
);
568 in2
= bfd_get_32 (abfd
, location
+ 4);
570 SET_INSN_FIELD (IMM16
, in1
, relocation
>> 16);
571 SET_INSN_FIELD (IMM16
, in2
, relocation
& 0xffff);
573 bfd_put_32 (abfd
, in1
, location
);
574 bfd_put_32 (abfd
, in2
, location
+ 4);
576 /* Old GAS and LD versions have a bug, where the two
577 LDI instructions are swapped. Detect such object
579 if (GET_INSN_FIELD (RDSEL
, in1
) != RSEL_31_16
)
581 /* xgettext:c-format */
582 _bfd_error_handler (_("error: %pB: old incompatible object file detected"),
584 return bfd_reloc_notsupported
;
590 /* HOWTO handlers for relocations that require special handling. */
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
)
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
601 if (output_bfd
!= NULL
)
602 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
603 input_section
, output_bfd
, error_message
);
606 return pru_elf32_do_pmem_relocate (abfd
, reloc_entry
->howto
,
608 data
, reloc_entry
->address
,
610 + symbol
->section
->output_section
->vma
611 + symbol
->section
->output_offset
),
612 reloc_entry
->addend
);
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
)
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
624 if (output_bfd
!= NULL
)
625 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
626 input_section
, output_bfd
, error_message
);
628 return pru_elf32_do_s10_pcrel_relocate (abfd
, reloc_entry
->howto
,
630 reloc_entry
->address
,
632 + symbol
->section
->output_section
->vma
633 + symbol
->section
->output_offset
),
634 reloc_entry
->addend
);
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
,
641 char **error_message
)
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
646 if (output_bfd
!= NULL
)
647 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
648 input_section
, output_bfd
, error_message
);
650 return pru_elf32_do_u8_pcrel_relocate (abfd
, reloc_entry
->howto
,
652 data
, reloc_entry
->address
,
654 + symbol
->section
->output_section
->vma
655 + symbol
->section
->output_offset
),
656 reloc_entry
->addend
);
659 static bfd_reloc_status_type
660 pru_elf32_ldi32_relocate (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
661 void *data
, asection
*input_section
,
663 char **error_message
)
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
668 if (output_bfd
!= NULL
)
669 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
670 input_section
, output_bfd
, error_message
);
672 return pru_elf32_do_ldi32_relocate (abfd
, reloc_entry
->howto
,
674 data
, reloc_entry
->address
,
676 + symbol
->section
->output_section
->vma
677 + symbol
->section
->output_offset
),
678 reloc_entry
->addend
);
682 /* Implement elf_backend_relocate_section. */
684 pru_elf32_relocate_section (bfd
*output_bfd
,
685 struct bfd_link_info
*info
,
687 asection
*input_section
,
689 Elf_Internal_Rela
*relocs
,
690 Elf_Internal_Sym
*local_syms
,
691 asection
**local_sections
)
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
;
700 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
701 sym_hashes
= elf_sym_hashes (input_bfd
);
702 relend
= relocs
+ input_section
->reloc_count
;
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
);
711 for (rel
= relocs
; rel
< relend
; rel
++)
713 reloc_howto_type
*howto
;
714 unsigned long r_symndx
;
715 Elf_Internal_Sym
*sym
;
717 struct elf_link_hash_entry
*h
;
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
;
725 /* If we are using a REL relocation then the addend should be empty. */
726 BFD_ASSERT (! is_rel_reloc
|| rel
->r_addend
== 0);
728 r_symndx
= ELF32_R_SYM (rel
->r_info
);
730 howto
= lookup_howto ((unsigned) ELF32_R_TYPE (rel
->r_info
));
735 if (r_symndx
< symtab_hdr
->sh_info
)
737 sym
= local_syms
+ r_symndx
;
738 sec
= local_sections
[r_symndx
];
739 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
743 bfd_boolean warned
, ignored
;
745 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
746 r_symndx
, symtab_hdr
, sym_hashes
,
748 unresolved_reloc
, warned
, ignored
);
751 if (sec
&& discarded_section (sec
))
752 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
753 rel
, 1, relend
, howto
, 0, contents
);
755 /* Nothing more to do unless this is a final link. */
756 if (bfd_link_relocatable (info
))
764 /* We don't need to find a value for this symbol. It's just a
773 insn
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
774 addend
= GET_INSN_FIELD (IMM16
, insn
);
777 addend
= rel
->r_addend
;
778 r
= _bfd_final_link_relocate (howto
, input_bfd
,
779 input_section
, contents
,
780 rel
->r_offset
, relocation
,
784 case R_PRU_U16_PMEMIMM
:
787 if (is_rel_reloc
&& howto
->type
== R_PRU_U16_PMEMIMM
)
790 insn
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
791 addend
= GET_INSN_FIELD (IMM16
, insn
) << 2;
793 else if (is_rel_reloc
&& howto
->type
== R_PRU_32_PMEM
)
795 addend
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
798 else if (is_rel_reloc
&& howto
->type
== R_PRU_16_PMEM
)
800 addend
= bfd_get_16 (input_bfd
, contents
+ rel
->r_offset
);
805 BFD_ASSERT (!is_rel_reloc
);
806 addend
= rel
->r_addend
;
808 r
= pru_elf32_do_pmem_relocate (input_bfd
, howto
,
810 contents
, rel
->r_offset
,
813 case R_PRU_S10_PCREL
:
814 BFD_ASSERT (! is_rel_reloc
);
815 r
= pru_elf32_do_s10_pcrel_relocate (input_bfd
, howto
,
823 BFD_ASSERT (! is_rel_reloc
);
824 r
= pru_elf32_do_u8_pcrel_relocate (input_bfd
, howto
,
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
);
842 addend
= rel
->r_addend
;
844 r
= pru_elf32_do_ldi32_relocate (input_bfd
, howto
,
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
863 case R_PRU_BFD_RELOC_16
:
865 addend
= bfd_get_16 (input_bfd
, contents
+ rel
->r_offset
);
867 addend
= rel
->r_addend
;
868 r
= _bfd_final_link_relocate (howto
, input_bfd
,
869 input_section
, contents
,
870 rel
->r_offset
, relocation
,
874 case R_PRU_BFD_RELOC_32
:
876 addend
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
878 addend
= rel
->r_addend
;
879 r
= _bfd_final_link_relocate (howto
, input_bfd
,
880 input_section
, contents
,
881 rel
->r_offset
, relocation
,
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
,
899 r
= bfd_reloc_notsupported
;
901 if (r
!= bfd_reloc_ok
)
904 name
= h
->root
.root
.string
;
907 name
= bfd_elf_string_from_elf_section (input_bfd
,
910 if (name
== NULL
|| *name
== '\0')
911 name
= bfd_section_name (sec
);
916 case bfd_reloc_overflow
:
917 (*info
->callbacks
->reloc_overflow
) (info
, NULL
, name
,
918 howto
->name
, (bfd_vma
) 0,
919 input_bfd
, input_section
,
923 case bfd_reloc_undefined
:
924 (*info
->callbacks
->undefined_symbol
) (info
, name
, input_bfd
,
926 rel
->r_offset
, TRUE
);
929 case bfd_reloc_outofrange
:
931 msg
= _("relocation out of range");
934 case bfd_reloc_notsupported
:
936 msg
= _("unsupported relocation");
939 case bfd_reloc_dangerous
:
941 msg
= _("dangerous relocation");
946 msg
= _("unknown error");
952 (*info
->callbacks
->warning
) (info
, msg
, name
, input_bfd
,
953 input_section
, rel
->r_offset
);
962 /* Perform a diff relocation. Nothing to do, as the difference value is
963 already written into the section's contents. */
965 static bfd_reloc_status_type
966 bfd_elf_pru_diff_relocate (bfd
*abfd ATTRIBUTE_UNUSED
,
967 arelent
*reloc_entry ATTRIBUTE_UNUSED
,
968 asymbol
*symbol ATTRIBUTE_UNUSED
,
969 void *data ATTRIBUTE_UNUSED
,
970 asection
*input_section ATTRIBUTE_UNUSED
,
971 bfd
*output_bfd ATTRIBUTE_UNUSED
,
972 char **error_message ATTRIBUTE_UNUSED
)
978 /* Returns whether the relocation type passed is a diff reloc. */
981 elf32_pru_is_diff_reloc (Elf_Internal_Rela
*irel
)
983 return (ELF32_R_TYPE (irel
->r_info
) == R_PRU_GNU_DIFF8
984 || ELF32_R_TYPE (irel
->r_info
) == R_PRU_GNU_DIFF16
985 || ELF32_R_TYPE (irel
->r_info
) == R_PRU_GNU_DIFF32
986 || ELF32_R_TYPE (irel
->r_info
) == R_PRU_GNU_DIFF16_PMEM
987 || ELF32_R_TYPE (irel
->r_info
) == R_PRU_GNU_DIFF32_PMEM
);
990 /* Reduce the diff value written in the section by count if the shrinked
991 insn address happens to fall between the two symbols for which this
992 diff reloc was emitted. */
995 elf32_pru_adjust_diff_reloc_value (bfd
*abfd
,
996 struct bfd_section
*isec
,
997 Elf_Internal_Rela
*irel
,
999 bfd_vma shrinked_insn_address
,
1002 unsigned char *reloc_contents
= NULL
;
1003 unsigned char *isec_contents
= elf_section_data (isec
)->this_hdr
.contents
;
1004 if (isec_contents
== NULL
)
1006 if (! bfd_malloc_and_get_section (abfd
, isec
, &isec_contents
))
1009 elf_section_data (isec
)->this_hdr
.contents
= isec_contents
;
1012 reloc_contents
= isec_contents
+ irel
->r_offset
;
1014 /* Read value written in object file. */
1015 bfd_signed_vma x
= 0;
1016 switch (ELF32_R_TYPE (irel
->r_info
))
1018 case R_PRU_GNU_DIFF8
:
1020 x
= bfd_get_signed_8 (abfd
, reloc_contents
);
1023 case R_PRU_GNU_DIFF16
:
1025 x
= bfd_get_signed_16 (abfd
, reloc_contents
);
1028 case R_PRU_GNU_DIFF32
:
1030 x
= bfd_get_signed_32 (abfd
, reloc_contents
);
1033 case R_PRU_GNU_DIFF16_PMEM
:
1035 x
= bfd_get_signed_16 (abfd
, reloc_contents
) * 4;
1038 case R_PRU_GNU_DIFF32_PMEM
:
1040 x
= bfd_get_signed_32 (abfd
, reloc_contents
) * 4;
1049 /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written
1050 into the object file at the reloc offset. sym2's logical value is
1051 symval (<start_of_section>) + reloc addend. Compute the start and end
1052 addresses and check if the shrinked insn falls between sym1 and sym2. */
1054 bfd_vma end_address
= symval
+ irel
->r_addend
;
1055 bfd_vma start_address
= end_address
- x
;
1057 /* Shrink the absolute DIFF value (get the to labels "closer"
1058 together), because we have removed data between labels. */
1062 /* In case the signed x is negative, restore order. */
1063 SWAP_VALS (end_address
, start_address
);
1070 /* Reduce the diff value by count bytes and write it back into section
1073 if (shrinked_insn_address
>= start_address
1074 && shrinked_insn_address
<= end_address
)
1076 switch (ELF32_R_TYPE (irel
->r_info
))
1078 case R_PRU_GNU_DIFF8
:
1080 bfd_put_signed_8 (abfd
, x
& 0xFF, reloc_contents
);
1083 case R_PRU_GNU_DIFF16
:
1085 bfd_put_signed_16 (abfd
, x
& 0xFFFF, reloc_contents
);
1088 case R_PRU_GNU_DIFF32
:
1090 bfd_put_signed_32 (abfd
, x
& 0xFFFFFFFF, reloc_contents
);
1093 case R_PRU_GNU_DIFF16_PMEM
:
1095 bfd_put_signed_16 (abfd
, (x
/ 4) & 0xFFFF, reloc_contents
);
1098 case R_PRU_GNU_DIFF32_PMEM
:
1100 bfd_put_signed_32 (abfd
, (x
/ 4) & 0xFFFFFFFF, reloc_contents
);
1112 /* Delete some bytes from a section while changing the size of an instruction.
1113 The parameter "addr" denotes the section-relative offset pointing just
1114 behind the shrinked instruction. "addr+count" point at the first
1115 byte just behind the original unshrinked instruction.
1117 Idea copied from the AVR port. */
1120 pru_elf_relax_delete_bytes (bfd
*abfd
,
1125 Elf_Internal_Shdr
*symtab_hdr
;
1126 unsigned int sec_shndx
;
1128 Elf_Internal_Rela
*irel
, *irelend
;
1129 Elf_Internal_Sym
*isym
;
1130 Elf_Internal_Sym
*isymbuf
= NULL
;
1132 struct elf_link_hash_entry
**sym_hashes
;
1133 struct elf_link_hash_entry
**end_hashes
;
1134 unsigned int symcount
;
1136 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1137 sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1138 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1142 irel
= elf_section_data (sec
)->relocs
;
1143 irelend
= irel
+ sec
->reloc_count
;
1145 /* Actually delete the bytes. */
1146 if (toaddr
- addr
- count
> 0)
1147 memmove (contents
+ addr
, contents
+ addr
+ count
,
1148 (size_t) (toaddr
- addr
- count
));
1151 /* Adjust all the reloc addresses. */
1152 for (irel
= elf_section_data (sec
)->relocs
; irel
< irelend
; irel
++)
1154 bfd_vma old_reloc_address
;
1156 old_reloc_address
= (sec
->output_section
->vma
1157 + sec
->output_offset
+ irel
->r_offset
);
1159 /* Get the new reloc address. */
1160 if ((irel
->r_offset
> addr
1161 && irel
->r_offset
< toaddr
))
1164 printf ("Relocation at address 0x%x needs to be moved.\n"
1165 "Old section offset: 0x%x, New section offset: 0x%x \n",
1166 (unsigned int) old_reloc_address
,
1167 (unsigned int) irel
->r_offset
,
1168 (unsigned int) ((irel
->r_offset
) - count
));
1170 irel
->r_offset
-= count
;
1175 /* The reloc's own addresses are now ok. However, we need to readjust
1176 the reloc's addend, i.e. the reloc's value if two conditions are met:
1177 1.) the reloc is relative to a symbol in this section that
1178 is located in front of the shrinked instruction
1179 2.) symbol plus addend end up behind the shrinked instruction.
1181 The most common case where this happens are relocs relative to
1182 the section-start symbol.
1184 This step needs to be done for all of the sections of the bfd. */
1187 struct bfd_section
*isec
;
1189 for (isec
= abfd
->sections
; isec
; isec
= isec
->next
)
1192 bfd_vma shrinked_insn_address
;
1194 if (isec
->reloc_count
== 0)
1197 shrinked_insn_address
= (sec
->output_section
->vma
1198 + sec
->output_offset
+ addr
);
1200 irel
= elf_section_data (isec
)->relocs
;
1201 /* PR 12161: Read in the relocs for this section if necessary. */
1203 irel
= _bfd_elf_link_read_relocs (abfd
, isec
, NULL
, NULL
, TRUE
);
1205 for (irelend
= irel
+ isec
->reloc_count
;
1209 /* Read this BFD's local symbols if we haven't done
1211 if (isymbuf
== NULL
&& symtab_hdr
->sh_info
!= 0)
1213 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1214 if (isymbuf
== NULL
)
1215 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
1216 symtab_hdr
->sh_info
, 0,
1218 if (isymbuf
== NULL
)
1222 /* Get the value of the symbol referred to by the reloc. */
1223 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1225 /* A local symbol. */
1228 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1229 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1230 symval
= isym
->st_value
;
1231 /* If the reloc is absolute, it will not have
1232 a symbol or section associated with it. */
1235 symval
+= sym_sec
->output_section
->vma
1236 + sym_sec
->output_offset
;
1239 printf ("Checking if the relocation's "
1240 "addend needs corrections.\n"
1241 "Address of anchor symbol: 0x%x \n"
1242 "Address of relocation target: 0x%x \n"
1243 "Address of relaxed insn: 0x%x \n",
1244 (unsigned int) symval
,
1245 (unsigned int) (symval
+ irel
->r_addend
),
1246 (unsigned int) shrinked_insn_address
);
1248 /* Shrink the special DIFF relocations. */
1249 if (elf32_pru_is_diff_reloc (irel
))
1251 elf32_pru_adjust_diff_reloc_value (abfd
, isec
, irel
,
1253 shrinked_insn_address
,
1257 /* Fix the addend, if it is affected. */
1258 if (symval
<= shrinked_insn_address
1259 && (symval
+ irel
->r_addend
) > shrinked_insn_address
)
1262 irel
->r_addend
-= count
;
1265 printf ("Relocation's addend needed to be fixed \n");
1268 /* else...Reference symbol is absolute.
1269 No adjustment needed. */
1271 /* else...Reference symbol is extern. No need for adjusting
1277 /* Adjust the local symbols defined in this section. */
1278 isym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1279 /* Fix PR 9841, there may be no local symbols. */
1282 Elf_Internal_Sym
*isymend
;
1284 isymend
= isym
+ symtab_hdr
->sh_info
;
1285 for (; isym
< isymend
; isym
++)
1287 if (isym
->st_shndx
== sec_shndx
)
1289 if (isym
->st_value
> addr
1290 && isym
->st_value
<= toaddr
)
1291 isym
->st_value
-= count
;
1293 if (isym
->st_value
<= addr
1294 && isym
->st_value
+ isym
->st_size
> addr
)
1296 /* If this assert fires then we have a symbol that ends
1297 part way through an instruction. Does that make
1299 BFD_ASSERT (isym
->st_value
+ isym
->st_size
>= addr
+ count
);
1300 isym
->st_size
-= count
;
1306 /* Now adjust the global symbols defined in this section. */
1307 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)
1308 - symtab_hdr
->sh_info
);
1309 sym_hashes
= elf_sym_hashes (abfd
);
1310 end_hashes
= sym_hashes
+ symcount
;
1311 for (; sym_hashes
< end_hashes
; sym_hashes
++)
1313 struct elf_link_hash_entry
*sym_hash
= *sym_hashes
;
1314 if ((sym_hash
->root
.type
== bfd_link_hash_defined
1315 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
1316 && sym_hash
->root
.u
.def
.section
== sec
)
1318 if (sym_hash
->root
.u
.def
.value
> addr
1319 && sym_hash
->root
.u
.def
.value
<= toaddr
)
1320 sym_hash
->root
.u
.def
.value
-= count
;
1322 if (sym_hash
->root
.u
.def
.value
<= addr
1323 && (sym_hash
->root
.u
.def
.value
+ sym_hash
->size
> addr
))
1325 /* If this assert fires then we have a symbol that ends
1326 part way through an instruction. Does that make
1328 BFD_ASSERT (sym_hash
->root
.u
.def
.value
+ sym_hash
->size
1330 sym_hash
->size
-= count
;
1339 pru_elf32_relax_section (bfd
* abfd
, asection
* sec
,
1340 struct bfd_link_info
* link_info
,
1341 bfd_boolean
* again
)
1343 Elf_Internal_Shdr
* symtab_hdr
;
1344 Elf_Internal_Rela
* internal_relocs
;
1345 Elf_Internal_Rela
* irel
;
1346 Elf_Internal_Rela
* irelend
;
1347 bfd_byte
* contents
= NULL
;
1348 Elf_Internal_Sym
* isymbuf
= NULL
;
1350 /* Assume nothing changes. */
1353 /* We don't have to do anything for a relocatable link, if
1354 this section does not have relocs, or if this is not a
1356 if (bfd_link_relocatable (link_info
)
1357 || (sec
->flags
& SEC_RELOC
) == 0
1358 || sec
->reloc_count
== 0 || (sec
->flags
& SEC_CODE
) == 0)
1361 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
1363 /* Get a copy of the native relocations. */
1364 internal_relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
,
1365 link_info
->keep_memory
);
1366 if (internal_relocs
== NULL
)
1369 /* Walk through them looking for relaxing opportunities. */
1370 irelend
= internal_relocs
+ sec
->reloc_count
;
1372 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
1376 /* Get the section contents if we haven't done so already. */
1377 if (contents
== NULL
)
1379 /* Get cached copy if it exists. */
1380 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1381 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1382 else if (! bfd_malloc_and_get_section (abfd
, sec
, &contents
))
1386 /* Read this BFD's local symbols if we haven't done so already. */
1387 if (isymbuf
== NULL
&& symtab_hdr
->sh_info
!= 0)
1389 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1390 if (isymbuf
== NULL
)
1391 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
1392 symtab_hdr
->sh_info
, 0,
1394 if (isymbuf
== NULL
)
1398 /* Get the value of the symbol referred to by the reloc. */
1399 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1401 /* A local symbol. */
1402 Elf_Internal_Sym
*isym
;
1405 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1406 if (isym
->st_shndx
== SHN_UNDEF
)
1407 sym_sec
= bfd_und_section_ptr
;
1408 else if (isym
->st_shndx
== SHN_ABS
)
1409 sym_sec
= bfd_abs_section_ptr
;
1410 else if (isym
->st_shndx
== SHN_COMMON
)
1411 sym_sec
= bfd_com_section_ptr
;
1413 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1414 symval
= (isym
->st_value
1415 + sym_sec
->output_section
->vma
+ sym_sec
->output_offset
);
1420 struct elf_link_hash_entry
*h
;
1422 /* An external symbol. */
1423 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1424 h
= elf_sym_hashes (abfd
)[indx
];
1425 BFD_ASSERT (h
!= NULL
);
1427 if (h
->root
.type
!= bfd_link_hash_defined
1428 && h
->root
.type
!= bfd_link_hash_defweak
)
1429 /* This appears to be a reference to an undefined
1430 symbol. Just ignore it--it will be caught by the
1431 regular reloc processing. */
1434 symval
= (h
->root
.u
.def
.value
1435 + h
->root
.u
.def
.section
->output_section
->vma
1436 + h
->root
.u
.def
.section
->output_offset
);
1439 /* For simplicity of coding, we are going to modify the section
1440 contents, the section relocs, and the BFD symbol table. We
1441 must tell the rest of the code not to free up this
1442 information. It would be possible to instead create a table
1443 of changes which have to be made, as is done in coff-mips.c;
1444 that would be more work, but would require less memory when
1445 the linker is run. */
1447 /* Check if we can remove an LDI instruction from the LDI32
1448 pseudo instruction if the upper 16 operand bits are zero. */
1449 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_PRU_LDI32
)
1451 bfd_vma value
= symval
+ irel
->r_addend
;
1454 printf ("R_PRU_LDI32 with value=0x%lx\n", (long) value
);
1456 if ((long) value
>> 16 == 0)
1460 /* Note that we've changed the relocs, section contents. */
1461 elf_section_data (sec
)->relocs
= internal_relocs
;
1462 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1463 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1465 /* Make the second instruction load the 16-bit constant
1466 into the full 32-bit register. */
1467 insn
= bfd_get_32 (abfd
, contents
+ irel
->r_offset
+ 4);
1469 /* Old GAS and LD versions have a bug, where the two
1470 LDI instructions are swapped. Detect such object
1472 if (GET_INSN_FIELD (RDSEL
, insn
) != RSEL_15_0
)
1474 /* xgettext:c-format */
1475 _bfd_error_handler (_("error: %pB: old incompatible object file detected"),
1480 SET_INSN_FIELD (RDSEL
, insn
, RSEL_31_0
);
1481 bfd_put_32 (abfd
, insn
, contents
+ irel
->r_offset
+ 4);
1483 /* Delete the first LDI instruction. Note that there should
1484 be no relocations or symbols pointing to the second LDI
1486 if (!pru_elf_relax_delete_bytes (abfd
, sec
, irel
->r_offset
, 4))
1489 /* We're done with deletion of the first instruction.
1490 Set a regular LDI relocation for the second instruction
1491 we left to load the 16-bit value into the 32-bit
1493 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1496 /* That will change things, so, we should relax again.
1497 Note that this is not required, and it may be slow. */
1503 if (isymbuf
!= NULL
&& symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1505 if (!link_info
->keep_memory
)
1509 /* Cache the symbols for elf_link_input_bfd. */
1510 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1514 if (contents
!= NULL
1515 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1517 if (!link_info
->keep_memory
)
1521 /* Cache the section contents for elf_link_input_bfd. */
1522 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1526 if (internal_relocs
!= NULL
1527 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1528 free (internal_relocs
);
1533 if (isymbuf
!= NULL
&& symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1535 if (contents
!= NULL
1536 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1538 if (internal_relocs
!= NULL
1539 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1540 free (internal_relocs
);
1545 /* Free the derived linker hash table. */
1547 pru_elf32_link_hash_table_free (bfd
*obfd
)
1549 _bfd_elf_link_hash_table_free (obfd
);
1552 /* Implement bfd_elf32_bfd_link_hash_table_create. */
1553 static struct bfd_link_hash_table
*
1554 pru_elf32_link_hash_table_create (bfd
*abfd
)
1556 struct elf_link_hash_table
*ret
;
1557 bfd_size_type amt
= sizeof (struct elf_link_hash_table
);
1559 ret
= bfd_zmalloc (amt
);
1563 if (!_bfd_elf_link_hash_table_init (ret
, abfd
,
1566 elf_link_hash_entry
),
1573 ret
->root
.hash_table_free
= pru_elf32_link_hash_table_free
;
1578 #define ELF_ARCH bfd_arch_pru
1579 #define ELF_TARGET_ID PRU_ELF_DATA
1580 #define ELF_MACHINE_CODE EM_TI_PRU
1582 #define ELF_MAXPAGESIZE 1
1584 #define bfd_elf32_bfd_link_hash_table_create \
1585 pru_elf32_link_hash_table_create
1587 /* Relocation table lookup macros. */
1589 #define bfd_elf32_bfd_reloc_type_lookup pru_elf32_bfd_reloc_type_lookup
1590 #define bfd_elf32_bfd_reloc_name_lookup pru_elf32_bfd_reloc_name_lookup
1592 #define elf_info_to_howto pru_elf32_info_to_howto
1593 #define elf_info_to_howto_rel NULL
1595 /* elf backend functions. */
1597 /* TI folks like to use a mix of REL and RELA relocations. See also
1598 the MSP430 and TI C6X backends. */
1599 #define elf_backend_may_use_rel_p 1
1600 #define elf_backend_may_use_rela_p 1
1601 #define elf_backend_default_use_rela_p 1
1603 #define elf_backend_rela_normal 1
1605 #define elf_backend_relocate_section pru_elf32_relocate_section
1606 #define bfd_elf32_bfd_relax_section pru_elf32_relax_section
1608 #define TARGET_LITTLE_SYM pru_elf32_vec
1609 #define TARGET_LITTLE_NAME "elf32-pru"
1611 #include "elf32-target.h"