diff options
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf32-spu.c | 181 | ||||
-rw-r--r-- | bfd/elf32-spu.h | 1 | ||||
-rw-r--r-- | ld/ChangeLog | 7 | ||||
-rw-r--r-- | ld/emultempl/spuelf.em | 17 |
5 files changed, 136 insertions, 75 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ebb847b7016..704a418843c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,10 @@ 2008-12-10 Alan Modra <amodra@bigpond.net.au> + * elf32-spu.h (struct spu_elf_params): Add num_regions. + * elf32-spu.c (spu_elf_auto_overlay): Handle multiple overlay regions. + +2008-12-10 Alan Modra <amodra@bigpond.net.au> + * elf32-spu.g (struct spu_elf_params, enum _ovly_flavour): New. (spu_elf_setup): Declare. (spu_elf_create_sections, spu_elf_size_stubs): Update prototype. diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index 3908ecd125c..447aa8da0a0 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -3444,8 +3444,9 @@ spu_elf_auto_overlay (struct bfd_link_info *info) unsigned int fixed_size, lo, hi; struct spu_link_hash_table *htab; unsigned int base, i, count, bfd_count; - int ovlynum; + unsigned int region, ovlynum; asection **ovly_sections, **ovly_p; + unsigned int *ovly_map; FILE *script; unsigned int total_overlay_size, overlay_size; struct elf_link_hash_entry *h; @@ -3625,20 +3626,17 @@ spu_elf_auto_overlay (struct bfd_link_info *info) if (!for_each_node (collect_overlays, info, &ovly_p, TRUE)) goto err_exit; count = (size_t) (ovly_p - ovly_sections) / 2; - - script = (*htab->params->spu_elf_open_overlay_script) (); - - if (fprintf (script, "SECTIONS\n{\n OVERLAY :\n {\n") <= 0) - goto file_err; + ovly_map = bfd_malloc (count * sizeof (*ovly_map)); + if (ovly_map == NULL) + goto err_exit; memset (&dummy_caller, 0, sizeof (dummy_caller)); - overlay_size = htab->local_store - fixed_size; + overlay_size = (htab->local_store - fixed_size) / htab->params->num_regions; base = 0; ovlynum = 0; while (base < count) { unsigned int size = 0; - unsigned int j; for (i = base; i < count; i++) { @@ -3741,90 +3739,127 @@ spu_elf_auto_overlay (struct bfd_link_info *info) goto err_exit; } - if (fprintf (script, " .ovly%d {\n", ++ovlynum) <= 0) + while (dummy_caller.call_list != NULL) + { + struct call_info *call = dummy_caller.call_list; + dummy_caller.call_list = call->next; + free (call); + } + + ++ovlynum; + while (base < i) + ovly_map[base++] = ovlynum; + } + + script = htab->params->spu_elf_open_overlay_script (); + + if (fprintf (script, "SECTIONS\n{\n") <= 0) + goto file_err; + + for (region = 1; region <= htab->params->num_regions; region++) + { + ovlynum = region; + base = 0; + while (base < count && ovly_map[base] < ovlynum) + base++; + + if (base == count) + break; + + if (fprintf (script, " OVERLAY :\n {\n") <= 0) goto file_err; - for (j = base; j < i; j++) + + while (base < count) { - asection *sec = ovly_sections[2 * j]; - - if (fprintf (script, " %s%c%s (%s)\n", - (sec->owner->my_archive != NULL - ? sec->owner->my_archive->filename : ""), - info->path_separator, - sec->owner->filename, - sec->name) <= 0) + unsigned int j; + + if (fprintf (script, " .ovly%u {\n", ovlynum) <= 0) goto file_err; - if (sec->segment_mark) + + for (j = base; j < count && ovly_map[j] == ovlynum; j++) { - struct call_info *call = find_pasted_call (sec); - while (call != NULL) + asection *sec = ovly_sections[2 * j]; + + if (fprintf (script, " %s%c%s (%s)\n", + (sec->owner->my_archive != NULL + ? sec->owner->my_archive->filename : ""), + info->path_separator, + sec->owner->filename, + sec->name) <= 0) + goto file_err; + if (sec->segment_mark) { - struct function_info *call_fun = call->fun; - sec = call_fun->sec; - if (fprintf (script, " %s%c%s (%s)\n", - (sec->owner->my_archive != NULL - ? sec->owner->my_archive->filename : ""), - info->path_separator, - sec->owner->filename, - sec->name) <= 0) - goto file_err; - for (call = call_fun->call_list; call; call = call->next) - if (call->is_pasted) - break; + struct call_info *call = find_pasted_call (sec); + while (call != NULL) + { + struct function_info *call_fun = call->fun; + sec = call_fun->sec; + if (fprintf (script, " %s%c%s (%s)\n", + (sec->owner->my_archive != NULL + ? sec->owner->my_archive->filename : ""), + info->path_separator, + sec->owner->filename, + sec->name) <= 0) + goto file_err; + for (call = call_fun->call_list; call; call = call->next) + if (call->is_pasted) + break; + } } } - } - for (j = base; j < i; j++) - { - asection *sec = ovly_sections[2 * j + 1]; - if (sec != NULL - && fprintf (script, " %s%c%s (%s)\n", - (sec->owner->my_archive != NULL - ? sec->owner->my_archive->filename : ""), - info->path_separator, - sec->owner->filename, - sec->name) <= 0) - goto file_err; - - sec = ovly_sections[2 * j]; - if (sec->segment_mark) + for (j = base; j < count && ovly_map[j] == ovlynum; j++) { - struct call_info *call = find_pasted_call (sec); - while (call != NULL) + asection *sec = ovly_sections[2 * j + 1]; + if (sec != NULL + && fprintf (script, " %s%c%s (%s)\n", + (sec->owner->my_archive != NULL + ? sec->owner->my_archive->filename : ""), + info->path_separator, + sec->owner->filename, + sec->name) <= 0) + goto file_err; + + sec = ovly_sections[2 * j]; + if (sec->segment_mark) { - struct function_info *call_fun = call->fun; - sec = call_fun->rodata; - if (sec != NULL - && fprintf (script, " %s%c%s (%s)\n", - (sec->owner->my_archive != NULL - ? sec->owner->my_archive->filename : ""), - info->path_separator, - sec->owner->filename, - sec->name) <= 0) - goto file_err; - for (call = call_fun->call_list; call; call = call->next) - if (call->is_pasted) - break; + struct call_info *call = find_pasted_call (sec); + while (call != NULL) + { + struct function_info *call_fun = call->fun; + sec = call_fun->rodata; + if (sec != NULL + && fprintf (script, " %s%c%s (%s)\n", + (sec->owner->my_archive != NULL + ? sec->owner->my_archive->filename : ""), + info->path_separator, + sec->owner->filename, + sec->name) <= 0) + goto file_err; + for (call = call_fun->call_list; call; call = call->next) + if (call->is_pasted) + break; + } } } - } - if (fprintf (script, " }\n") <= 0) - goto file_err; + if (fprintf (script, " }\n") <= 0) + goto file_err; - while (dummy_caller.call_list != NULL) - { - struct call_info *call = dummy_caller.call_list; - dummy_caller.call_list = call->next; - free (call); + base = j; + ovlynum += htab->params->num_regions; + while (base < count && ovly_map[base] < ovlynum) + base++; } - base = i; + if (fprintf (script, " }\n") <= 0) + goto file_err; } + + free (ovly_map); free (ovly_sections); - if (fprintf (script, " }\n}\nINSERT AFTER .text;\n") <= 0) + if (fprintf (script, "}\nINSERT BEFORE .text;\n") <= 0) goto file_err; if (fclose (script) != 0) goto file_err; diff --git a/bfd/elf32-spu.h b/bfd/elf32-spu.h index 8cac3a33760..442dd5d3b2e 100644 --- a/bfd/elf32-spu.h +++ b/bfd/elf32-spu.h @@ -55,6 +55,7 @@ struct spu_elf_params bfd_vma local_store_hi; /* Control --auto-overlay feature. */ + unsigned int num_regions; unsigned int auto_overlay_fixed; unsigned int auto_overlay_reserved; int extra_stack_space; diff --git a/ld/ChangeLog b/ld/ChangeLog index 864cba31f1c..b9588c36c1f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,12 @@ 2008-12-10 Alan Modra <amodra@bigpond.net.au> + * emultempl/spuelf.em (params): Init new field. + (OPTION_SPU_NUM_REGIONS): Define. + (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add --num-regions. + (PARSE_AND_LIST_ARGS_CASES): Handle --num-regions. + +2008-12-10 Alan Modra <amodra@bigpond.net.au> + * emultempl/spuelf.em (params): New var, used instead of various others. Adjust use throughout file. (spu_after_open): Call spu_elf_setup. diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index cb80c45cbf3..bfabb8b72ee 100644 --- a/ld/emultempl/spuelf.em +++ b/ld/emultempl/spuelf.em @@ -39,7 +39,7 @@ static struct spu_elf_params params = &spu_elf_relink, 0, ovly_normal, 0, 0, 0, 0, 0, 0x3ffff, - 0, 0, 2000 + 1, 0, 0, 2000 }; static char *auto_overlay_file = 0; @@ -520,7 +520,8 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_SPU_AUTO_OVERLAY (OPTION_SPU_STACK_SYMS + 1) #define OPTION_SPU_AUTO_RELINK (OPTION_SPU_AUTO_OVERLAY + 1) #define OPTION_SPU_OVERLAY_RODATA (OPTION_SPU_AUTO_RELINK + 1) -#define OPTION_SPU_FIXED_SPACE (OPTION_SPU_OVERLAY_RODATA + 1) +#define OPTION_SPU_NUM_REGIONS (OPTION_SPU_OVERLAY_RODATA + 1) +#define OPTION_SPU_FIXED_SPACE (OPTION_SPU_NUM_REGIONS + 1) #define OPTION_SPU_RESERVED_SPACE (OPTION_SPU_FIXED_SPACE + 1) #define OPTION_SPU_EXTRA_STACK (OPTION_SPU_RESERVED_SPACE + 1) #define OPTION_SPU_NO_AUTO_OVERLAY (OPTION_SPU_EXTRA_STACK + 1) @@ -537,6 +538,7 @@ PARSE_AND_LIST_LONGOPTS=' { "auto-overlay", optional_argument, NULL, OPTION_SPU_AUTO_OVERLAY }, { "auto-relink", no_argument, NULL, OPTION_SPU_AUTO_RELINK }, { "overlay-rodata", no_argument, NULL, OPTION_SPU_OVERLAY_RODATA }, + { "num-regions", required_argument, NULL, OPTION_SPU_NUM_REGIONS }, { "fixed-space", required_argument, NULL, OPTION_SPU_FIXED_SPACE }, { "reserved-space", required_argument, NULL, OPTION_SPU_RESERVED_SPACE }, { "extra-stack-space", required_argument, NULL, OPTION_SPU_EXTRA_STACK }, @@ -557,6 +559,7 @@ PARSE_AND_LIST_OPTIONS=' --auto-relink Rerun linker using auto-overlay script.\n\ --overlay-rodata Place read-only data with associated function\n\ code in overlays.\n\ + --num-regions Number of overlay buffers (default 1).\n\ --fixed-space=bytes Local store for non-overlay code and data.\n\ --reserved-space=bytes Local store for stack and heap. If not specified\n\ ld will estimate stack size and assume no heap.\n\ @@ -621,6 +624,16 @@ PARSE_AND_LIST_ARGS_CASES=' params.auto_overlay |= 4; break; + case OPTION_SPU_NUM_REGIONS: + { + char *end; + params.num_regions = strtoul (optarg, &end, 0); + if (*end == 0) + break; + einfo (_("%P%F: invalid --num-regions `%s'\''\n"), optarg); + } + break; + case OPTION_SPU_FIXED_SPACE: { char *end; |