| Index: binutils/bfd/elf32-spu.c
|
| diff --git a/binutils/bfd/elf32-spu.c b/binutils/bfd/elf32-spu.c
|
| index 890f260868f71cacf6789a7b0845a78ba156f953..250beef3d0ffbbdad83e167096ecfcf0cff6c653 100644
|
| --- a/binutils/bfd/elf32-spu.c
|
| +++ b/binutils/bfd/elf32-spu.c
|
| @@ -331,16 +331,7 @@ struct spu_link_hash_table
|
|
|
| /* How much memory we have. */
|
| unsigned int local_store;
|
| - /* Local store --auto-overlay should reserve for non-overlay
|
| - functions and data. */
|
| - 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;
|
|
|
| @@ -2692,19 +2683,12 @@ mark_functions_via_relocs (asection *sec,
|
| Elf_Internal_Sym *sym;
|
| struct elf_link_hash_entry *h;
|
| bfd_vma val;
|
| - bfd_boolean reject, is_call;
|
| + bfd_boolean nonbranch, is_call;
|
| struct function_info *caller;
|
| struct call_info *callee;
|
|
|
| - reject = FALSE;
|
| r_type = ELF32_R_TYPE (irela->r_info);
|
| - if (r_type != R_SPU_REL16
|
| - && r_type != R_SPU_ADDR16)
|
| - {
|
| - reject = TRUE;
|
| - if (!(call_tree && spu_hash_table (info)->params->auto_overlay))
|
| - continue;
|
| - }
|
| + nonbranch = r_type != R_SPU_REL16 && r_type != R_SPU_ADDR16;
|
|
|
| r_indx = ELF32_R_SYM (irela->r_info);
|
| if (!get_sym_h (&h, &sym, &sym_sec, psyms, r_indx, sec->owner))
|
| @@ -2715,7 +2699,7 @@ mark_functions_via_relocs (asection *sec,
|
| continue;
|
|
|
| is_call = FALSE;
|
| - if (!reject)
|
| + if (!nonbranch)
|
| {
|
| unsigned char insn[4];
|
|
|
| @@ -2746,14 +2730,13 @@ mark_functions_via_relocs (asection *sec,
|
| }
|
| else
|
| {
|
| - reject = TRUE;
|
| - if (!(call_tree && spu_hash_table (info)->params->auto_overlay)
|
| - || is_hint (insn))
|
| + nonbranch = TRUE;
|
| + if (is_hint (insn))
|
| continue;
|
| }
|
| }
|
|
|
| - if (reject)
|
| + if (nonbranch)
|
| {
|
| /* For --auto-overlay, count possible stubs we need for
|
| function pointer references. */
|
| @@ -2763,8 +2746,20 @@ mark_functions_via_relocs (asection *sec,
|
| else
|
| sym_type = ELF_ST_TYPE (sym->st_info);
|
| if (sym_type == STT_FUNC)
|
| - spu_hash_table (info)->non_ovly_stub += 1;
|
| - continue;
|
| + {
|
| + if (call_tree && spu_hash_table (info)->params->auto_overlay)
|
| + spu_hash_table (info)->non_ovly_stub += 1;
|
| + /* If the symbol type is STT_FUNC then this must be a
|
| + function pointer initialisation. */
|
| + continue;
|
| + }
|
| + /* Ignore data references. */
|
| + if ((sym_sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE))
|
| + != (SEC_ALLOC | SEC_LOAD | SEC_CODE))
|
| + continue;
|
| + /* Otherwise we probably have a jump table reloc for
|
| + a switch statement or some other reference to a
|
| + code label. */
|
| }
|
|
|
| if (h)
|
| @@ -2813,7 +2808,7 @@ mark_functions_via_relocs (asection *sec,
|
| callee->is_pasted = FALSE;
|
| callee->broken_cycle = FALSE;
|
| callee->priority = priority;
|
| - callee->count = 1;
|
| + callee->count = nonbranch? 0 : 1;
|
| if (callee->fun->last_caller != sec)
|
| {
|
| callee->fun->last_caller = sec;
|
| @@ -4159,6 +4154,7 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
|
| bfd **bfd_arr;
|
| struct elf_segment_map *m;
|
| unsigned int fixed_size, lo, hi;
|
| + unsigned int reserved;
|
| struct spu_link_hash_table *htab;
|
| unsigned int base, i, count, bfd_count;
|
| unsigned int region, ovlynum;
|
| @@ -4194,7 +4190,8 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
|
| goto err_exit;
|
|
|
| htab = spu_hash_table (info);
|
| - if (htab->reserved == 0)
|
| + reserved = htab->params->auto_overlay_reserved;
|
| + if (reserved == 0)
|
| {
|
| struct _sum_stack_param sum_stack_param;
|
|
|
| @@ -4202,11 +4199,12 @@ 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 + htab->extra_stack_space;
|
| + reserved = (sum_stack_param.overall_stack
|
| + + htab->params->extra_stack_space);
|
| }
|
|
|
| /* No need for overlays if everything already fits. */
|
| - if (fixed_size + htab->reserved <= htab->local_store
|
| + if (fixed_size + reserved <= htab->local_store
|
| && htab->params->ovly_flavour != ovly_soft_icache)
|
| {
|
| htab->params->auto_overlay = 0;
|
| @@ -4319,7 +4317,7 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
|
| }
|
| free (bfd_arr);
|
|
|
| - fixed_size += htab->reserved;
|
| + fixed_size += reserved;
|
| fixed_size += htab->non_ovly_stub * ovl_stub_size (htab->params);
|
| if (fixed_size + mos_param.max_overlay_size <= htab->local_store)
|
| {
|
| @@ -4358,13 +4356,13 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
|
| (bfd_vma) mos_param.max_overlay_size);
|
|
|
| /* Now see if we should put some functions in the non-overlay area. */
|
| - else if (fixed_size < htab->overlay_fixed)
|
| + else if (fixed_size < htab->params->auto_overlay_fixed)
|
| {
|
| unsigned int max_fixed, lib_size;
|
|
|
| max_fixed = htab->local_store - mos_param.max_overlay_size;
|
| - if (max_fixed > htab->overlay_fixed)
|
| - max_fixed = htab->overlay_fixed;
|
| + if (max_fixed > htab->params->auto_overlay_fixed)
|
| + max_fixed = htab->params->auto_overlay_fixed;
|
| lib_size = max_fixed - fixed_size;
|
| lib_size = auto_ovl_lib_functions (info, lib_size);
|
| if (lib_size == (unsigned int) -1)
|
|
|