summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2007-03-17 02:56:37 +0000
committerAlan Modra <amodra@bigpond.net.au>2007-03-17 02:56:37 +0000
commit7e8c1673b3a91cac9e1e2be716b64f38d75be169 (patch)
treec6def5d1a82961b2ad999e3e2e86bb97cefc22bd /bfd
parent1e7f75b5b5d7c2610a7f0607993972d050c952ad (diff)
downloadgdb-7e8c1673b3a91cac9e1e2be716b64f38d75be169.tar.gz
* elf32-spu.c (spu_elf_size_stubs): Always use an overlay stub
on setjmp calls.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf32-spu.c16
2 files changed, 19 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7f319a79ca4..3db69191cd4 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 8d130b86ff2..0326e84c962 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