aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-spu.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2008-02-28 09:30:27 +0000
committerAlan Modra <amodra@gmail.com>2008-02-28 09:30:27 +0000
commit911f096e1a0b04d82d059a42e459b15503c285ce (patch)
tree2c44d703a1e26f521515cbdf359f4939e10de418 /bfd/elf32-spu.c
parent6fe305f7fb813317dced51a909bc3c8a7b164689 (diff)
downloadgdb-911f096e1a0b04d82d059a42e459b15503c285ce.zip
gdb-911f096e1a0b04d82d059a42e459b15503c285ce.tar.gz
gdb-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/elf32-spu.c')
-rw-r--r--bfd/elf32-spu.c38
1 files changed, 27 insertions, 11 deletions
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;
}