1 /* SPU specific support for 32-bit ELF
3 Copyright 2006 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. The input section
429 id isn't really necessary but we add that in for consistency with
430 ppc32 and ppc64 stub names. We can't use a local symbol name
431 because ld -r might generate duplicate local symbols. */
434 spu_stub_name (const asection
*input_sec
,
435 const asection
*sym_sec
,
436 const struct elf_link_hash_entry
*h
,
437 const Elf_Internal_Rela
*rel
)
444 len
= 8 + 1 + strlen (h
->root
.root
.string
) + 1 + 8 + 1;
445 stub_name
= bfd_malloc (len
);
446 if (stub_name
== NULL
)
449 sprintf (stub_name
, "%08x.%s+%x",
450 input_sec
->id
& 0xffffffff,
452 (int) rel
->r_addend
& 0xffffffff);
457 len
= 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
458 stub_name
= bfd_malloc (len
);
459 if (stub_name
== NULL
)
462 sprintf (stub_name
, "%08x.%x:%x+%x",
463 input_sec
->id
& 0xffffffff,
464 sym_sec
->id
& 0xffffffff,
465 (int) ELF32_R_SYM (rel
->r_info
) & 0xffffffff,
466 (int) rel
->r_addend
& 0xffffffff);
467 len
= strlen (stub_name
);
470 if (stub_name
[len
- 2] == '+'
471 && stub_name
[len
- 1] == '0'
472 && stub_name
[len
] == 0)
473 stub_name
[len
- 2] = 0;
478 /* Create the note section if not already present. This is done early so
479 that the linker maps the sections to the right place in the output. */
482 spu_elf_create_sections (bfd
*output_bfd
, struct bfd_link_info
*info
)
486 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->next
)
487 if (bfd_get_section_by_name (ibfd
, SPU_PTNOTE_SPUNAME
) != NULL
)
492 /* Make SPU_PTNOTE_SPUNAME section. */
499 ibfd
= info
->input_bfds
;
500 flags
= SEC_LOAD
| SEC_READONLY
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
501 s
= bfd_make_section_anyway_with_flags (ibfd
, SPU_PTNOTE_SPUNAME
, flags
);
503 || !bfd_set_section_alignment (ibfd
, s
, 4))
506 name_len
= strlen (bfd_get_filename (output_bfd
)) + 1;
507 size
= 12 + ((sizeof (SPU_PLUGIN_NAME
) + 3) & -4);
508 size
+= (name_len
+ 3) & -4;
510 if (!bfd_set_section_size (ibfd
, s
, size
))
513 data
= bfd_zalloc (ibfd
, size
);
517 bfd_put_32 (ibfd
, sizeof (SPU_PLUGIN_NAME
), data
+ 0);
518 bfd_put_32 (ibfd
, name_len
, data
+ 4);
519 bfd_put_32 (ibfd
, 1, data
+ 8);
520 memcpy (data
+ 12, SPU_PLUGIN_NAME
, sizeof (SPU_PLUGIN_NAME
));
521 memcpy (data
+ 12 + ((sizeof (SPU_PLUGIN_NAME
) + 3) & -4),
522 bfd_get_filename (output_bfd
), name_len
);
529 /* Return the section that should be marked against GC for a given
533 spu_elf_gc_mark_hook (asection
*sec
,
534 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
535 Elf_Internal_Rela
*rel ATTRIBUTE_UNUSED
,
536 struct elf_link_hash_entry
*h
,
537 Elf_Internal_Sym
*sym
)
541 switch (h
->root
.type
)
543 case bfd_link_hash_defined
:
544 case bfd_link_hash_defweak
:
545 return h
->root
.u
.def
.section
;
547 case bfd_link_hash_common
:
548 return h
->root
.u
.c
.p
->section
;
555 return bfd_section_from_elf_index (sec
->owner
, sym
->st_shndx
);
560 /* qsort predicate to sort sections by vma. */
563 sort_sections (const void *a
, const void *b
)
565 const asection
*const *s1
= a
;
566 const asection
*const *s2
= b
;
567 bfd_signed_vma delta
= (*s1
)->vma
- (*s2
)->vma
;
570 return delta
< 0 ? -1 : 1;
572 return (*s1
)->index
- (*s2
)->index
;
575 /* Identify overlays in the output bfd, and number them. */
578 spu_elf_find_overlays (bfd
*output_bfd
, struct bfd_link_info
*info
)
580 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
581 asection
**alloc_sec
;
582 unsigned int i
, n
, ovl_index
, num_buf
;
586 if (output_bfd
->section_count
< 2)
589 alloc_sec
= bfd_malloc (output_bfd
->section_count
* sizeof (*alloc_sec
));
590 if (alloc_sec
== NULL
)
593 /* Pick out all the alloced sections. */
594 for (n
= 0, s
= output_bfd
->sections
; s
!= NULL
; s
= s
->next
)
595 if ((s
->flags
& SEC_ALLOC
) != 0
596 && (s
->flags
& (SEC_LOAD
| SEC_THREAD_LOCAL
)) != SEC_THREAD_LOCAL
606 /* Sort them by vma. */
607 qsort (alloc_sec
, n
, sizeof (*alloc_sec
), sort_sections
);
609 /* Look for overlapping vmas. Any with overlap must be overlays.
610 Count them. Also count the number of overlay regions and for
611 each region save a section from that region with the lowest vma
612 and another section with the highest end vma. */
613 ovl_end
= alloc_sec
[0]->vma
+ alloc_sec
[0]->size
;
614 for (ovl_index
= 0, num_buf
= 0, i
= 1; i
< n
; i
++)
617 if (s
->vma
< ovl_end
)
619 asection
*s0
= alloc_sec
[i
- 1];
621 if (spu_elf_section_data (s0
)->ovl_index
== 0)
623 spu_elf_section_data (s0
)->ovl_index
= ++ovl_index
;
624 alloc_sec
[num_buf
* 2] = s0
;
625 alloc_sec
[num_buf
* 2 + 1] = s0
;
628 spu_elf_section_data (s
)->ovl_index
= ++ovl_index
;
629 if (ovl_end
< s
->vma
+ s
->size
)
631 ovl_end
= s
->vma
+ s
->size
;
632 alloc_sec
[num_buf
* 2 - 1] = s
;
636 ovl_end
= s
->vma
+ s
->size
;
639 htab
->num_overlays
= ovl_index
;
640 htab
->num_buf
= num_buf
;
647 alloc_sec
= bfd_realloc (alloc_sec
, num_buf
* 2 * sizeof (*alloc_sec
));
648 if (alloc_sec
== NULL
)
651 htab
->ovl_region
= alloc_sec
;
655 /* One of these per stub. */
656 #define SIZEOF_STUB1 8
657 #define ILA_79 0x4200004f /* ila $79,function_address */
658 #define BR 0x32000000 /* br stub2 */
660 /* One of these per overlay. */
661 #define SIZEOF_STUB2 8
662 #define ILA_78 0x4200004e /* ila $78,overlay_number */
664 #define NOP 0x40200000
666 /* Return true for all relative and absolute branch and hint instructions.
679 is_branch (const unsigned char *insn
)
681 return (((insn
[0] & 0xec) == 0x20 && (insn
[1] & 0x80) == 0)
682 || (insn
[0] & 0xfc) == 0x10);
686 struct spu_stub_hash_entry
**sh
;
690 /* Called via bfd_hash_traverse to set up pointers to all symbols
691 in the stub hash table. */
694 populate_stubs (struct bfd_hash_entry
*bh
, void *inf
)
696 struct stubarr
*stubs
= inf
;
698 stubs
->sh
[--stubs
->count
] = (struct spu_stub_hash_entry
*) bh
;
702 /* qsort predicate to sort stubs by overlay number. */
705 sort_stubs (const void *a
, const void *b
)
707 const struct spu_stub_hash_entry
*const *sa
= a
;
708 const struct spu_stub_hash_entry
*const *sb
= b
;
712 i
= spu_elf_section_data ((*sa
)->target_section
->output_section
)->ovl_index
;
713 i
-= spu_elf_section_data ((*sb
)->target_section
->output_section
)->ovl_index
;
717 d
= ((*sa
)->target_section
->output_section
->vma
718 + (*sa
)->target_section
->output_offset
720 - (*sb
)->target_section
->output_section
->vma
721 - (*sb
)->target_section
->output_offset
722 - (*sb
)->target_off
);
724 return d
< 0 ? -1 : 1;
726 /* Two functions at the same address. Aliases perhaps. */
727 i
= strcmp ((*sb
)->root
.string
, (*sa
)->root
.string
);
732 /* Allocate space for overlay call and return stubs. */
735 spu_elf_size_stubs (bfd
*output_bfd
,
736 struct bfd_link_info
*info
,
737 int non_overlay_stubs
,
742 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
744 struct stubarr stubs
;
748 htab
->non_overlay_stubs
= non_overlay_stubs
;
750 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link_next
)
752 extern const bfd_target bfd_elf32_spu_vec
;
753 Elf_Internal_Shdr
*symtab_hdr
;
755 Elf_Internal_Sym
*local_syms
= NULL
;
757 if (ibfd
->xvec
!= &bfd_elf32_spu_vec
)
760 /* We'll need the symbol table in a second. */
761 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
762 if (symtab_hdr
->sh_info
== 0)
765 /* Walk over each section attached to the input bfd. */
766 for (section
= ibfd
->sections
; section
!= NULL
; section
= section
->next
)
768 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
770 /* If there aren't any relocs, then there's nothing more to do. */
771 if ((section
->flags
& SEC_RELOC
) == 0
772 || (section
->flags
& SEC_ALLOC
) == 0
773 || (section
->flags
& SEC_LOAD
) == 0
774 || section
->reloc_count
== 0)
777 /* If this section is a link-once section that will be
778 discarded, then don't create any stubs. */
779 if (section
->output_section
== NULL
780 || section
->output_section
->owner
!= output_bfd
)
783 /* Get the relocs. */
785 = _bfd_elf_link_read_relocs (ibfd
, section
, NULL
, NULL
,
787 if (internal_relocs
== NULL
)
788 goto error_ret_free_local
;
790 /* Now examine each relocation. */
791 irela
= internal_relocs
;
792 irelaend
= irela
+ section
->reloc_count
;
793 for (; irela
< irelaend
; irela
++)
795 enum elf_spu_reloc_type r_type
;
798 Elf_Internal_Sym
*sym
;
799 struct elf_link_hash_entry
*h
;
801 struct spu_stub_hash_entry
*sh
;
802 unsigned int sym_type
;
803 enum _insn_type
{ non_branch
, branch
, call
} insn_type
;
805 r_type
= ELF32_R_TYPE (irela
->r_info
);
806 r_indx
= ELF32_R_SYM (irela
->r_info
);
808 if (r_type
>= R_SPU_max
)
810 bfd_set_error (bfd_error_bad_value
);
811 goto error_ret_free_internal
;
814 /* Determine the reloc target section. */
815 if (!get_sym_h (&h
, &sym
, &sym_sec
, &local_syms
, r_indx
, ibfd
))
816 goto error_ret_free_internal
;
819 || sym_sec
->output_section
== NULL
820 || sym_sec
->output_section
->owner
!= output_bfd
)
823 /* Ensure no stubs for user supplied overlay manager syms. */
825 && (strcmp (h
->root
.root
.string
, "__ovly_load") == 0
826 || strcmp (h
->root
.root
.string
, "__ovly_return") == 0))
829 insn_type
= non_branch
;
830 if (r_type
== R_SPU_REL16
831 || r_type
== R_SPU_ADDR16
)
833 unsigned char insn
[4];
835 if (!bfd_get_section_contents (ibfd
, section
, insn
,
837 goto error_ret_free_internal
;
839 if (is_branch (insn
))
842 if ((insn
[0] & 0xfd) == 0x31)
847 /* We are only interested in function symbols. */
851 sym_type
= ELF_ST_TYPE (sym
->st_info
);
852 if (sym_type
!= STT_FUNC
)
854 /* It's common for people to write assembly and forget
855 to give function symbols the right type. Handle
856 calls to such symbols, but warn so that (hopefully)
857 people will fix their code. We need the symbol
858 type to be correct to distinguish function pointer
859 initialisation from other pointer initialisation. */
860 if (insn_type
== call
)
862 const char *sym_name
;
865 sym_name
= h
->root
.root
.string
;
867 sym_name
= bfd_elf_sym_name (sym_sec
->owner
,
872 (*_bfd_error_handler
) (_("warning: call to non-function"
873 " symbol %s defined in %B"),
874 sym_name
, sym_sec
->owner
);
880 /* Usually, non-overlay sections don't need stubs. */
881 if (!spu_elf_section_data (sym_sec
->output_section
)->ovl_index
882 && !non_overlay_stubs
)
885 /* We need a reference from some other section before
886 we consider that a symbol might need an overlay stub. */
887 if (spu_elf_section_data (sym_sec
->output_section
)->ovl_index
888 == spu_elf_section_data (section
->output_section
)->ovl_index
)
890 /* Or we need this to *not* be a branch. ie. We are
891 possibly taking the address of a function and
892 passing it out somehow. */
893 if (insn_type
!= non_branch
)
897 stub_name
= spu_stub_name (section
, sym_sec
, h
, irela
);
898 if (stub_name
== NULL
)
899 goto error_ret_free_internal
;
901 sh
= (struct spu_stub_hash_entry
*)
902 bfd_hash_lookup (&htab
->stub_hash_table
, stub_name
,
907 error_ret_free_internal
:
908 if (elf_section_data (section
)->relocs
!= internal_relocs
)
909 free (internal_relocs
);
910 error_ret_free_local
:
911 if (local_syms
!= NULL
912 && (symtab_hdr
->contents
913 != (unsigned char *) local_syms
))
918 /* If this entry isn't new, we already have a stub. */
919 if (sh
->target_section
!= NULL
)
925 sh
->target_section
= sym_sec
;
927 sh
->target_off
= h
->root
.u
.def
.value
;
929 sh
->target_off
= sym
->st_value
;
930 sh
->target_off
+= irela
->r_addend
;
935 /* We're done with the internal relocs, free them. */
936 if (elf_section_data (section
)->relocs
!= internal_relocs
)
937 free (internal_relocs
);
940 if (local_syms
!= NULL
941 && symtab_hdr
->contents
!= (unsigned char *) local_syms
)
943 if (!info
->keep_memory
)
946 symtab_hdr
->contents
= (unsigned char *) local_syms
;
951 if (stubs
.count
== 0)
954 ibfd
= info
->input_bfds
;
955 flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_CODE
| SEC_READONLY
956 | SEC_HAS_CONTENTS
| SEC_IN_MEMORY
);
957 htab
->stub
= bfd_make_section_anyway_with_flags (ibfd
, ".stub", flags
);
959 if (htab
->stub
== NULL
960 || !bfd_set_section_alignment (ibfd
, htab
->stub
, 2))
963 flags
= (SEC_ALLOC
| SEC_LOAD
964 | SEC_HAS_CONTENTS
| SEC_IN_MEMORY
);
965 htab
->ovtab
= bfd_make_section_anyway_with_flags (ibfd
, ".ovtab", flags
);
966 *ovtab
= htab
->ovtab
;
967 if (htab
->ovtab
== NULL
968 || !bfd_set_section_alignment (ibfd
, htab
->stub
, 4))
971 *toe
= bfd_make_section_anyway_with_flags (ibfd
, ".toe", SEC_ALLOC
);
973 || !bfd_set_section_alignment (ibfd
, *toe
, 4))
977 /* Retrieve all the stubs and sort. */
978 stubs
.sh
= bfd_malloc (stubs
.count
* sizeof (*stubs
.sh
));
979 if (stubs
.sh
== NULL
)
982 bfd_hash_traverse (&htab
->stub_hash_table
, populate_stubs
, &stubs
);
983 BFD_ASSERT (stubs
.count
== 0);
986 qsort (stubs
.sh
, stubs
.count
, sizeof (*stubs
.sh
), sort_stubs
);
988 /* Now that the stubs are sorted, place them in the stub section.
989 Stubs are grouped per overlay
1003 for (i
= 0; i
< stubs
.count
; i
++)
1005 if (spu_elf_section_data (stubs
.sh
[group
]->target_section
1006 ->output_section
)->ovl_index
1007 != spu_elf_section_data (stubs
.sh
[i
]->target_section
1008 ->output_section
)->ovl_index
)
1010 htab
->stub
->size
+= SIZEOF_STUB2
;
1011 for (; group
!= i
; group
++)
1012 stubs
.sh
[group
]->delta
1013 = stubs
.sh
[i
- 1]->off
- stubs
.sh
[group
]->off
;
1016 || ((stubs
.sh
[i
- 1]->target_section
->output_section
->vma
1017 + stubs
.sh
[i
- 1]->target_section
->output_offset
1018 + stubs
.sh
[i
- 1]->target_off
)
1019 != (stubs
.sh
[i
]->target_section
->output_section
->vma
1020 + stubs
.sh
[i
]->target_section
->output_offset
1021 + stubs
.sh
[i
]->target_off
)))
1023 stubs
.sh
[i
]->off
= htab
->stub
->size
;
1024 htab
->stub
->size
+= SIZEOF_STUB1
;
1027 stubs
.sh
[i
]->off
= stubs
.sh
[i
- 1]->off
;
1030 htab
->stub
->size
+= SIZEOF_STUB2
;
1031 for (; group
!= i
; group
++)
1032 stubs
.sh
[group
]->delta
= stubs
.sh
[i
- 1]->off
- stubs
.sh
[group
]->off
;
1034 /* htab->ovtab consists of two arrays.
1044 . } _ovly_buf_table[]; */
1046 htab
->ovtab
->alignment_power
= 4;
1047 htab
->ovtab
->size
= htab
->num_overlays
* 16 + htab
->num_buf
* 4;
1052 /* Functions to handle embedded spu_ovl.o object. */
1055 ovl_mgr_open (struct bfd
*nbfd ATTRIBUTE_UNUSED
, void *stream
)
1061 ovl_mgr_pread (struct bfd
*abfd ATTRIBUTE_UNUSED
,
1067 struct _ovl_stream
*os
;
1071 os
= (struct _ovl_stream
*) stream
;
1072 max
= (char *) os
->end
- (char *) os
->start
;
1074 if ((ufile_ptr
) offset
>= max
)
1078 if (count
> max
- offset
)
1079 count
= max
- offset
;
1081 memcpy (buf
, (char *) os
->start
+ offset
, count
);
1086 spu_elf_open_builtin_lib (bfd
**ovl_bfd
, const struct _ovl_stream
*stream
)
1088 *ovl_bfd
= bfd_openr_iovec ("builtin ovl_mgr",
1095 return *ovl_bfd
!= NULL
;
1098 /* Fill in the ila and br for a stub. On the last stub for a group,
1099 write the stub that sets the overlay number too. */
1102 write_one_stub (struct bfd_hash_entry
*bh
, void *inf
)
1104 struct spu_stub_hash_entry
*ent
= (struct spu_stub_hash_entry
*) bh
;
1105 struct spu_link_hash_table
*htab
= inf
;
1106 asection
*sec
= htab
->stub
;
1107 asection
*s
= ent
->target_section
;
1111 val
= ent
->target_off
+ s
->output_offset
+ s
->output_section
->vma
;
1112 bfd_put_32 (sec
->owner
, ILA_79
+ ((val
<< 7) & 0x01ffff80),
1113 sec
->contents
+ ent
->off
);
1114 val
= ent
->delta
+ 4;
1115 bfd_put_32 (sec
->owner
, BR
+ ((val
<< 5) & 0x007fff80),
1116 sec
->contents
+ ent
->off
+ 4);
1118 /* If this is the last stub of this group, write stub2. */
1119 if (ent
->delta
== 0)
1121 bfd_put_32 (sec
->owner
, NOP
,
1122 sec
->contents
+ ent
->off
+ 4);
1124 ovl
= spu_elf_section_data (s
->output_section
)->ovl_index
;
1125 bfd_put_32 (sec
->owner
, ILA_78
+ ((ovl
<< 7) & 0x01ffff80),
1126 sec
->contents
+ ent
->off
+ 8);
1128 val
= (htab
->ovly_load
->root
.u
.def
.section
->output_section
->vma
1129 + htab
->ovly_load
->root
.u
.def
.section
->output_offset
1130 + htab
->ovly_load
->root
.u
.def
.value
1131 - (sec
->output_section
->vma
1132 + sec
->output_offset
1135 if (val
+ 0x20000 >= 0x40000)
1136 htab
->stub_overflow
= TRUE
;
1138 bfd_put_32 (sec
->owner
, BR
+ ((val
<< 5) & 0x007fff80),
1139 sec
->contents
+ ent
->off
+ 12);
1142 if (htab
->emit_stub_syms
)
1144 struct elf_link_hash_entry
*h
;
1148 len1
= sizeof ("ovl_call.") - 1;
1149 len2
= strlen (ent
->root
.string
);
1150 name
= bfd_malloc (len1
+ len2
+ 1);
1153 memcpy (name
, ent
->root
.string
, 9);
1154 memcpy (name
+ 9, "ovl_call.", len1
);
1155 memcpy (name
+ 9 + len1
, ent
->root
.string
+ 9, len2
- 9 + 1);
1156 h
= elf_link_hash_lookup (&htab
->elf
, name
, TRUE
, FALSE
, FALSE
);
1159 if (h
->root
.type
== bfd_link_hash_new
)
1161 h
->root
.type
= bfd_link_hash_defined
;
1162 h
->root
.u
.def
.section
= sec
;
1163 h
->root
.u
.def
.value
= ent
->off
;
1164 h
->size
= (ent
->delta
== 0
1165 ? SIZEOF_STUB1
+ SIZEOF_STUB2
: SIZEOF_STUB1
);
1169 h
->ref_regular_nonweak
= 1;
1170 h
->forced_local
= 1;
1178 /* Define an STT_OBJECT symbol. */
1180 static struct elf_link_hash_entry
*
1181 define_ovtab_symbol (struct spu_link_hash_table
*htab
, const char *name
)
1183 struct elf_link_hash_entry
*h
;
1185 h
= elf_link_hash_lookup (&htab
->elf
, name
, TRUE
, FALSE
, FALSE
);
1189 if (h
->root
.type
!= bfd_link_hash_defined
1192 h
->root
.type
= bfd_link_hash_defined
;
1193 h
->root
.u
.def
.section
= htab
->ovtab
;
1194 h
->type
= STT_OBJECT
;
1197 h
->ref_regular_nonweak
= 1;
1202 (*_bfd_error_handler
) (_("%B is not allowed to define %s"),
1203 h
->root
.u
.def
.section
->owner
,
1204 h
->root
.root
.string
);
1205 bfd_set_error (bfd_error_bad_value
);
1212 /* Fill in all stubs and the overlay tables. */
1215 spu_elf_build_stubs (struct bfd_link_info
*info
, int emit_syms
, asection
*toe
)
1217 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
1218 struct elf_link_hash_entry
*h
;
1224 htab
->emit_stub_syms
= emit_syms
;
1225 htab
->stub
->contents
= bfd_zalloc (htab
->stub
->owner
, htab
->stub
->size
);
1226 if (htab
->stub
->contents
== NULL
)
1229 h
= elf_link_hash_lookup (&htab
->elf
, "__ovly_load", FALSE
, FALSE
, FALSE
);
1230 htab
->ovly_load
= h
;
1231 BFD_ASSERT (h
!= NULL
1232 && (h
->root
.type
== bfd_link_hash_defined
1233 || h
->root
.type
== bfd_link_hash_defweak
)
1236 s
= h
->root
.u
.def
.section
->output_section
;
1237 if (spu_elf_section_data (s
)->ovl_index
)
1239 (*_bfd_error_handler
) (_("%s in overlay section"),
1240 h
->root
.u
.def
.section
->owner
);
1241 bfd_set_error (bfd_error_bad_value
);
1245 /* Write out all the stubs. */
1246 bfd_hash_traverse (&htab
->stub_hash_table
, write_one_stub
, htab
);
1248 if (htab
->stub_overflow
)
1250 (*_bfd_error_handler
) (_("overlay stub relocation overflow"));
1251 bfd_set_error (bfd_error_bad_value
);
1255 htab
->ovtab
->contents
= bfd_zalloc (htab
->ovtab
->owner
, htab
->ovtab
->size
);
1256 if (htab
->ovtab
->contents
== NULL
)
1259 /* Write out _ovly_table. */
1260 p
= htab
->ovtab
->contents
;
1261 obfd
= htab
->ovtab
->output_section
->owner
;
1262 for (s
= obfd
->sections
; s
!= NULL
; s
= s
->next
)
1264 unsigned int ovl_index
= spu_elf_section_data (s
)->ovl_index
;
1268 unsigned int lo
, hi
, mid
;
1269 unsigned long off
= (ovl_index
- 1) * 16;
1270 bfd_put_32 (htab
->ovtab
->owner
, s
->vma
, p
+ off
);
1271 bfd_put_32 (htab
->ovtab
->owner
, (s
->size
+ 15) & -16, p
+ off
+ 4);
1272 /* file_off written later in spu_elf_modify_program_headers. */
1278 mid
= (lo
+ hi
) >> 1;
1279 if (htab
->ovl_region
[2 * mid
+ 1]->vma
1280 + htab
->ovl_region
[2 * mid
+ 1]->size
<= s
->vma
)
1282 else if (htab
->ovl_region
[2 * mid
]->vma
> s
->vma
)
1286 bfd_put_32 (htab
->ovtab
->owner
, mid
+ 1, p
+ off
+ 12);
1290 BFD_ASSERT (lo
< hi
);
1294 /* Write out _ovly_buf_table. */
1295 p
= htab
->ovtab
->contents
+ htab
->num_overlays
* 16;
1296 for (i
= 0; i
< htab
->num_buf
; i
++)
1298 bfd_put_32 (htab
->ovtab
->owner
, 0, p
);
1302 h
= define_ovtab_symbol (htab
, "_ovly_table");
1305 h
->root
.u
.def
.value
= 0;
1306 h
->size
= htab
->num_overlays
* 16;
1308 h
= define_ovtab_symbol (htab
, "_ovly_table_end");
1311 h
->root
.u
.def
.value
= htab
->num_overlays
* 16;
1314 h
= define_ovtab_symbol (htab
, "_ovly_buf_table");
1317 h
->root
.u
.def
.value
= htab
->num_overlays
* 16;
1318 h
->size
= htab
->num_buf
* 4;
1320 h
= define_ovtab_symbol (htab
, "_ovly_buf_table_end");
1323 h
->root
.u
.def
.value
= htab
->num_overlays
* 16 + htab
->num_buf
* 4;
1326 h
= define_ovtab_symbol (htab
, "_EAR_");
1329 h
->root
.u
.def
.section
= toe
;
1330 h
->root
.u
.def
.value
= 0;
1336 /* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
1339 spu_elf_relocate_section (bfd
*output_bfd
,
1340 struct bfd_link_info
*info
,
1342 asection
*input_section
,
1344 Elf_Internal_Rela
*relocs
,
1345 Elf_Internal_Sym
*local_syms
,
1346 asection
**local_sections
)
1348 Elf_Internal_Shdr
*symtab_hdr
;
1349 struct elf_link_hash_entry
**sym_hashes
;
1350 Elf_Internal_Rela
*rel
, *relend
;
1351 struct spu_link_hash_table
*htab
;
1352 bfd_boolean ret
= TRUE
;
1354 if (info
->relocatable
)
1357 htab
= spu_hash_table (info
);
1358 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
1359 sym_hashes
= (struct elf_link_hash_entry
**) (elf_sym_hashes (input_bfd
));
1362 relend
= relocs
+ input_section
->reloc_count
;
1363 for (; rel
< relend
; rel
++)
1366 reloc_howto_type
*howto
;
1367 unsigned long r_symndx
;
1368 Elf_Internal_Sym
*sym
;
1370 struct elf_link_hash_entry
*h
;
1371 const char *sym_name
;
1374 bfd_reloc_status_type r
;
1375 bfd_boolean unresolved_reloc
;
1378 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1379 r_type
= ELF32_R_TYPE (rel
->r_info
);
1380 howto
= elf_howto_table
+ r_type
;
1381 unresolved_reloc
= FALSE
;
1387 if (r_symndx
< symtab_hdr
->sh_info
)
1389 sym
= local_syms
+ r_symndx
;
1390 sec
= local_sections
[r_symndx
];
1391 sym_name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
, sec
);
1392 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1396 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1397 r_symndx
, symtab_hdr
, sym_hashes
,
1399 unresolved_reloc
, warned
);
1400 sym_name
= h
->root
.root
.string
;
1403 if (unresolved_reloc
)
1405 (*_bfd_error_handler
)
1406 (_("%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
1408 bfd_get_section_name (input_bfd
, input_section
),
1409 (long) rel
->r_offset
,
1415 /* If this symbol is in an overlay area, we may need to relocate
1416 to the overlay stub. */
1417 addend
= rel
->r_addend
;
1419 && sec
->output_section
!= NULL
1420 && sec
->output_section
->owner
== output_bfd
1421 && (spu_elf_section_data (sec
->output_section
)->ovl_index
!= 0
1422 || htab
->non_overlay_stubs
)
1423 && !(sec
== input_section
1424 && is_branch (contents
+ rel
->r_offset
)))
1427 struct spu_stub_hash_entry
*sh
;
1429 stub_name
= spu_stub_name (input_section
, sec
, h
, rel
);
1430 if (stub_name
== NULL
)
1433 sh
= (struct spu_stub_hash_entry
*)
1434 bfd_hash_lookup (&htab
->stub_hash_table
, stub_name
, FALSE
, FALSE
);
1437 relocation
= (htab
->stub
->output_section
->vma
1438 + htab
->stub
->output_offset
1445 r
= _bfd_final_link_relocate (howto
,
1449 rel
->r_offset
, relocation
, addend
);
1451 if (r
!= bfd_reloc_ok
)
1453 const char *msg
= (const char *) 0;
1457 case bfd_reloc_overflow
:
1458 if (!((*info
->callbacks
->reloc_overflow
)
1459 (info
, (h
? &h
->root
: NULL
), sym_name
, howto
->name
,
1460 (bfd_vma
) 0, input_bfd
, input_section
, rel
->r_offset
)))
1464 case bfd_reloc_undefined
:
1465 if (!((*info
->callbacks
->undefined_symbol
)
1466 (info
, sym_name
, input_bfd
, input_section
,
1467 rel
->r_offset
, TRUE
)))
1471 case bfd_reloc_outofrange
:
1472 msg
= _("internal error: out of range error");
1475 case bfd_reloc_notsupported
:
1476 msg
= _("internal error: unsupported relocation error");
1479 case bfd_reloc_dangerous
:
1480 msg
= _("internal error: dangerous error");
1484 msg
= _("internal error: unknown error");
1488 if (!((*info
->callbacks
->warning
)
1489 (info
, msg
, sym_name
, input_bfd
, input_section
,
1500 static int spu_plugin
= 0;
1503 spu_elf_plugin (int val
)
1508 /* Set ELF header e_type for plugins. */
1511 spu_elf_post_process_headers (bfd
*abfd
,
1512 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1516 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
1518 i_ehdrp
->e_type
= ET_DYN
;
1522 /* We may add an extra PT_LOAD segment for .toe. We also need extra
1523 segments for overlays. */
1526 spu_elf_additional_program_headers (bfd
*abfd
, struct bfd_link_info
*info
)
1528 struct spu_link_hash_table
*htab
= spu_hash_table (info
);
1529 int extra
= htab
->num_overlays
;
1535 sec
= bfd_get_section_by_name (abfd
, ".toe");
1536 if (sec
!= NULL
&& (sec
->flags
& SEC_LOAD
) != 0)
1542 /* Remove .toe section from other PT_LOAD segments and put it in
1543 a segment of its own. Put overlays in separate segments too. */
1546 spu_elf_modify_segment_map (bfd
*abfd
, struct bfd_link_info
*info
)
1549 struct elf_segment_map
*m
;
1555 toe
= bfd_get_section_by_name (abfd
, ".toe");
1556 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1557 if (m
->p_type
== PT_LOAD
&& m
->count
> 1)
1558 for (i
= 0; i
< m
->count
; i
++)
1559 if ((s
= m
->sections
[i
]) == toe
1560 || spu_elf_section_data (s
)->ovl_index
!= 0)
1562 struct elf_segment_map
*m2
;
1565 if (i
+ 1 < m
->count
)
1567 amt
= sizeof (struct elf_segment_map
);
1568 amt
+= (m
->count
- (i
+ 2)) * sizeof (m
->sections
[0]);
1569 m2
= bfd_zalloc (abfd
, amt
);
1572 m2
->count
= m
->count
- (i
+ 1);
1573 memcpy (m2
->sections
, m
->sections
+ i
+ 1,
1574 m2
->count
* sizeof (m
->sections
[0]));
1575 m2
->p_type
= PT_LOAD
;
1583 amt
= sizeof (struct elf_segment_map
);
1584 m2
= bfd_zalloc (abfd
, amt
);
1587 m2
->p_type
= PT_LOAD
;
1589 m2
->sections
[0] = s
;
1599 /* Check that all loadable section VMAs lie in the range
1600 LO .. HI inclusive. */
1603 spu_elf_check_vma (bfd
*abfd
, bfd_vma lo
, bfd_vma hi
)
1605 struct elf_segment_map
*m
;
1608 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1609 if (m
->p_type
== PT_LOAD
)
1610 for (i
= 0; i
< m
->count
; i
++)
1611 if (m
->sections
[i
]->size
!= 0
1612 && (m
->sections
[i
]->vma
< lo
1613 || m
->sections
[i
]->vma
> hi
1614 || m
->sections
[i
]->vma
+ m
->sections
[i
]->size
- 1 > hi
))
1615 return m
->sections
[i
];
1620 /* Tweak phdrs before writing them out. */
1623 spu_elf_modify_program_headers (bfd
*abfd
, struct bfd_link_info
*info
)
1625 const struct elf_backend_data
*bed
;
1626 struct elf_obj_tdata
*tdata
;
1627 Elf_Internal_Phdr
*phdr
, *last
;
1628 struct spu_link_hash_table
*htab
;
1635 bed
= get_elf_backend_data (abfd
);
1636 tdata
= elf_tdata (abfd
);
1638 count
= tdata
->program_header_size
/ bed
->s
->sizeof_phdr
;
1639 htab
= spu_hash_table (info
);
1640 if (htab
->num_overlays
!= 0)
1642 struct elf_segment_map
*m
;
1645 for (i
= 0, m
= elf_tdata (abfd
)->segment_map
; m
; ++i
, m
= m
->next
)
1647 && (o
= spu_elf_section_data (m
->sections
[0])->ovl_index
) != 0)
1649 /* Mark this as an overlay header. */
1650 phdr
[i
].p_flags
|= PF_OVERLAY
;
1652 if (htab
->ovtab
!= NULL
&& htab
->ovtab
->size
!= 0)
1654 bfd_byte
*p
= htab
->ovtab
->contents
;
1655 unsigned int off
= (o
- 1) * 16 + 8;
1657 /* Write file_off into _ovly_table. */
1658 bfd_put_32 (htab
->ovtab
->owner
, phdr
[i
].p_offset
, p
+ off
);
1663 /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples
1664 of 16. This should always be possible when using the standard
1665 linker scripts, but don't create overlapping segments if
1666 someone is playing games with linker scripts. */
1668 for (i
= count
; i
-- != 0; )
1669 if (phdr
[i
].p_type
== PT_LOAD
)
1673 adjust
= -phdr
[i
].p_filesz
& 15;
1676 && phdr
[i
].p_offset
+ phdr
[i
].p_filesz
> last
->p_offset
- adjust
)
1679 adjust
= -phdr
[i
].p_memsz
& 15;
1682 && phdr
[i
].p_filesz
!= 0
1683 && phdr
[i
].p_vaddr
+ phdr
[i
].p_memsz
> last
->p_vaddr
- adjust
1684 && phdr
[i
].p_vaddr
+ phdr
[i
].p_memsz
<= last
->p_vaddr
)
1687 if (phdr
[i
].p_filesz
!= 0)
1691 if (i
== (unsigned int) -1)
1692 for (i
= count
; i
-- != 0; )
1693 if (phdr
[i
].p_type
== PT_LOAD
)
1697 adjust
= -phdr
[i
].p_filesz
& 15;
1698 phdr
[i
].p_filesz
+= adjust
;
1700 adjust
= -phdr
[i
].p_memsz
& 15;
1701 phdr
[i
].p_memsz
+= adjust
;
1707 /* Arrange for our linker created section to be output. */
1710 spu_elf_section_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
1711 Elf_Internal_Shdr
*i_shdrp
)
1715 sec
= i_shdrp
->bfd_section
;
1717 && (sec
->flags
& SEC_LINKER_CREATED
) != 0
1718 && sec
->name
!= NULL
1719 && strcmp (sec
->name
, SPU_PTNOTE_SPUNAME
) == 0)
1720 i_shdrp
->contents
= sec
->contents
;
1725 #define TARGET_BIG_SYM bfd_elf32_spu_vec
1726 #define TARGET_BIG_NAME "elf32-spu"
1727 #define ELF_ARCH bfd_arch_spu
1728 #define ELF_MACHINE_CODE EM_SPU
1729 /* This matches the alignment need for DMA. */
1730 #define ELF_MAXPAGESIZE 0x80
1731 #define elf_backend_rela_normal 1
1732 #define elf_backend_can_gc_sections 1
1734 #define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
1735 #define elf_info_to_howto spu_elf_info_to_howto
1736 #define elf_backend_gc_mark_hook spu_elf_gc_mark_hook
1737 #define elf_backend_relocate_section spu_elf_relocate_section
1738 #define elf_backend_symbol_processing spu_elf_backend_symbol_processing
1739 #define bfd_elf32_new_section_hook spu_elf_new_section_hook
1740 #define bfd_elf32_bfd_link_hash_table_create spu_elf_link_hash_table_create
1741 #define bfd_elf32_bfd_link_hash_table_free spu_elf_link_hash_table_free
1743 #define elf_backend_additional_program_headers spu_elf_additional_program_headers
1744 #define elf_backend_modify_segment_map spu_elf_modify_segment_map
1745 #define elf_backend_modify_program_headers spu_elf_modify_program_headers
1746 #define elf_backend_post_process_headers spu_elf_post_process_headers
1747 #define elf_backend_section_processing spu_elf_section_processing
1748 #define elf_backend_special_sections spu_elf_special_sections
1750 #include "elf32-target.h"