From 81402edc4aee63f3e0700e93f67b36894592ce04 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 3 Nov 2009 13:58:47 +0000 Subject: [PATCH] 2009-11-03 Alan Modra Ulrich Weigand * elf32-spu.c (mark_functions_via_relocs): Handle non-branch relocs (jump tables or other references to code labels) as well. --- bfd/ChangeLog | 6 ++++++ bfd/elf32-spu.c | 38 +++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ce48a24ec6..3c8fd003e0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2009-11-03 Alan Modra + Ulrich Weigand + + * elf32-spu.c (mark_functions_via_relocs): Handle non-branch relocs + (jump tables or other references to code labels) as well. + 2009-11-02 Paul Brook * elf32-arm.c (elf32_arm_merge_eabi_attributes): Handle VFPv4 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; -- 2.11.0