diff options
author | Alan Modra <amodra@gmail.com> | 2007-03-17 02:56:37 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2007-03-17 02:56:37 +0000 |
commit | 5384511fec8c3ab7aa9e53eb1013c4a43241a8fc (patch) | |
tree | 019fcdc41c38b2b8d866bc2f058179fdbd987ea3 /bfd | |
parent | bc7c4163e6b43a3be4315ba3cb5615b46ae56f0c (diff) | |
download | gdb-5384511fec8c3ab7aa9e53eb1013c4a43241a8fc.zip gdb-5384511fec8c3ab7aa9e53eb1013c4a43241a8fc.tar.gz gdb-5384511fec8c3ab7aa9e53eb1013c4a43241a8fc.tar.bz2 |
* elf32-spu.c (spu_elf_size_stubs): Always use an overlay stub
on setjmp calls.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf32-spu.c | 16 |
2 files changed, 19 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7f319a7..3db6919 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2007-03-17 Alan Modra <amodra@bigpond.net.au> + + * elf32-spu.c (spu_elf_size_stubs): Always use an overlay stub + on setjmp calls. + 2007-03-15 H.J. Lu <hongjiu.lu@intel.com> * doc/Makefile.in: Regenerated. diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index 8d130b8..0326e84 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -801,6 +801,7 @@ spu_elf_size_stubs (bfd *output_bfd, struct spu_stub_hash_entry *sh; unsigned int sym_type; enum _insn_type { non_branch, branch, call } insn_type; + bfd_boolean is_setjmp; r_type = ELF32_R_TYPE (irela->r_info); r_indx = ELF32_R_SYM (irela->r_info); @@ -877,15 +878,26 @@ spu_elf_size_stubs (bfd *output_bfd, continue; } + /* setjmp always goes via an overlay stub, because + then the return and hence the longjmp goes via + __ovly_return. That magically makes setjmp/longjmp + between overlays work. */ + is_setjmp = (h != NULL + && strncmp (h->root.root.string, "setjmp", 6) == 0 + && (h->root.root.string[6] == '\0' + || h->root.root.string[6] == '@')); + /* Usually, non-overlay sections don't need stubs. */ if (!spu_elf_section_data (sym_sec->output_section)->ovl_index - && !non_overlay_stubs) + && !non_overlay_stubs + && !is_setjmp) continue; /* We need a reference from some other section before we consider that a symbol might need an overlay stub. */ if (spu_elf_section_data (sym_sec->output_section)->ovl_index - == spu_elf_section_data (section->output_section)->ovl_index) + == spu_elf_section_data (section->output_section)->ovl_index + && !is_setjmp) { /* Or we need this to *not* be a branch. ie. We are possibly taking the address of a function and |