1 /* SPU specific support for 32-bit ELF
3 Copyright 2006, 2007 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
27 #include "elf32-spu.h"
29 /* We use RELA style relocs. Don't define USE_REL. */
31 static bfd_reloc_status_type
spu_elf_rel9 (bfd
*, arelent
*, asymbol
*,
35 /* Values of type 'enum elf_spu_reloc_type' are used to index this
36 array, so it must be declared in the order of that type. */
38 static reloc_howto_type elf_howto_table
[] = {
39 HOWTO (R_SPU_NONE
, 0, 0, 0, FALSE
, 0, complain_overflow_dont
,
40 bfd_elf_generic_reloc
, "SPU_NONE",
41 FALSE
, 0, 0x00000000, FALSE
),
42 HOWTO (R_SPU_ADDR10
, 4, 2, 10, FALSE
, 14, complain_overflow_bitfield
,
43 bfd_elf_generic_reloc
, "SPU_ADDR10",
44 FALSE
, 0, 0x00ffc000, FALSE
),
45 HOWTO (R_SPU_ADDR16
, 2, 2, 16, FALSE
, 7, complain_overflow_bitfield
,
46 bfd_elf_generic_reloc
, "SPU_ADDR16",
47 FALSE
, 0, 0x007fff80, FALSE
),
48 HOWTO (R_SPU_ADDR16_HI
, 16, 2, 16, FALSE
, 7, complain_overflow_bitfield
,
49 bfd_elf_generic_reloc
, "SPU_ADDR16_HI",
50 FALSE
, 0, 0x007fff80, FALSE
),
51 HOWTO (R_SPU_ADDR16_LO
, 0, 2, 16, FALSE
, 7, complain_overflow_dont
,
52 bfd_elf_generic_reloc
, "SPU_ADDR16_LO",
53 FALSE
, 0, 0x007fff80, FALSE
),
54 HOWTO (R_SPU_ADDR18
, 0, 2, 18, FALSE
, 7, complain_overflow_bitfield
,
55 bfd_elf_generic_reloc
, "SPU_ADDR18",
56 FALSE
, 0, 0x01ffff80, FALSE
),
57 HOWTO (R_SPU_ADDR32
, 0, 2, 32, FALSE
, 0, complain_overflow_dont
,
58 bfd_elf_generic_reloc
, "SPU_ADDR32",
59 FALSE
, 0, 0xffffffff, FALSE
),
60 HOWTO (R_SPU_REL16
, 2, 2, 16, TRUE
, 7, complain_overflow_bitfield
,
61 bfd_elf_generic_reloc
, "SPU_REL16",
62 FALSE
, 0, 0x007fff80, TRUE
),
63 HOWTO (R_SPU_ADDR7
, 0, 2, 7, FALSE
, 14, complain_overflow_dont
,
64 bfd_elf_generic_reloc
, "SPU_ADDR7",
65 FALSE
, 0, 0x001fc000, FALSE
),
66 HOWTO (R_SPU_REL9
, 2, 2, 9, TRUE
, 0, complain_overflow_signed
,
67 spu_elf_rel9
, "SPU_REL9",
68 FALSE
, 0, 0x0180007f, TRUE
),
69 HOWTO (R_SPU_REL9I
, 2, 2, 9, TRUE
, 0, complain_overflow_signed
,
70 spu_elf_rel9
, "SPU_REL9I",
71 FALSE
, 0, 0x0000c07f, TRUE
),
72 HOWTO (R_SPU_ADDR10I
, 0, 2, 10, FALSE
, 14, complain_overflow_signed
,
73 bfd_elf_generic_reloc
, "SPU_ADDR10I",
74 FALSE
, 0, 0x00ffc000, FALSE
),
75 HOWTO (R_SPU_ADDR16I
, 0, 2, 16, FALSE
, 7, complain_overflow_signed
,
76 bfd_elf_generic_reloc
, "SPU_ADDR16I",
77 FALSE
, 0, 0x007fff80, FALSE
),
78 HOWTO (R_SPU_REL32
, 0, 2, 32, TRUE
, 0, complain_overflow_dont
,
79 bfd_elf_generic_reloc
, "SPU_REL32",
80 FALSE
, 0, 0xffffffff, TRUE
),
83 static struct bfd_elf_special_section
const spu_elf_special_sections
[] = {
84 { ".toe", 4, 0, SHT_NOBITS
, SHF_ALLOC
},
88 static enum elf_spu_reloc_type
89 spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code
)
95 case BFD_RELOC_SPU_IMM10W
:
97 case BFD_RELOC_SPU_IMM16W
:
99 case BFD_RELOC_SPU_LO16
:
100 return R_SPU_ADDR16_LO
;
101 case BFD_RELOC_SPU_HI16
:
102 return R_SPU_ADDR16_HI
;
103 case BFD_RELOC_SPU_IMM18
:
105 case BFD_RELOC_SPU_PCREL16
:
107 case BFD_RELOC_SPU_IMM7
:
109 case BFD_RELOC_SPU_IMM8
:
111 case BFD_RELOC_SPU_PCREL9a
:
113 case BFD_RELOC_SPU_PCREL9b
:
115 case BFD_RELOC_SPU_IMM10
:
116 return R_SPU_ADDR10I
;
117 case BFD_RELOC_SPU_IMM16
:
118 return R_SPU_ADDR16I
;
121 case BFD_RELOC_32_PCREL
:
127 spu_elf_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
129 Elf_Internal_Rela
*dst
)
131 enum elf_spu_reloc_type r_type
;
133 r_type
= (enum elf_spu_reloc_type
) ELF32_R_TYPE (dst
->r_info
);
134 BFD_ASSERT (r_type
< R_SPU_max
);
135 cache_ptr
->howto
= &elf_howto_table
[(int) r_type
];
138 static reloc_howto_type
*
139 spu_elf_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
140 bfd_reloc_code_real_type code
)
142 return elf_howto_table
+ spu_elf_bfd_to_reloc_type (code
);
145 /* Apply R_SPU_REL9 and R_SPU_REL9I relocs. */
147 static bfd_reloc_status_type
148 spu_elf_rel9 (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
149 void *data
, asection
*input_section
,
150 bfd
*output_bfd
, char **error_message
)
152 bfd_size_type octets
;
156 /* If this is a relocatable link (output_bfd test tells us), just
157 call the generic function. Any adjustment will be done at final
159 if (output_bfd
!= NULL
)
160 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
161 input_section
, output_bfd
, error_message
);
163 if (reloc_entry
->address
> bfd_get_section_limit (abfd
, input_section
))
164 return bfd_reloc_outofrange
;
165 octets
= reloc_entry
->address
* bfd_octets_per_byte (abfd
);
167 /* Get symbol value. */
169 if (!bfd_is_com_section (symbol
->section
))
171 if (symbol
->section
->output_section
)
172 val
+= symbol
->section
->output_section
->vma
;
174 val
+= reloc_entry
->addend
;
176 /* Make it pc-relative. */
177 val
-= input_section
->output_section
->vma
+ input_section
->output_offset
;
180 if (val
+ 256 >= 512)
181 return bfd_reloc_overflow
;
183 insn
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
185 /* Move two high bits of value to REL9I and REL9 position.
186 The mask will take care of selecting the right field. */
187 val
= (val
& 0x7f) | ((val
& 0x180) << 7) | ((val
& 0x180) << 16);
188 insn
&= ~reloc_entry
->howto
->dst_mask
;
189 insn
|= val
& reloc_entry
->howto
->dst_mask
;
190 bfd_put_32 (abfd
, insn
, (bfd_byte
*) data
+ octets
);
195 spu_elf_new_section_hook (bfd
*abfd
, asection
*sec
)
197 if (!sec
->used_by_bfd
)
199 struct _spu_elf_section_data
*sdata
;
201 sdata
= bfd_zalloc (abfd
, sizeof (*sdata
));
204 sec
->used_by_bfd
= sdata
;
207 return _bfd_elf_new_section_hook (abfd
, sec
);
210 /* Specially mark defined symbols named _EAR_* with BSF_KEEP so that
211 strip --strip-unneeded will not remove them. */
214 spu_elf_backend_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
, asymbol
*sym
)
216 if (sym
->name
!= NULL
217 && sym
->section
!= bfd_abs_section_ptr
218 && strncmp (sym
->name
, "_EAR_", 5) == 0)
219 sym
->flags
|= BSF_KEEP
;
222 /* SPU ELF linker hash table. */
224 struct spu_link_hash_table
226 struct elf_link_hash_table elf
;
228 /* The stub hash table. */
229 struct bfd_hash_table stub_hash_table
;
231 /* Shortcuts to overlay sections. */
235 struct elf_link_hash_entry
*ovly_load
;
237 /* An array of two output sections per overlay region, chosen such that
238 the first section vma is the overlay buffer vma (ie. the section has
239 the lowest vma in the group that occupy the region), and the second
240 section vma+size specifies the end of the region. We keep pointers
241 to sections like this because section vmas may change when laying
243 asection
**ovl_region
;
245 /* Number of overlay buffers. */
246 unsigned int num_buf
;
248 /* Total number of overlays. */
249 unsigned int num_overlays
;
251 /* Set if we should emit symbols for stubs. */
252 unsigned int emit_stub_syms
:1;
254 /* Set if we want stubs on calls out of overlay regions to
255 non-overlay regions. */
256 unsigned int non_overlay_stubs
: 1;
259 unsigned int stub_overflow
: 1;
262 #define spu_hash_table(p) \
263 ((struct spu_link_hash_table *) ((p)->hash))
265 struct spu_stub_hash_entry
267 struct bfd_hash_entry root
;
269 /* Destination of this stub. */
270 asection
*target_section
;
273 /* Offset of entry in stub section. */
276 /* Offset from this stub to stub that loads the overlay index. */
280 /* Create an entry in a spu stub hash table. */
282 static struct bfd_hash_entry
*
283 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
284 struct bfd_hash_table
*table
,
287 /* Allocate the structure if it has not already been allocated by a
291 entry
= bfd_hash_allocate (table
, sizeof (struct spu_stub_hash_entry
));
296 /* Call the allocation method of the superclass. */
297 entry
= bfd_hash_newfunc (entry
, table
, string
);
300 struct spu_stub_hash_entry
*sh
= (struct spu_stub_hash_entry
*) entry
;
302 sh
->target_section
= NULL
;
311 /* Create a spu ELF linker hash table. */
313 static struct bfd_link_hash_table
*
314 spu_elf_link_hash_table_create (bfd
*abfd
)
316 struct spu_link_hash_table
*htab
;
318 htab
= bfd_malloc (sizeof (*htab
));
322 if (!_bfd_elf_link_hash_table_init (&htab
->elf
, abfd
,
323 _bfd_elf_link_hash_newfunc
,
324 sizeof (struct elf_link_hash_entry
)))
330 /* Init the stub hash table too. */
331 if (!bfd_hash_table_init (&htab
->stub_hash_table
, stub_hash_newfunc
,
332 sizeof (struct spu_stub_hash_entry
)))
335 memset (&htab
->stub
, 0,
336 sizeof (*htab
) - offsetof (struct spu_link_hash_table
, stub
));
338 return &htab
->elf
.root
;
341 /* Free the derived linker hash table. */
344 spu_elf_link_hash_table_free (struct bfd_link_hash_table
*hash
)
346 struct spu_link_hash_table
*ret
= (struct spu_link_hash_table
*) hash
;
348 bfd_hash_table_free (&ret
->stub_hash_table
);
349 _bfd_generic_link_hash_table_free (hash
);
352 /* Find the symbol for the given R_SYMNDX in IBFD and set *HP and *SYMP
353 to (hash, NULL) for global symbols, and (NULL, sym) for locals. Set
354 *SYMSECP to the symbol's section. *LOCSYMSP caches local syms. */
357 get_sym_h (struct elf_link_hash_entry
**hp
,
358 Elf_Internal_Sym
**symp
,
360 Elf_Internal_Sym
**locsymsp
,
361 unsigned long r_symndx
,
364 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
366 if (r_symndx
>= symtab_hdr
->sh_info
)
368 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (ibfd
);
369 struct elf_link_hash_entry
*h
;
371 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
372 while (h
->root
.type
== bfd_link_hash_indirect
373 || h
->root
.type
== bfd_link_hash_warning
)
374 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
384 asection
*symsec
= NULL
;
385 if (h
->root
.type
== bfd_link_hash_defined
386 || h
->root
.type
== bfd_link_hash_defweak
)
387 symsec
= h
->root
.u
.def
.section
;
393 Elf_Internal_Sym
*sym
;
394 Elf_Internal_Sym
*locsyms
= *locsymsp
;
398 locsyms
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
400 locsyms
= bfd_elf_get_elf_syms (ibfd
, symtab_hdr
,
402 0, NULL
, NULL
, NULL
);
407 sym
= locsyms
+ r_symndx
;
417 asection
*symsec
= NULL
;
418 if ((sym
->st_shndx
!= SHN_UNDEF
419 && sym
->st_shndx
< SHN_LORESERVE
)
420 || sym
->st_shndx
> SHN_HIRESERVE
)
421 symsec
= bfd_section_from_elf_index (ibfd
, sym
->st_shndx
);
428 /* Build a name for an entry in the stub hash table. We can't use a
429 local symbol name because ld -r might generate duplicate local symbols. */
432 spu_stub_name (const asection
*sym_sec
,
433 const struct elf_link_hash_entry
*h
,
434 const Elf_Internal_Rela
*rel
)
441 len
= strlen (h
->root
.root
.string
) + 1 + 8 + 1;
442 stub_name
= bfd_malloc (len
);
443 if (stub_name
== NULL
)
446 sprintf (stub_name
, "%s+%x",
448 (int) rel
->r_addend
& 0xffffffff);
453 len
= 8 + 1 + 8 + 1 + 8 + 1;
454 stub_name
= bfd_malloc (len
);
455 if (stub_name
== NULL
)
458 sprintf (stub_name
, "%x:%x+%x",
459 sym_sec
->id
& 0xffffffff,
460 (int) ELF32_R_SYM (rel
->r_info
) & 0xffffffff,
461 (int) rel
->r_addend
& 0xffffffff);
462 len
= strlen (stub_name
);
465 if (stub_name
[len
- 2] == '+'
466 && stub_name
[len
- 1] == '0'
467 && stub_name
[len
] == 0)
468 stub_name
[len
- 2] = 0;
473 /* Create the note section if not already present. This is done early so
474 that the linker maps the sections to the right place in the output. */
477 spu_elf_create_sections (bfd
*output_bfd
, struct bfd_link_info
*info
)
481 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->next
)
482 if (bfd_get_section_by_name (ibfd
, SPU_PTNOTE_SPUNAME
) != NULL
)
487 /* Make SPU_PTNOTE_SPUNAME section. */
494 ibfd
= info
->input_bfds
;
495 flags
= SEC_LOAD
| SEC_READONLY
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
496 s
= bfd_make_section_anyway_with_flags (ibfd
, SPU_PTNOTE_SPUNAME
, flags
);
498 || !bfd_set_section_alignment (ibfd
, s
, 4))
501 name_len
= strlen (bfd_get_filename (output_bfd
)) + 1;
502 size
= 12 + ((sizeof (SPU_PLUGIN_NAME
) + 3) & -4);
503 size
+= (name_len
+ 3) & -4;
505 if (!bfd_set_section_size (ibfd
, s
, size
))
508 data
= bfd_zalloc (ibfd
, size
);
512 bfd_put_32 (ibfd
, sizeof (SPU_PLUGIN_NAME
), data
+ 0);
513 bfd_put_32 (ibfd
, name_len
, data
+ 4);
514 bfd_put_32 (ibfd
, 1, data
+ 8);
515 memcpy (data
+ 12, SPU_PLUGIN_NAME
, sizeof (SPU_PLUGIN_NAME
));
516 memcpy (data
+ 12 + ((sizeof (SPU_PLUGIN_NAME
) + 3) & -4),
517 bfd_get_filename (output_bfd
), name_len
);
524 /* Return the section that should be marked against GC for a given
528 spu_elf_gc_mark_hook (asection
*sec
,
529 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
530 Elf_Internal_Rela
*rel ATTRIBUTE_UNUSED
,
531 struct elf_link_hash_entry
*h
,
532 Elf_Internal_Sym
*sym
)
536 switch (h
->root
.type
)
538 case bfd_link_hash_defined
:
539 case bfd_link_hash_defweak
:
540 return h
->root
.u
.def
.section
;
542 case bfd_link_hash_common
:
543 return h
->root
.u
.c
.p
->section
;
550 return bfd_section_from_elf_index (sec
->owner
, sym
->st_shndx
);
555 /* qsort predicate to sort sections by vma. */
558 sort_sections (const void *a
, const void *b
)
560 const asection
*const *s1
= a
;
561 const asection
*const *s2
= b
;
562 bfd_signed_vma delta
= (*s1
)->vma
- (*s2
)->vma
;
565 return delta
< 0 ? -1 : 1;
567 return (*s1
)->index
- (*s2
)->index
;
570 /* Identify overlays in the output bfd, and number them. */
573 spu_elf_find_overlays (bfd
*output_bfd
, struct bfd_link_info
*info
)
575 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
576 asection
**alloc_sec
;
577 unsigned int i
, n
, ovl_index
, num_buf
;
581 if (output_bfd
->section_count
< 2)
584 alloc_sec
= bfd_malloc (output_bfd
->section_count
* sizeof (*alloc_sec
));
585 if (alloc_sec
== NULL
)
588 /* Pick out all the alloced sections. */
589 for (n
= 0, s
= output_bfd
->sections
; s
!= NULL
; s
= s
->next
)
590 if ((s
->flags
& SEC_ALLOC
) != 0
591 && (s
->flags
& (SEC_LOAD
| SEC_THREAD_LOCAL
)) != SEC_THREAD_LOCAL
601 /* Sort them by vma. */
602 qsort (alloc_sec
, n
, sizeof (*alloc_sec
), sort_sections
);
604 /* Look for overlapping vmas. Any with overlap must be overlays.
605 Count them. Also count the number of overlay regions and for
606 each region save a section from that region with the lowest vma
607 and another section with the highest end vma. */
608 ovl_end
= alloc_sec
[0]->vma
+ alloc_sec
[0]->size
;
609 for (ovl_index
= 0, num_buf
= 0, i
= 1; i
< n
; i
++)
612 if (s
->vma
< ovl_end
)
614 asection
*s0
= alloc_sec
[i
- 1];
616 if (spu_elf_section_data (s0
)->ovl_index
== 0)
618 spu_elf_section_data (s0
)->ovl_index
= ++ovl_index
;
619 alloc_sec
[num_buf
* 2] = s0
;
620 alloc_sec
[num_buf
* 2 + 1] = s0
;
623 spu_elf_section_data (s
)->ovl_index
= ++ovl_index
;
624 if (ovl_end
< s
->vma
+ s
->size
)
626 ovl_end
= s
->vma
+ s
->size
;
627 alloc_sec
[num_buf
* 2 - 1] = s
;
631 ovl_end
= s
->vma
+ s
->size
;
634 htab
->num_overlays
= ovl_index
;
635 htab
->num_buf
= num_buf
;
642 alloc_sec
= bfd_realloc (alloc_sec
, num_buf
* 2 * sizeof (*alloc_sec
));
643 if (alloc_sec
== NULL
)
646 htab
->ovl_region
= alloc_sec
;
650 /* One of these per stub. */
651 #define SIZEOF_STUB1 8
652 #define ILA_79 0x4200004f /* ila $79,function_address */
653 #define BR 0x32000000 /* br stub2 */
655 /* One of these per overlay. */
656 #define SIZEOF_STUB2 8
657 #define ILA_78 0x4200004e /* ila $78,overlay_number */
659 #define NOP 0x40200000
661 /* Return true for all relative and absolute branch and hint instructions.
674 is_branch (const unsigned char *insn
)
676 return (((insn
[0] & 0xec) == 0x20 && (insn
[1] & 0x80) == 0)
677 || (insn
[0] & 0xfc) == 0x10);
680 /* Return TRUE if this reloc symbol should possibly go via an overlay stub. */
683 needs_ovl_stub (const char *sym_name
,
685 asection
*input_section
,
686 struct spu_link_hash_table
*htab
,
687 bfd_boolean is_branch
)
689 if (htab
->num_overlays
== 0)
693 || sym_sec
->output_section
== NULL
)
696 /* setjmp always goes via an overlay stub, because then the return
697 and hence the longjmp goes via __ovly_return. That magically
698 makes setjmp/longjmp between overlays work. */
699 if (strncmp (sym_name
, "setjmp", 6) == 0
700 && (sym_name
[6] == '\0' || sym_name
[6] == '@'))
703 /* Usually, symbols in non-overlay sections don't need stubs. */
704 if (spu_elf_section_data (sym_sec
->output_section
)->ovl_index
== 0
705 && !htab
->non_overlay_stubs
)
708 /* A reference from some other section to a symbol in an overlay
709 section needs a stub. */
710 if (spu_elf_section_data (sym_sec
->output_section
)->ovl_index
711 != spu_elf_section_data (input_section
->output_section
)->ovl_index
)
714 /* If this insn isn't a branch then we are possibly taking the
715 address of a function and passing it out somehow. */
720 struct spu_stub_hash_entry
**sh
;
724 /* Called via bfd_hash_traverse to set up pointers to all symbols
725 in the stub hash table. */
728 populate_stubs (struct bfd_hash_entry
*bh
, void *inf
)
730 struct stubarr
*stubs
= inf
;
732 stubs
->sh
[--stubs
->count
] = (struct spu_stub_hash_entry
*) bh
;
736 /* qsort predicate to sort stubs by overlay number. */
739 sort_stubs (const void *a
, const void *b
)
741 const struct spu_stub_hash_entry
*const *sa
= a
;
742 const struct spu_stub_hash_entry
*const *sb
= b
;
746 i
= spu_elf_section_data ((*sa
)->target_section
->output_section
)->ovl_index
;
747 i
-= spu_elf_section_data ((*sb
)->target_section
->output_section
)->ovl_index
;
751 d
= ((*sa
)->target_section
->output_section
->vma
752 + (*sa
)->target_section
->output_offset
754 - (*sb
)->target_section
->output_section
->vma
755 - (*sb
)->target_section
->output_offset
756 - (*sb
)->target_off
);
758 return d
< 0 ? -1 : 1;
760 /* Two functions at the same address. Aliases perhaps. */
761 i
= strcmp ((*sb
)->root
.string
, (*sa
)->root
.string
);
766 /* Allocate space for overlay call and return stubs. */
769 spu_elf_size_stubs (bfd
*output_bfd
,
770 struct bfd_link_info
*info
,
771 int non_overlay_stubs
,
776 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
778 struct stubarr stubs
;
782 htab
->non_overlay_stubs
= non_overlay_stubs
;
784 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link_next
)
786 extern const bfd_target bfd_elf32_spu_vec
;
787 Elf_Internal_Shdr
*symtab_hdr
;
789 Elf_Internal_Sym
*local_syms
= NULL
;
791 if (ibfd
->xvec
!= &bfd_elf32_spu_vec
)
794 /* We'll need the symbol table in a second. */
795 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
796 if (symtab_hdr
->sh_info
== 0)
799 /* Walk over each section attached to the input bfd. */
800 for (section
= ibfd
->sections
; section
!= NULL
; section
= section
->next
)
802 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
804 /* If there aren't any relocs, then there's nothing more to do. */
805 if ((section
->flags
& SEC_RELOC
) == 0
806 || (section
->flags
& SEC_ALLOC
) == 0
807 || (section
->flags
& SEC_LOAD
) == 0
808 || section
->reloc_count
== 0)
811 /* If this section is a link-once section that will be
812 discarded, then don't create any stubs. */
813 if (section
->output_section
== NULL
814 || section
->output_section
->owner
!= output_bfd
)
817 /* Get the relocs. */
819 = _bfd_elf_link_read_relocs (ibfd
, section
, NULL
, NULL
,
821 if (internal_relocs
== NULL
)
822 goto error_ret_free_local
;
824 /* Now examine each relocation. */
825 irela
= internal_relocs
;
826 irelaend
= irela
+ section
->reloc_count
;
827 for (; irela
< irelaend
; irela
++)
829 enum elf_spu_reloc_type r_type
;
832 Elf_Internal_Sym
*sym
;
833 struct elf_link_hash_entry
*h
;
834 const char *sym_name
;
836 struct spu_stub_hash_entry
*sh
;
837 unsigned int sym_type
;
838 enum _insn_type
{ non_branch
, branch
, call
} insn_type
;
840 r_type
= ELF32_R_TYPE (irela
->r_info
);
841 r_indx
= ELF32_R_SYM (irela
->r_info
);
843 if (r_type
>= R_SPU_max
)
845 bfd_set_error (bfd_error_bad_value
);
846 goto error_ret_free_internal
;
849 /* Determine the reloc target section. */
850 if (!get_sym_h (&h
, &sym
, &sym_sec
, &local_syms
, r_indx
, ibfd
))
851 goto error_ret_free_internal
;
854 || sym_sec
->output_section
== NULL
855 || sym_sec
->output_section
->owner
!= output_bfd
)
858 /* Ensure no stubs for user supplied overlay manager syms. */
860 && (strcmp (h
->root
.root
.string
, "__ovly_load") == 0
861 || strcmp (h
->root
.root
.string
, "__ovly_return") == 0))
864 insn_type
= non_branch
;
865 if (r_type
== R_SPU_REL16
866 || r_type
== R_SPU_ADDR16
)
868 unsigned char insn
[4];
870 if (!bfd_get_section_contents (ibfd
, section
, insn
,
872 goto error_ret_free_internal
;
874 if (is_branch (insn
))
877 if ((insn
[0] & 0xfd) == 0x31)
882 /* We are only interested in function symbols. */
886 sym_name
= h
->root
.root
.string
;
890 sym_type
= ELF_ST_TYPE (sym
->st_info
);
891 sym_name
= bfd_elf_sym_name (sym_sec
->owner
,
896 if (sym_type
!= STT_FUNC
)
898 /* It's common for people to write assembly and forget
899 to give function symbols the right type. Handle
900 calls to such symbols, but warn so that (hopefully)
901 people will fix their code. We need the symbol
902 type to be correct to distinguish function pointer
903 initialisation from other pointer initialisation. */
904 if (insn_type
== call
)
905 (*_bfd_error_handler
) (_("warning: call to non-function"
906 " symbol %s defined in %B"),
907 sym_sec
->owner
, sym_name
);
912 if (!needs_ovl_stub (sym_name
, sym_sec
, section
, htab
,
913 insn_type
!= non_branch
))
916 stub_name
= spu_stub_name (sym_sec
, h
, irela
);
917 if (stub_name
== NULL
)
918 goto error_ret_free_internal
;
920 sh
= (struct spu_stub_hash_entry
*)
921 bfd_hash_lookup (&htab
->stub_hash_table
, stub_name
,
926 error_ret_free_internal
:
927 if (elf_section_data (section
)->relocs
!= internal_relocs
)
928 free (internal_relocs
);
929 error_ret_free_local
:
930 if (local_syms
!= NULL
931 && (symtab_hdr
->contents
932 != (unsigned char *) local_syms
))
937 /* If this entry isn't new, we already have a stub. */
938 if (sh
->target_section
!= NULL
)
944 sh
->target_section
= sym_sec
;
946 sh
->target_off
= h
->root
.u
.def
.value
;
948 sh
->target_off
= sym
->st_value
;
949 sh
->target_off
+= irela
->r_addend
;
954 /* We're done with the internal relocs, free them. */
955 if (elf_section_data (section
)->relocs
!= internal_relocs
)
956 free (internal_relocs
);
959 if (local_syms
!= NULL
960 && symtab_hdr
->contents
!= (unsigned char *) local_syms
)
962 if (!info
->keep_memory
)
965 symtab_hdr
->contents
= (unsigned char *) local_syms
;
970 if (stubs
.count
== 0)
973 ibfd
= info
->input_bfds
;
974 flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_CODE
| SEC_READONLY
975 | SEC_HAS_CONTENTS
| SEC_IN_MEMORY
);
976 htab
->stub
= bfd_make_section_anyway_with_flags (ibfd
, ".stub", flags
);
978 if (htab
->stub
== NULL
979 || !bfd_set_section_alignment (ibfd
, htab
->stub
, 2))
982 flags
= (SEC_ALLOC
| SEC_LOAD
983 | SEC_HAS_CONTENTS
| SEC_IN_MEMORY
);
984 htab
->ovtab
= bfd_make_section_anyway_with_flags (ibfd
, ".ovtab", flags
);
985 *ovtab
= htab
->ovtab
;
986 if (htab
->ovtab
== NULL
987 || !bfd_set_section_alignment (ibfd
, htab
->stub
, 4))
990 *toe
= bfd_make_section_anyway_with_flags (ibfd
, ".toe", SEC_ALLOC
);
992 || !bfd_set_section_alignment (ibfd
, *toe
, 4))
996 /* Retrieve all the stubs and sort. */
997 stubs
.sh
= bfd_malloc (stubs
.count
* sizeof (*stubs
.sh
));
998 if (stubs
.sh
== NULL
)
1001 bfd_hash_traverse (&htab
->stub_hash_table
, populate_stubs
, &stubs
);
1002 BFD_ASSERT (stubs
.count
== 0);
1005 qsort (stubs
.sh
, stubs
.count
, sizeof (*stubs
.sh
), sort_stubs
);
1007 /* Now that the stubs are sorted, place them in the stub section.
1008 Stubs are grouped per overlay
1022 for (i
= 0; i
< stubs
.count
; i
++)
1024 if (spu_elf_section_data (stubs
.sh
[group
]->target_section
1025 ->output_section
)->ovl_index
1026 != spu_elf_section_data (stubs
.sh
[i
]->target_section
1027 ->output_section
)->ovl_index
)
1029 htab
->stub
->size
+= SIZEOF_STUB2
;
1030 for (; group
!= i
; group
++)
1031 stubs
.sh
[group
]->delta
1032 = stubs
.sh
[i
- 1]->off
- stubs
.sh
[group
]->off
;
1035 || ((stubs
.sh
[i
- 1]->target_section
->output_section
->vma
1036 + stubs
.sh
[i
- 1]->target_section
->output_offset
1037 + stubs
.sh
[i
- 1]->target_off
)
1038 != (stubs
.sh
[i
]->target_section
->output_section
->vma
1039 + stubs
.sh
[i
]->target_section
->output_offset
1040 + stubs
.sh
[i
]->target_off
)))
1042 stubs
.sh
[i
]->off
= htab
->stub
->size
;
1043 htab
->stub
->size
+= SIZEOF_STUB1
;
1046 stubs
.sh
[i
]->off
= stubs
.sh
[i
- 1]->off
;
1049 htab
->stub
->size
+= SIZEOF_STUB2
;
1050 for (; group
!= i
; group
++)
1051 stubs
.sh
[group
]->delta
= stubs
.sh
[i
- 1]->off
- stubs
.sh
[group
]->off
;
1053 /* htab->ovtab consists of two arrays.
1063 . } _ovly_buf_table[]; */
1065 htab
->ovtab
->alignment_power
= 4;
1066 htab
->ovtab
->size
= htab
->num_overlays
* 16 + htab
->num_buf
* 4;
1071 /* Functions to handle embedded spu_ovl.o object. */
1074 ovl_mgr_open (struct bfd
*nbfd ATTRIBUTE_UNUSED
, void *stream
)
1080 ovl_mgr_pread (struct bfd
*abfd ATTRIBUTE_UNUSED
,
1086 struct _ovl_stream
*os
;
1090 os
= (struct _ovl_stream
*) stream
;
1091 max
= (const char *) os
->end
- (const char *) os
->start
;
1093 if ((ufile_ptr
) offset
>= max
)
1097 if (count
> max
- offset
)
1098 count
= max
- offset
;
1100 memcpy (buf
, (const char *) os
->start
+ offset
, count
);
1105 spu_elf_open_builtin_lib (bfd
**ovl_bfd
, const struct _ovl_stream
*stream
)
1107 *ovl_bfd
= bfd_openr_iovec ("builtin ovl_mgr",
1114 return *ovl_bfd
!= NULL
;
1117 /* Fill in the ila and br for a stub. On the last stub for a group,
1118 write the stub that sets the overlay number too. */
1121 write_one_stub (struct bfd_hash_entry
*bh
, void *inf
)
1123 struct spu_stub_hash_entry
*ent
= (struct spu_stub_hash_entry
*) bh
;
1124 struct spu_link_hash_table
*htab
= inf
;
1125 asection
*sec
= htab
->stub
;
1126 asection
*s
= ent
->target_section
;
1130 val
= ent
->target_off
+ s
->output_offset
+ s
->output_section
->vma
;
1131 bfd_put_32 (sec
->owner
, ILA_79
+ ((val
<< 7) & 0x01ffff80),
1132 sec
->contents
+ ent
->off
);
1133 val
= ent
->delta
+ 4;
1134 bfd_put_32 (sec
->owner
, BR
+ ((val
<< 5) & 0x007fff80),
1135 sec
->contents
+ ent
->off
+ 4);
1137 /* If this is the last stub of this group, write stub2. */
1138 if (ent
->delta
== 0)
1140 bfd_put_32 (sec
->owner
, NOP
,
1141 sec
->contents
+ ent
->off
+ 4);
1143 ovl
= spu_elf_section_data (s
->output_section
)->ovl_index
;
1144 bfd_put_32 (sec
->owner
, ILA_78
+ ((ovl
<< 7) & 0x01ffff80),
1145 sec
->contents
+ ent
->off
+ 8);
1147 val
= (htab
->ovly_load
->root
.u
.def
.section
->output_section
->vma
1148 + htab
->ovly_load
->root
.u
.def
.section
->output_offset
1149 + htab
->ovly_load
->root
.u
.def
.value
1150 - (sec
->output_section
->vma
1151 + sec
->output_offset
1154 if (val
+ 0x20000 >= 0x40000)
1155 htab
->stub_overflow
= TRUE
;
1157 bfd_put_32 (sec
->owner
, BR
+ ((val
<< 5) & 0x007fff80),
1158 sec
->contents
+ ent
->off
+ 12);
1161 if (htab
->emit_stub_syms
)
1163 struct elf_link_hash_entry
*h
;
1167 len1
= sizeof ("00000000.ovl_call.") - 1;
1168 len2
= strlen (ent
->root
.string
);
1169 name
= bfd_malloc (len1
+ len2
+ 1);
1172 memcpy (name
, "00000000.ovl_call.", len1
);
1173 memcpy (name
+ len1
, ent
->root
.string
, len2
+ 1);
1174 h
= elf_link_hash_lookup (&htab
->elf
, name
, TRUE
, FALSE
, FALSE
);
1177 if (h
->root
.type
== bfd_link_hash_new
)
1179 h
->root
.type
= bfd_link_hash_defined
;
1180 h
->root
.u
.def
.section
= sec
;
1181 h
->root
.u
.def
.value
= ent
->off
;
1182 h
->size
= (ent
->delta
== 0
1183 ? SIZEOF_STUB1
+ SIZEOF_STUB2
: SIZEOF_STUB1
);
1187 h
->ref_regular_nonweak
= 1;
1188 h
->forced_local
= 1;
1196 /* Define an STT_OBJECT symbol. */
1198 static struct elf_link_hash_entry
*
1199 define_ovtab_symbol (struct spu_link_hash_table
*htab
, const char *name
)
1201 struct elf_link_hash_entry
*h
;
1203 h
= elf_link_hash_lookup (&htab
->elf
, name
, TRUE
, FALSE
, FALSE
);
1207 if (h
->root
.type
!= bfd_link_hash_defined
1210 h
->root
.type
= bfd_link_hash_defined
;
1211 h
->root
.u
.def
.section
= htab
->ovtab
;
1212 h
->type
= STT_OBJECT
;
1215 h
->ref_regular_nonweak
= 1;
1220 (*_bfd_error_handler
) (_("%B is not allowed to define %s"),
1221 h
->root
.u
.def
.section
->owner
,
1222 h
->root
.root
.string
);
1223 bfd_set_error (bfd_error_bad_value
);
1230 /* Fill in all stubs and the overlay tables. */
1233 spu_elf_build_stubs (struct bfd_link_info
*info
, int emit_syms
, asection
*toe
)
1235 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
1236 struct elf_link_hash_entry
*h
;
1242 htab
->emit_stub_syms
= emit_syms
;
1243 htab
->stub
->contents
= bfd_zalloc (htab
->stub
->owner
, htab
->stub
->size
);
1244 if (htab
->stub
->contents
== NULL
)
1247 h
= elf_link_hash_lookup (&htab
->elf
, "__ovly_load", FALSE
, FALSE
, FALSE
);
1248 htab
->ovly_load
= h
;
1249 BFD_ASSERT (h
!= NULL
1250 && (h
->root
.type
== bfd_link_hash_defined
1251 || h
->root
.type
== bfd_link_hash_defweak
)
1254 s
= h
->root
.u
.def
.section
->output_section
;
1255 if (spu_elf_section_data (s
)->ovl_index
)
1257 (*_bfd_error_handler
) (_("%s in overlay section"),
1258 h
->root
.u
.def
.section
->owner
);
1259 bfd_set_error (bfd_error_bad_value
);
1263 /* Write out all the stubs. */
1264 bfd_hash_traverse (&htab
->stub_hash_table
, write_one_stub
, htab
);
1266 if (htab
->stub_overflow
)
1268 (*_bfd_error_handler
) (_("overlay stub relocation overflow"));
1269 bfd_set_error (bfd_error_bad_value
);
1273 htab
->ovtab
->contents
= bfd_zalloc (htab
->ovtab
->owner
, htab
->ovtab
->size
);
1274 if (htab
->ovtab
->contents
== NULL
)
1277 /* Write out _ovly_table. */
1278 p
= htab
->ovtab
->contents
;
1279 obfd
= htab
->ovtab
->output_section
->owner
;
1280 for (s
= obfd
->sections
; s
!= NULL
; s
= s
->next
)
1282 unsigned int ovl_index
= spu_elf_section_data (s
)->ovl_index
;
1286 unsigned int lo
, hi
, mid
;
1287 unsigned long off
= (ovl_index
- 1) * 16;
1288 bfd_put_32 (htab
->ovtab
->owner
, s
->vma
, p
+ off
);
1289 bfd_put_32 (htab
->ovtab
->owner
, (s
->size
+ 15) & -16, p
+ off
+ 4);
1290 /* file_off written later in spu_elf_modify_program_headers. */
1296 mid
= (lo
+ hi
) >> 1;
1297 if (htab
->ovl_region
[2 * mid
+ 1]->vma
1298 + htab
->ovl_region
[2 * mid
+ 1]->size
<= s
->vma
)
1300 else if (htab
->ovl_region
[2 * mid
]->vma
> s
->vma
)
1304 bfd_put_32 (htab
->ovtab
->owner
, mid
+ 1, p
+ off
+ 12);
1308 BFD_ASSERT (lo
< hi
);
1312 /* Write out _ovly_buf_table. */
1313 p
= htab
->ovtab
->contents
+ htab
->num_overlays
* 16;
1314 for (i
= 0; i
< htab
->num_buf
; i
++)
1316 bfd_put_32 (htab
->ovtab
->owner
, 0, p
);
1320 h
= define_ovtab_symbol (htab
, "_ovly_table");
1323 h
->root
.u
.def
.value
= 0;
1324 h
->size
= htab
->num_overlays
* 16;
1326 h
= define_ovtab_symbol (htab
, "_ovly_table_end");
1329 h
->root
.u
.def
.value
= htab
->num_overlays
* 16;
1332 h
= define_ovtab_symbol (htab
, "_ovly_buf_table");
1335 h
->root
.u
.def
.value
= htab
->num_overlays
* 16;
1336 h
->size
= htab
->num_buf
* 4;
1338 h
= define_ovtab_symbol (htab
, "_ovly_buf_table_end");
1341 h
->root
.u
.def
.value
= htab
->num_overlays
* 16 + htab
->num_buf
* 4;
1344 h
= define_ovtab_symbol (htab
, "_EAR_");
1347 h
->root
.u
.def
.section
= toe
;
1348 h
->root
.u
.def
.value
= 0;
1354 /* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
1357 spu_elf_relocate_section (bfd
*output_bfd
,
1358 struct bfd_link_info
*info
,
1360 asection
*input_section
,
1362 Elf_Internal_Rela
*relocs
,
1363 Elf_Internal_Sym
*local_syms
,
1364 asection
**local_sections
)
1366 Elf_Internal_Shdr
*symtab_hdr
;
1367 struct elf_link_hash_entry
**sym_hashes
;
1368 Elf_Internal_Rela
*rel
, *relend
;
1369 struct spu_link_hash_table
*htab
;
1370 bfd_boolean ret
= TRUE
;
1372 htab
= spu_hash_table (info
);
1373 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
1374 sym_hashes
= (struct elf_link_hash_entry
**) (elf_sym_hashes (input_bfd
));
1377 relend
= relocs
+ input_section
->reloc_count
;
1378 for (; rel
< relend
; rel
++)
1381 reloc_howto_type
*howto
;
1382 unsigned long r_symndx
;
1383 Elf_Internal_Sym
*sym
;
1385 struct elf_link_hash_entry
*h
;
1386 const char *sym_name
;
1389 bfd_reloc_status_type r
;
1390 bfd_boolean unresolved_reloc
;
1393 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1394 r_type
= ELF32_R_TYPE (rel
->r_info
);
1395 howto
= elf_howto_table
+ r_type
;
1396 unresolved_reloc
= FALSE
;
1402 if (r_symndx
< symtab_hdr
->sh_info
)
1404 sym
= local_syms
+ r_symndx
;
1405 sec
= local_sections
[r_symndx
];
1406 sym_name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
, sec
);
1407 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1411 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1412 r_symndx
, symtab_hdr
, sym_hashes
,
1414 unresolved_reloc
, warned
);
1415 sym_name
= h
->root
.root
.string
;
1418 if (sec
!= NULL
&& elf_discarded_section (sec
))
1420 /* For relocs against symbols from removed linkonce sections,
1421 or sections discarded by a linker script, we just want the
1422 section contents zeroed. Avoid any special processing. */
1423 _bfd_clear_contents (howto
, input_bfd
, contents
+ rel
->r_offset
);
1429 if (info
->relocatable
)
1432 if (unresolved_reloc
)
1434 (*_bfd_error_handler
)
1435 (_("%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
1437 bfd_get_section_name (input_bfd
, input_section
),
1438 (long) rel
->r_offset
,
1444 /* If this symbol is in an overlay area, we may need to relocate
1445 to the overlay stub. */
1446 addend
= rel
->r_addend
;
1447 if (needs_ovl_stub (sym_name
, sec
, input_section
, htab
,
1448 is_branch (contents
+ rel
->r_offset
)))
1451 struct spu_stub_hash_entry
*sh
;
1453 stub_name
= spu_stub_name (sec
, h
, rel
);
1454 if (stub_name
== NULL
)
1457 sh
= (struct spu_stub_hash_entry
*)
1458 bfd_hash_lookup (&htab
->stub_hash_table
, stub_name
, FALSE
, FALSE
);
1461 relocation
= (htab
->stub
->output_section
->vma
1462 + htab
->stub
->output_offset
1469 r
= _bfd_final_link_relocate (howto
,
1473 rel
->r_offset
, relocation
, addend
);
1475 if (r
!= bfd_reloc_ok
)
1477 const char *msg
= (const char *) 0;
1481 case bfd_reloc_overflow
:
1482 if (!((*info
->callbacks
->reloc_overflow
)
1483 (info
, (h
? &h
->root
: NULL
), sym_name
, howto
->name
,
1484 (bfd_vma
) 0, input_bfd
, input_section
, rel
->r_offset
)))
1488 case bfd_reloc_undefined
:
1489 if (!((*info
->callbacks
->undefined_symbol
)
1490 (info
, sym_name
, input_bfd
, input_section
,
1491 rel
->r_offset
, TRUE
)))
1495 case bfd_reloc_outofrange
:
1496 msg
= _("internal error: out of range error");
1499 case bfd_reloc_notsupported
:
1500 msg
= _("internal error: unsupported relocation error");
1503 case bfd_reloc_dangerous
:
1504 msg
= _("internal error: dangerous error");
1508 msg
= _("internal error: unknown error");
1512 if (!((*info
->callbacks
->warning
)
1513 (info
, msg
, sym_name
, input_bfd
, input_section
,
1524 static int spu_plugin
= 0;
1527 spu_elf_plugin (int val
)
1532 /* Set ELF header e_type for plugins. */
1535 spu_elf_post_process_headers (bfd
*abfd
,
1536 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1540 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
1542 i_ehdrp
->e_type
= ET_DYN
;
1546 /* We may add an extra PT_LOAD segment for .toe. We also need extra
1547 segments for overlays. */
1550 spu_elf_additional_program_headers (bfd
*abfd
, struct bfd_link_info
*info
)
1552 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
1553 int extra
= htab
->num_overlays
;
1559 sec
= bfd_get_section_by_name (abfd
, ".toe");
1560 if (sec
!= NULL
&& (sec
->flags
& SEC_LOAD
) != 0)
1566 /* Remove .toe section from other PT_LOAD segments and put it in
1567 a segment of its own. Put overlays in separate segments too. */
1570 spu_elf_modify_segment_map (bfd
*abfd
, struct bfd_link_info
*info
)
1573 struct elf_segment_map
*m
;
1579 toe
= bfd_get_section_by_name (abfd
, ".toe");
1580 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1581 if (m
->p_type
== PT_LOAD
&& m
->count
> 1)
1582 for (i
= 0; i
< m
->count
; i
++)
1583 if ((s
= m
->sections
[i
]) == toe
1584 || spu_elf_section_data (s
)->ovl_index
!= 0)
1586 struct elf_segment_map
*m2
;
1589 if (i
+ 1 < m
->count
)
1591 amt
= sizeof (struct elf_segment_map
);
1592 amt
+= (m
->count
- (i
+ 2)) * sizeof (m
->sections
[0]);
1593 m2
= bfd_zalloc (abfd
, amt
);
1596 m2
->count
= m
->count
- (i
+ 1);
1597 memcpy (m2
->sections
, m
->sections
+ i
+ 1,
1598 m2
->count
* sizeof (m
->sections
[0]));
1599 m2
->p_type
= PT_LOAD
;
1607 amt
= sizeof (struct elf_segment_map
);
1608 m2
= bfd_zalloc (abfd
, amt
);
1611 m2
->p_type
= PT_LOAD
;
1613 m2
->sections
[0] = s
;
1623 /* Check that all loadable section VMAs lie in the range
1624 LO .. HI inclusive. */
1627 spu_elf_check_vma (bfd
*abfd
, bfd_vma lo
, bfd_vma hi
)
1629 struct elf_segment_map
*m
;
1632 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1633 if (m
->p_type
== PT_LOAD
)
1634 for (i
= 0; i
< m
->count
; i
++)
1635 if (m
->sections
[i
]->size
!= 0
1636 && (m
->sections
[i
]->vma
< lo
1637 || m
->sections
[i
]->vma
> hi
1638 || m
->sections
[i
]->vma
+ m
->sections
[i
]->size
- 1 > hi
))
1639 return m
->sections
[i
];
1644 /* Tweak phdrs before writing them out. */
1647 spu_elf_modify_program_headers (bfd
*abfd
, struct bfd_link_info
*info
)
1649 const struct elf_backend_data
*bed
;
1650 struct elf_obj_tdata
*tdata
;
1651 Elf_Internal_Phdr
*phdr
, *last
;
1652 struct spu_link_hash_table
*htab
;
1659 bed
= get_elf_backend_data (abfd
);
1660 tdata
= elf_tdata (abfd
);
1662 count
= tdata
->program_header_size
/ bed
->s
->sizeof_phdr
;
1663 htab
= spu_hash_table (info
);
1664 if (htab
->num_overlays
!= 0)
1666 struct elf_segment_map
*m
;
1669 for (i
= 0, m
= elf_tdata (abfd
)->segment_map
; m
; ++i
, m
= m
->next
)
1671 && (o
= spu_elf_section_data (m
->sections
[0])->ovl_index
) != 0)
1673 /* Mark this as an overlay header. */
1674 phdr
[i
].p_flags
|= PF_OVERLAY
;
1676 if (htab
->ovtab
!= NULL
&& htab
->ovtab
->size
!= 0)
1678 bfd_byte
*p
= htab
->ovtab
->contents
;
1679 unsigned int off
= (o
- 1) * 16 + 8;
1681 /* Write file_off into _ovly_table. */
1682 bfd_put_32 (htab
->ovtab
->owner
, phdr
[i
].p_offset
, p
+ off
);
1687 /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples
1688 of 16. This should always be possible when using the standard
1689 linker scripts, but don't create overlapping segments if
1690 someone is playing games with linker scripts. */
1692 for (i
= count
; i
-- != 0; )
1693 if (phdr
[i
].p_type
== PT_LOAD
)
1697 adjust
= -phdr
[i
].p_filesz
& 15;
1700 && phdr
[i
].p_offset
+ phdr
[i
].p_filesz
> last
->p_offset
- adjust
)
1703 adjust
= -phdr
[i
].p_memsz
& 15;
1706 && phdr
[i
].p_filesz
!= 0
1707 && phdr
[i
].p_vaddr
+ phdr
[i
].p_memsz
> last
->p_vaddr
- adjust
1708 && phdr
[i
].p_vaddr
+ phdr
[i
].p_memsz
<= last
->p_vaddr
)
1711 if (phdr
[i
].p_filesz
!= 0)
1715 if (i
== (unsigned int) -1)
1716 for (i
= count
; i
-- != 0; )
1717 if (phdr
[i
].p_type
== PT_LOAD
)
1721 adjust
= -phdr
[i
].p_filesz
& 15;
1722 phdr
[i
].p_filesz
+= adjust
;
1724 adjust
= -phdr
[i
].p_memsz
& 15;
1725 phdr
[i
].p_memsz
+= adjust
;
1731 /* Arrange for our linker created section to be output. */
1734 spu_elf_section_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
1735 Elf_Internal_Shdr
*i_shdrp
)
1739 sec
= i_shdrp
->bfd_section
;
1741 && (sec
->flags
& SEC_LINKER_CREATED
) != 0
1742 && sec
->name
!= NULL
1743 && strcmp (sec
->name
, SPU_PTNOTE_SPUNAME
) == 0)
1744 i_shdrp
->contents
= sec
->contents
;
1749 #define TARGET_BIG_SYM bfd_elf32_spu_vec
1750 #define TARGET_BIG_NAME "elf32-spu"
1751 #define ELF_ARCH bfd_arch_spu
1752 #define ELF_MACHINE_CODE EM_SPU
1753 /* This matches the alignment need for DMA. */
1754 #define ELF_MAXPAGESIZE 0x80
1755 #define elf_backend_rela_normal 1
1756 #define elf_backend_can_gc_sections 1
1758 #define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
1759 #define elf_info_to_howto spu_elf_info_to_howto
1760 #define elf_backend_gc_mark_hook spu_elf_gc_mark_hook
1761 #define elf_backend_relocate_section spu_elf_relocate_section
1762 #define elf_backend_symbol_processing spu_elf_backend_symbol_processing
1763 #define bfd_elf32_new_section_hook spu_elf_new_section_hook
1764 #define bfd_elf32_bfd_link_hash_table_create spu_elf_link_hash_table_create
1765 #define bfd_elf32_bfd_link_hash_table_free spu_elf_link_hash_table_free
1767 #define elf_backend_additional_program_headers spu_elf_additional_program_headers
1768 #define elf_backend_modify_segment_map spu_elf_modify_segment_map
1769 #define elf_backend_modify_program_headers spu_elf_modify_program_headers
1770 #define elf_backend_post_process_headers spu_elf_post_process_headers
1771 #define elf_backend_section_processing spu_elf_section_processing
1772 #define elf_backend_special_sections spu_elf_special_sections
1774 #include "elf32-target.h"