aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl/spuelf.em
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2008-01-28 05:59:24 +0000
committerAlan Modra <amodra@gmail.com>2008-01-28 05:59:24 +0000
commit47f6dab9a3fb353b0faca52fcc07d2f57c4d906c (patch)
tree9cc0fcaf801807941794b51c5a6726a21692d0b6 /ld/emultempl/spuelf.em
parent8693ff0ffb451be8a54dceda84bfc78246271dd9 (diff)
downloadfsf-binutils-gdb-47f6dab9a3fb353b0faca52fcc07d2f57c4d906c.zip
fsf-binutils-gdb-47f6dab9a3fb353b0faca52fcc07d2f57c4d906c.tar.gz
fsf-binutils-gdb-47f6dab9a3fb353b0faca52fcc07d2f57c4d906c.tar.bz2
Rewrite SPU overlay handling code. Put overlay calls stubs in the
overlays where possible. Use a faster call stub, or optionally at compile time, a more compact stub. Double size of _ovly_buf_table so that low bit of _ovly_table.buf can be used as a "present" bit. Reserve an extra _ovly_table entry for index zero.
Diffstat (limited to 'ld/emultempl/spuelf.em')
-rw-r--r--ld/emultempl/spuelf.em47
1 files changed, 24 insertions, 23 deletions
diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em
index e8333a4..7e618a5 100644
--- a/ld/emultempl/spuelf.em
+++ b/ld/emultempl/spuelf.em
@@ -58,8 +58,6 @@ static const struct _ovl_stream ovl_mgr_stream = {
ovl_mgr + sizeof (ovl_mgr)
};
-static asection *toe = NULL;
-
static int
is_spu_target (void)
@@ -84,7 +82,8 @@ spu_after_open (void)
gld${EMULATION_NAME}_after_open ();
}
-/* Add section S at the end of output section OUTPUT_NAME.
+/* If O is NULL, add section S at the end of output section OUTPUT_NAME.
+ If O is not NULL, add section S at the beginning of output section O.
Really, we should be duplicating ldlang.c map_input_to_output_sections
logic here, ie. using the linker script to find where the section
@@ -95,11 +94,11 @@ spu_after_open (void)
overlay manager code somewhere else. */
static void
-spu_place_special_section (asection *s, const char *output_name)
+spu_place_special_section (asection *s, asection *o, const char *output_name)
{
lang_output_section_statement_type *os;
- os = lang_output_section_find (output_name);
+ os = lang_output_section_find (o != NULL ? o->name : output_name);
if (os == NULL)
{
const char *save = s->name;
@@ -107,6 +106,15 @@ spu_place_special_section (asection *s, const char *output_name)
gld${EMULATION_NAME}_place_orphan (s);
s->name = save;
}
+ else if (o != NULL && os->children.head != NULL)
+ {
+ lang_statement_list_type add;
+
+ lang_list_init (&add);
+ lang_add_section (&add, s, os);
+ *add.tail = os->children.head;
+ os->children.head = add.head;
+ }
else
lang_add_section (&os->children, s, os);
@@ -154,7 +162,7 @@ spu_elf_load_ovl_mgr (void)
for (in = ovl_is->the_bfd->sections; in != NULL; in = in->next)
if ((in->flags & (SEC_ALLOC | SEC_LOAD))
== (SEC_ALLOC | SEC_LOAD))
- spu_place_special_section (in, ".text");
+ spu_place_special_section (in, NULL, ".text");
}
}
@@ -164,7 +172,7 @@ spu_elf_load_ovl_mgr (void)
os = os->next)
if (os->bfd_section != NULL
&& spu_elf_section_data (os->bfd_section) != NULL
- && spu_elf_section_data (os->bfd_section)->ovl_index != 0)
+ && spu_elf_section_data (os->bfd_section)->u.o.ovl_index != 0)
{
if (os->bfd_section->alignment_power < 4)
os->bfd_section->alignment_power = 4;
@@ -192,20 +200,15 @@ spu_before_allocation (void)
/* Find overlays by inspecting section vmas. */
if (spu_elf_find_overlays (output_bfd, &link_info))
{
- asection *stub, *ovtab;
+ int ret;
- if (!spu_elf_size_stubs (output_bfd, &link_info, non_overlay_stubs,
- stack_analysis, &stub, &ovtab, &toe))
+ ret = spu_elf_size_stubs (output_bfd, &link_info,
+ spu_place_special_section,
+ non_overlay_stubs);
+ if (ret == 0)
einfo ("%X%P: can not size overlay stubs: %E\n");
-
- if (stub != NULL)
- {
- spu_place_special_section (stub, ".text");
- spu_place_special_section (ovtab, ".data");
- spu_place_special_section (toe, ".toe");
-
- spu_elf_load_ovl_mgr ();
- }
+ else if (ret == 2)
+ spu_elf_load_ovl_mgr ();
}
/* We must not cache anything from the preliminary sizing. */
@@ -235,10 +238,8 @@ gld${EMULATION_NAME}_finish (void)
einfo ("%X%P: %A exceeds local store range\n", s);
}
- if (toe != NULL
- && !spu_elf_build_stubs (&link_info,
- emit_stub_syms || link_info.emitrelocations,
- toe))
+ if (!spu_elf_build_stubs (&link_info,
+ emit_stub_syms || link_info.emitrelocations))
einfo ("%X%P: can not build overlay stubs: %E\n");
finish_default ();