summaryrefslogtreecommitdiff
path: root/bfd/elf32-spu.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2009-11-03 13:58:49 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2009-11-03 13:58:49 +0000
commit6567fa84dc8325138a269fbd20e37bd163eebeed (patch)
tree9638dae807efe264a4236ce4bf19bfa7d89df7f2 /bfd/elf32-spu.c
parent1ee69515803d3297f776f3984d48e0c5a6b0687b (diff)
2009-11-03 Alan Modra <amodra@bigpond.net.au>
Ulrich Weigand <uweigand@de.ibm.com> * elf32-spu.c (mark_functions_via_relocs): Handle non-branch relocs (jump tables or other references to code labels) as well.
Diffstat (limited to 'bfd/elf32-spu.c')
-rw-r--r--bfd/elf32-spu.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index 890f260868..48025ffc60 100644
--- a/bfd/elf32-spu.c
+++ b/bfd/elf32-spu.c
@@ -2692,19 +2692,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 +2708,7 @@ mark_functions_via_relocs (asection *sec,
continue;
is_call = FALSE;
- if (!reject)
+ if (!nonbranch)
{
unsigned char insn[4];
@@ -2746,14 +2739,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 +2755,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 +2817,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;