diff options
author | Alan Modra <amodra@gmail.com> | 2008-06-16 16:16:31 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2008-06-16 16:16:31 +0000 |
commit | 99302af9a20c001bbc360d6c9721ce3fdd429530 (patch) | |
tree | 073f35056649b3124448468d78ad6bba9d438372 /bfd/elf32-spu.c | |
parent | 7a2de473a3b65c21cdc483217bd37af14c54c6ce (diff) | |
download | gdb-99302af9a20c001bbc360d6c9721ce3fdd429530.zip gdb-99302af9a20c001bbc360d6c9721ce3fdd429530.tar.gz gdb-99302af9a20c001bbc360d6c9721ce3fdd429530.tar.bz2 |
bfd/
* elf32-spu.c (struct spu_link_hash_table): Add extra_stack_space.
(spu_elf_check_vma): Add extra_stack_space param, copy to htab.
(spu_elf_auto_overlay): Use it.
(RECURSE_UNMARK): Define as 0.
(unmark_overlay_section): Heed RECURSE_UNMARK.
* elf32-spu.h (spu_elf_check_vma): Update prototype.
ld/
* emultempl/spuelf.em (extra_stack_space): New variable.
(gld${EMULATION_NAME}_finish): Pass it to spu_elf_check_vma.
(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS,
PARSE_AND_LIST_ARGS_CASES): Handle --extra-stack-space.
* emultempl/spu_ovl.S: Mask interrupts during dma and update of
overlay manager structures.
* emultempl/spu_ovl.o: Regenerate.
Diffstat (limited to 'bfd/elf32-spu.c')
-rw-r--r-- | bfd/elf32-spu.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index eac2e85..590ebd5 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -325,6 +325,11 @@ struct spu_link_hash_table unsigned int overlay_fixed; /* Local store --auto-overlay should reserve for stack and heap. */ unsigned int reserved; + /* If reserved is not specified, stack analysis will calculate a value + for the stack. This parameter adjusts that value to allow for + negative sp access (the ABI says 2000 bytes below sp are valid, + and the overlay manager uses some of this area). */ + int extra_stack_space; /* Count of overlay stubs needed in non-overlay area. */ unsigned int non_ovly_stub; @@ -1548,6 +1553,7 @@ spu_elf_check_vma (struct bfd_link_info *info, unsigned int hi, unsigned int overlay_fixed, unsigned int reserved, + int extra_stack_space, void (*spu_elf_load_ovl_mgr) (void), FILE *(*spu_elf_open_overlay_script) (void), void (*spu_elf_relink) (void)) @@ -1562,6 +1568,7 @@ spu_elf_check_vma (struct bfd_link_info *info, htab->local_store = hi + 1 - lo; htab->overlay_fixed = overlay_fixed; htab->reserved = reserved; + htab->extra_stack_space = extra_stack_space; htab->spu_elf_load_ovl_mgr = spu_elf_load_ovl_mgr; htab->spu_elf_open_overlay_script = spu_elf_open_overlay_script; htab->spu_elf_relink = spu_elf_relink; @@ -2923,6 +2930,11 @@ mark_overlay_section (struct function_info *fun, return TRUE; } +/* If non-zero then unmark functions called from those within sections + that we need to unmark. Unfortunately this isn't reliable since the + call graph cannot know the destination of function pointer calls. */ +#define RECURSE_UNMARK 0 + struct _uos_param { asection *exclude_input_section; asection *exclude_output_section; @@ -2950,9 +2962,10 @@ unmark_overlay_section (struct function_info *fun, || fun->sec->output_section == uos_param->exclude_output_section) excluded = 1; - uos_param->clearing += excluded; + if (RECURSE_UNMARK) + uos_param->clearing += excluded; - if (uos_param->clearing) + if (RECURSE_UNMARK ? uos_param->clearing : excluded) { fun->sec->linker_mark = 0; if (fun->rodata) @@ -2963,7 +2976,8 @@ unmark_overlay_section (struct function_info *fun, if (!unmark_overlay_section (call->fun, info, param)) return FALSE; - uos_param->clearing -= excluded; + if (RECURSE_UNMARK) + uos_param->clearing -= excluded; return TRUE; } @@ -3574,7 +3588,7 @@ spu_elf_auto_overlay (struct bfd_link_info *info, sum_stack_param.overall_stack = 0; if (!for_each_node (sum_stack, info, &sum_stack_param, TRUE)) goto err_exit; - htab->reserved = sum_stack_param.overall_stack + 2000; + htab->reserved = sum_stack_param.overall_stack + htab->extra_stack_space; } fixed_size += htab->reserved; fixed_size += htab->non_ovly_stub * OVL_STUB_SIZE; |