bfd/
* elf32-spu.h (struct spu_elf_params): Add num_regions. * elf32-spu.c (spu_elf_auto_overlay): Handle multiple overlay regions. ld/ * 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.
This commit is contained in:
parent
64615358cc
commit
a3a219a90a
5 changed files with 145 additions and 84 deletions
|
@ -1,3 +1,8 @@
|
|||
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.
|
||||
|
|
199
bfd/elf32-spu.c
199
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,78 +3739,6 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
|
|||
goto err_exit;
|
||||
}
|
||||
|
||||
if (fprintf (script, " .ovly%d {\n", ++ovlynum) <= 0)
|
||||
goto file_err;
|
||||
for (j = base; j < i; j++)
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
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;
|
||||
|
||||
while (dummy_caller.call_list != NULL)
|
||||
{
|
||||
struct call_info *call = dummy_caller.call_list;
|
||||
|
@ -3820,11 +3746,120 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
|
|||
free (call);
|
||||
}
|
||||
|
||||
base = i;
|
||||
++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;
|
||||
|
||||
while (base < count)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
if (fprintf (script, " .ovly%u {\n", ovlynum) <= 0)
|
||||
goto file_err;
|
||||
|
||||
for (j = base; j < count && ovly_map[j] == ovlynum; j++)
|
||||
{
|
||||
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 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 < count && ovly_map[j] == ovlynum; 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)
|
||||
{
|
||||
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;
|
||||
|
||||
base = j;
|
||||
ovlynum += htab->params->num_regions;
|
||||
while (base < count && ovly_map[base] < ovlynum)
|
||||
base++;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
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.
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue