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) |