diff options
author | Alan Modra <amodra@gmail.com> | 2008-02-28 09:30:27 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2008-02-28 09:30:27 +0000 |
commit | 911f096e1a0b04d82d059a42e459b15503c285ce (patch) | |
tree | 2c44d703a1e26f521515cbdf359f4939e10de418 /bfd | |
parent | 6fe305f7fb813317dced51a909bc3c8a7b164689 (diff) | |
download | binutils-911f096e1a0b04d82d059a42e459b15503c285ce.zip binutils-911f096e1a0b04d82d059a42e459b15503c285ce.tar.gz binutils-911f096e1a0b04d82d059a42e459b15503c285ce.tar.bz2 |
* elf32-spu.c (mark_functions_via_relocs): Don't assume that
the "->start" pointer reaches to function origin, so that we
can handle functions split over more than two sections.
(build_call_tree): Likewise.
(pasted_function): Don't attempt to set fun->start back to the
function origin, just go back one section.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elf32-spu.c | 38 |
2 files changed, 37 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1646c19..15b939d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2008-02-28 Alan Modra <amodra@bigpond.net.au> + + * elf32-spu.c (mark_functions_via_relocs): Don't assume that + the "->start" pointer reaches to function origin, so that we + can handle functions split over more than two sections. + (build_call_tree): Likewise. + (pasted_function): Don't attempt to set fun->start back to the + function origin, just go back one section. + 2008-02-27 Catherine Moore <clm@codesourcery.com> * elf.c ( _bfd_elf_print_private_bfd_data): Call @@ -9,7 +18,7 @@ * elfxx-mips.h (_bfd_mips_elf_get_target_dtag): Declare. * elf-bfd.h (elf_backend_get_target_dtag): Add prototype. * elfxx-target.h (elf_backend_get_target_dtag): Add default. - (elf_backend_data): Add elf_backend_get_target_dtag. + (elf_backend_data): Add elf_backend_get_target_dtag. 2008-02-26 Alan Modra <amodra@bigpond.net.au> diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index 826512f..3557c6b 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -1997,14 +1997,29 @@ mark_functions_via_relocs (asection *sec, destination has been called by some other function then it is a separate function. We also assume that functions are not split across input files. */ - if (callee->fun->start != NULL - || sec->owner != sym_sec->owner) + if (sec->owner != sym_sec->owner) { callee->fun->start = NULL; callee->fun->is_func = TRUE; } - else + else if (callee->fun->start == NULL) callee->fun->start = caller; + else + { + struct function_info *callee_start; + struct function_info *caller_start; + callee_start = callee->fun; + while (callee_start->start) + callee_start = callee_start->start; + caller_start = caller; + while (caller_start->start) + caller_start = caller_start->start; + if (caller_start != callee_start) + { + callee->fun->start = NULL; + callee->fun->is_func = TRUE; + } + } } } @@ -2041,11 +2056,7 @@ pasted_function (asection *sec, struct bfd_link_info *info) if (l->u.indirect.section == sec) { if (fun_start != NULL) - { - if (fun_start->start) - fun_start = fun_start->start; - fun->start = fun_start; - } + fun->start = fun_start; return TRUE; } if (l->type == bfd_indirect_link_order @@ -2382,14 +2393,19 @@ build_call_tree (bfd *output_bfd, struct bfd_link_info *info) int i; for (i = 0; i < sinfo->num_fun; ++i) { - if (sinfo->fun[i].start != NULL) + struct function_info *start = sinfo->fun[i].start; + + if (start != NULL) { - struct call_info *call = sinfo->fun[i].call_list; + struct call_info *call; + while (start->start != NULL) + start = start->start; + call = sinfo->fun[i].call_list; while (call != NULL) { struct call_info *call_next = call->next; - if (!insert_callee (sinfo->fun[i].start, call)) + if (!insert_callee (start, call)) free (call); call = call_next; } |