(Logical change 1.45)
diff --git a/src/elf32.c b/src/elf32.c
index e69de29..f1c21e6 100644
--- a/src/elf32.c
+++ b/src/elf32.c
@@ -0,0 +1,2 @@
+#include "elf32.h"
+#include "elfxx.c"
diff --git a/src/elf32.h b/src/elf32.h
index e69de29..d27646c 100644
--- a/src/elf32.h
+++ b/src/elf32.h
@@ -0,0 +1,7 @@
+#ifndef elf32_h
+#define elf32_h
+
+#define ELF_CLASS ELFCLASS32
+#include "elfxx.h"
+
+#endif /* elf32_h */
diff --git a/src/elf64.c b/src/elf64.c
index e69de29..1154179 100644
--- a/src/elf64.c
+++ b/src/elf64.c
@@ -0,0 +1,2 @@
+#include "elf64.h"
+#include "elfxx.c"
diff --git a/src/elf64.h b/src/elf64.h
index e69de29..8f22384 100644
--- a/src/elf64.h
+++ b/src/elf64.h
@@ -0,0 +1,7 @@
+#ifndef elf64_h
+#define elf64_h
+
+#define ELF_CLASS ELFCLASS64
+#include "elfxx.h"
+
+#endif /* elf64_h */
diff --git a/src/elfxx.c b/src/elfxx.c
index e69de29..68985b5 100644
--- a/src/elfxx.c
+++ b/src/elfxx.c
@@ -0,0 +1,168 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+
+extern HIDDEN int
+elfW (valid_object) (struct elf_image *ei)
+{
+ if (ei->size <= EI_CLASS)
+ return 0;
+
+ return (memcmp (ei->image, ELFMAG, SELFMAG) == 0
+ && ((uint8_t *) ei->image)[EI_CLASS] == ELF_CLASS);
+}
+
+
+static int
+elfW (lookup_symbol) (unw_word_t ip, struct elf_image *ei,
+ ElfW (Addr) load_offset,
+ char *buf, size_t buf_len, unw_word_t *offp)
+{
+ size_t syment_size, str_size;
+ ElfW (Ehdr) *ehdr = ei->image;
+ ElfW (Sym) *sym, *symtab, *symtab_end;
+ ElfW (Off) soff, str_soff;
+ ElfW (Shdr) *shdr, *str_shdr;
+ ElfW (Addr) val, min_dist = ~(ElfW (Addr))0;
+ char *strtab;
+ int i;
+
+ if (!elfW (valid_object) (ei))
+ return -1;
+
+ soff = ehdr->e_shoff;
+ if (soff + ehdr->e_shnum * ehdr->e_shentsize > ei->size)
+ {
+ debug (1, "%s: section table outside of image? (%lu > %lu)\n",
+ __FUNCTION__, soff + ehdr->e_shnum * ehdr->e_shentsize,
+ ei->size);
+ return -1;
+ }
+
+ shdr = (ElfW (Shdr) *) ((char *) ei->image + soff);
+
+ for (i = 0; i < ehdr->e_shnum; ++i)
+ {
+ switch (shdr->sh_type)
+ {
+ case SHT_SYMTAB:
+ case SHT_DYNSYM:
+ symtab = (ElfW (Sym) *) ((char *) ei->image + shdr->sh_offset);
+ symtab_end = (ElfW (Sym) *) ((char *) symtab + shdr->sh_size);
+ syment_size = shdr->sh_entsize;
+
+ str_soff = soff + (shdr->sh_link * ehdr->e_shentsize);
+ if (str_soff + ehdr->e_shentsize >= ei->size)
+ {
+ debug (1, "%s: string table outside of image? (%lu >= %lu)\n",
+ __FUNCTION__, str_soff + ehdr->e_shentsize, ei->size);
+ break;
+ }
+ str_shdr = (ElfW (Shdr) *) ((char *) ei->image + str_soff);
+ str_size = str_shdr->sh_size;
+ strtab = (char *) ei->image + str_shdr->sh_offset;
+
+ debug (10, "symtab=0x%lx[%d], strtab=0x%lx\n", shdr->sh_offset,
+ shdr->sh_type, str_shdr->sh_offset);
+
+ for (sym = symtab;
+ sym < symtab_end;
+ sym = (ElfW (Sym) *) ((char *) sym + syment_size))
+ {
+ if (ELFW (ST_TYPE) (sym->st_info) == STT_FUNC
+ && sym->st_shndx != SHN_UNDEF)
+ {
+ val = sym->st_value;
+ if (sym->st_shndx != SHN_ABS)
+ val += load_offset;
+ debug (100, "0x%016lx info=0x%02x %s\n",
+ val, sym->st_info, strtab + sym->st_name);
+
+ if ((ElfW (Addr)) (ip - val) < min_dist)
+ {
+ min_dist = (ElfW (Addr)) (ip - val);
+ buf[buf_len - 1] = 'x';
+ strncpy (buf, strtab + sym->st_name, buf_len);
+ buf[buf_len - 1] = '\0';
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize);
+ }
+ if (min_dist >= ei->size)
+ return -1; /* not found */
+ if (offp)
+ *offp = min_dist;
+ return 0;
+}
+
+/* Find the ELF image that contains IP and return the "closest"
+ procedure name, if there is one. With some caching, this could be
+ sped up greatly, but until an application materializes that's
+ sensitive to the performance of this routine, why bother... */
+
+HIDDEN int
+elfW (get_proc_name) (unw_word_t ip, char *buf, size_t buf_len,
+ unw_word_t *offp)
+{
+ unsigned long segbase, mapoff;
+ ElfW (Addr) load_offset = 0;
+ struct elf_image ei;
+ ElfW (Ehdr) *ehdr;
+ ElfW (Phdr) *phdr;
+ int i, ret;
+
+ ret = tdep_get_elf_image (&ei, getpid (), ip, &segbase, &mapoff);
+ if (ret < 0)
+ return ret;
+
+ ehdr = ei.image;
+ phdr = (Elf64_Phdr *) ((char *) ei.image + ehdr->e_phoff);
+
+ for (i = 0; i < ehdr->e_phnum; ++i)
+ if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff)
+ {
+ load_offset = segbase - phdr[i].p_vaddr;
+ break;
+ }
+
+ ret = elfW (lookup_symbol) (ip, &ei, load_offset, buf, buf_len, offp);
+
+ munmap (ei.image, ei.size);
+ ei.image = NULL;
+
+ return ret;
+}
diff --git a/src/elfxx.h b/src/elfxx.h
index e69de29..b92253b 100644
--- a/src/elfxx.h
+++ b/src/elfxx.h
@@ -0,0 +1,71 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <elf.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+
+#include "internal.h"
+
+#if ELF_CLASS == ELFCLASS32
+# define ELFW(x) ELF32_##x
+# define ElfW(x) Elf32_##x
+# define elfW(x) _Uelf32_##x
+#else
+# define ELFW(x) ELF64_##x
+# define ElfW(x) Elf64_##x
+# define elfW(x) _Uelf64_##x
+#endif
+
+static inline int
+elf_map_image (struct elf_image *ei, char *path)
+{
+ struct stat stat;
+ int fd;
+
+ fd = open (path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (fstat (fd, &stat) < 0)
+ {
+ close (fd);
+ return -1;
+ }
+
+ ei->size = stat.st_size;
+ ei->image = mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close (fd);
+ if (ei->image == MAP_FAILED)
+ return -1;
+
+ return 0;
+}
+
+extern HIDDEN int elfW (valid_object) (struct elf_image *ei);
+extern HIDDEN int elfW (get_proc_name) (unw_word_t ip, char *buf, size_t len,
+ unw_word_t *offp);
diff --git a/src/ia64/mk_cursor_i-ia64.c b/src/ia64/mk_cursor_i-ia64.c
index e69de29..aa70a27 100644
--- a/src/ia64/mk_cursor_i-ia64.c
+++ b/src/ia64/mk_cursor_i-ia64.c
@@ -0,0 +1,104 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+/* Utility to generate cursor_i.h. */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "internal.h"
+
+#ifdef offsetof
+# undef offsetof
+#endif
+
+#define offsetof(type,field) ((char *) &((type *) 0)->field - (char *) 0)
+
+struct
+ {
+ const char name[256];
+ unsigned long value;
+ }
+tab[] =
+ {
+ { "IP_OFF", offsetof (struct cursor, ip) },
+ { "PR_OFF", offsetof (struct cursor, pr) },
+ { "BSP_OFF", offsetof (struct cursor, bsp) },
+ { "PSP_OFF", offsetof (struct cursor, psp) },
+ { "PFS_LOC_OFF", offsetof (struct cursor, pfs_loc) },
+ { "RNAT_LOC_OFF", offsetof (struct cursor, rnat_loc) },
+ { "UNAT_LOC_OFF", offsetof (struct cursor, unat_loc) },
+ { "LC_LOC_OFF", offsetof (struct cursor, lc_loc) },
+ { "FPSR_LOC_OFF", offsetof (struct cursor, fpsr_loc) },
+ { "B1_LOC_OFF", offsetof (struct cursor, b1_loc) },
+ { "B2_LOC_OFF", offsetof (struct cursor, b2_loc) },
+ { "B3_LOC_OFF", offsetof (struct cursor, b3_loc) },
+ { "B4_LOC_OFF", offsetof (struct cursor, b4_loc) },
+ { "B5_LOC_OFF", offsetof (struct cursor, b5_loc) },
+ { "F2_LOC_OFF", offsetof (struct cursor, f2_loc) },
+ { "F3_LOC_OFF", offsetof (struct cursor, f3_loc) },
+ { "F4_LOC_OFF", offsetof (struct cursor, f4_loc) },
+ { "F5_LOC_OFF", offsetof (struct cursor, f5_loc) },
+ { "FR_LOC_OFF", offsetof (struct cursor, fr_loc) },
+ { "SIGCONTEXT_LOC_OFF", offsetof (struct cursor, sigcontext_loc) },
+};
+
+static const char *tabs = "\t\t\t\t\t\t\t\t\t\t";
+
+int
+main (int argc, char **argv)
+{
+ const char *space;
+ int i, num_tabs;
+ size_t len;
+
+ printf ("#ifndef cursor_i_h\n");
+ printf ("#define cursor_i_h\n\n");
+
+ printf ("/*\n * DO NOT MODIFY\n *\n * This file was generated by "
+ "print_offsets.\n *\n */\n\n");
+
+ for (i = 0; i < (int) (sizeof (tab) / sizeof (tab[0])); ++i)
+ {
+ if (tab[i].name[0] == '\0')
+ printf ("\n");
+ else
+ {
+ len = strlen (tab[i].name);
+
+ num_tabs = (40 - len) / 8;
+ if (num_tabs <= 0)
+ space = " ";
+ else
+ space = strchr(tabs, '\0') - (40 - len) / 8;
+
+ printf ("#define %s%s%lu\t/* 0x%lx */\n",
+ tab[i].name, space, tab[i].value, tab[i].value);
+ }
+ }
+
+ printf ("\n#endif /* cursor_i_h */\n");
+ return 0;
+}
diff --git a/src/ia64/setjmp-ia64.S b/src/ia64/setjmp-ia64.S
index e69de29..52ecd53 100644
--- a/src/ia64/setjmp-ia64.S
+++ b/src/ia64/setjmp-ia64.S
@@ -0,0 +1,45 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+ .align 32
+
+ .global _setjmp
+
+ .proc _setjmp
+
+_setjmp:
+ mov r2 = ar.bsp
+ st8 [r32] = r12 // jmp_buf[0] = sp
+ mov r3 = rp
+
+ adds r16 = 8, r32
+ adds r17 = 16, r32
+ mov r8 = 0
+ ;;
+ st8 [r16] = r3 // jmp_buf[1] = rp
+ st8 [r17] = r2 // jmp_buf[2] = bsp
+ br.ret.sptk.many rp
+
+ .endp _setjmp
diff --git a/src/ia64/siglongjmp-ia64.S b/src/ia64/siglongjmp-ia64.S
index e69de29..3feccf2 100644
--- a/src/ia64/siglongjmp-ia64.S
+++ b/src/ia64/siglongjmp-ia64.S
@@ -0,0 +1,64 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define SIG_SETMASK 2
+
+ .globl _UI_siglongjmp_cont
+
+ .align 32
+ .proc siglongjmp_continuation
+siglongjmp_continuation:
+_UI_siglongjmp_cont: // non-function label for {sig,}longjmp.c
+ .prologue
+ .save rp, r15
+ .body
+ nop 0
+ nop 0
+ br.call.sptk.many b6 = 1f
+ ;;
+ .prologue
+ .save ar.pfs, r33
+1: alloc loc1 = ar.pfs, 0, 3, 3, 0
+ /*
+ * Note: we can use the scratch stack are because the caller
+ * of sigsetjmp() by definition is not a leaf-procedure.
+ */
+ st8 [sp] = r17 // store signal mask
+ .save rp, loc0
+ mov loc0 = r15 // final continuation point
+ ;;
+ .body
+ mov loc2 = r16 // value to return in r8
+
+ mov out0 = SIG_SETMASK
+ mov out1 = sp
+ mov out2 = r0
+ br.call.sptk.many rp = sigprocmask
+ ;;
+ mov rp = loc0
+ mov ar.pfs = loc1
+ mov r8 = loc2
+ br.ret.sptk.many rp
+ .endp siglongjmp_continuation
diff --git a/src/ia64/sigsetjmp-ia64.S b/src/ia64/sigsetjmp-ia64.S
index e69de29..271d29d 100644
--- a/src/ia64/sigsetjmp-ia64.S
+++ b/src/ia64/sigsetjmp-ia64.S
@@ -0,0 +1,64 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define SIG_BLOCK 0
+
+ .align 32
+
+ .global __sigsetjmp
+
+ .proc __sigsetjmp
+
+__sigsetjmp:
+ .prologue
+ .save ar.pfs, r35
+ alloc loc1 = ar.pfs, 2, 3, 3, 0
+ add r16 = 16, in0
+ add out2 = 24, in0
+
+ st8 [in0] = sp, 8 // sigjmp_buf[0] = sp
+ mov out0 = SIG_BLOCK
+ .save rp, loc0
+ mov loc0 = rp
+ .body
+ ;;
+ st8 [in0] = loc0, 24 // sigjmp_buf[1] = rp
+ st8 [r16] = in1 // sigjmp_buf[2] = savemask
+ cmp.ne p6, p0 = in1, r0
+
+ mov out1 = r0
+ mov loc2 = ar.bsp
+(p6) br.call.sptk.many rp = sigprocmask // sigjmp_buf[3] = sigmask
+ ;;
+
+ st8 [in0] = loc2 // sigjmp_buf[4] = bsp
+ mov rp = loc0
+ nop 0
+
+ mov r8 = 0
+ mov.i ar.pfs = loc1
+ br.ret.sptk.many rp
+
+ .endp __sigsetjmp
diff --git a/src/longjmp.c b/src/longjmp.c
index e69de29..69bfeba 100644
--- a/src/longjmp.c
+++ b/src/longjmp.c
@@ -0,0 +1,109 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define UNW_LOCAL_ONLY
+
+#include <libunwind.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#if UNW_TARGET_IA64
+# include "ia64/rse.h"
+#endif
+
+void
+_longjmp (jmp_buf env, int val)
+{
+ extern int _UI_siglongjmp_cont;
+ sigset_t current_mask;
+ unw_context_t uc;
+ unw_cursor_t c;
+ unw_word_t sp;
+ unw_word_t *wp = (unw_word_t *) env;
+
+ if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0)
+ abort ();
+
+ do
+ {
+ if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0)
+ abort ();
+ if (sp != wp[0])
+ continue;
+
+#if UNW_TARGET_IA64
+ {
+ unw_word_t bsp, pfs, sol;
+
+ if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0
+ || unw_get_reg (&c, UNW_IA64_AR_PFS, &pfs) < 0)
+ abort ();
+
+ /* simulate the effect of "br.call setjmp" on ar.bsp: */
+ sol = (pfs >> 7) & 0x7f;
+ bsp = ia64_rse_skip_regs (bsp, sol);
+
+ if (bsp != wp[2])
+ continue;
+ }
+#endif
+
+ /* found the right frame: */
+
+ if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0)
+ abort ();
+
+ if (unw_set_reg (&c, UNW_REG_EH_ARG0, wp[1]) < 0
+ || unw_set_reg (&c, UNW_REG_EH_ARG1, val) < 0
+ || unw_set_reg (&c, UNW_REG_EH_ARG2,
+ ((unw_word_t *) ¤t_mask)[0]) < 0
+ || unw_set_reg (&c, UNW_REG_IP,
+ (unw_word_t) &_UI_siglongjmp_cont))
+ abort ();
+
+ if (_NSIG > 8 * sizeof (unw_word_t))
+ {
+ if (_NSIG > 16 * sizeof (unw_word_t))
+ abort ();
+ if (unw_set_reg (&c, UNW_REG_EH_ARG3,
+ ((unw_word_t *) ¤t_mask)[1]) < 0)
+ abort ();
+ }
+
+ unw_resume (&c);
+
+ abort ();
+ }
+ while (unw_step (&c) >= 0);
+
+ abort ();
+}
+
+void
+longjmp (jmp_buf env, int val)
+{
+ _longjmp (env, val);
+}
diff --git a/src/os-linux.c b/src/os-linux.c
index e69de29..b4b8d71 100644
--- a/src/os-linux.c
+++ b/src/os-linux.c
@@ -0,0 +1,63 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef UNW_REMOTE_ONLY
+
+#include <limits.h>
+#include <stdio.h>
+
+#include "internal.h"
+#include "os-linux.h"
+
+/* Here, it doesn't matter whether we include elf64.h or elf32.h.
+ Both define "struct elf_image" and elf_map_image() in an identical
+ fashion. */
+#include "elf64.h"
+
+HIDDEN int
+tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
+ unsigned long *segbase, unsigned long *mapoff)
+{
+ struct map_iterator mi;
+ char path[PATH_MAX];
+ int found = 0;
+ unsigned long hi;
+
+ maps_init (&mi, pid);
+ while (maps_next (&mi, segbase, &hi, mapoff, path))
+ if (ip >= *segbase && ip < hi)
+ {
+ found = 1;
+ break;
+ }
+ maps_close (&mi);
+
+ if (!found)
+ return -1;
+
+ return elf_map_image (ei, path);
+}
+
+#endif /* UNW_REMOTE_ONLY */
diff --git a/src/os-linux.h b/src/os-linux.h
index e69de29..88ba4ac 100644
--- a/src/os-linux.h
+++ b/src/os-linux.h
@@ -0,0 +1,69 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef os_linux_h
+#define os_linux_h
+
+struct map_iterator
+ {
+ FILE *fp;
+ };
+
+static inline void
+maps_init (struct map_iterator *mi, pid_t pid)
+{
+ char path[PATH_MAX];
+
+ snprintf (path, sizeof (path), "/proc/%d/maps", pid);
+ mi->fp = fopen (path, "r");
+}
+
+static inline int
+maps_next (struct map_iterator *mi,
+ unsigned long *low, unsigned long *high, unsigned long *offset,
+ char *path)
+{
+ char line[256+PATH_MAX];
+
+ if (!mi->fp)
+ return 0;
+
+ while (fgets (line, sizeof (line), mi->fp))
+ {
+ if (sscanf (line, "%lx-%lx %*4c %lx %*x:%*x %*d %s\n",
+ low, high, offset, path) == 4)
+ return 1;
+ }
+ return 0;
+}
+
+static inline void
+maps_close (struct map_iterator *mi)
+{
+ fclose (mi->fp);
+ mi->fp = NULL;
+}
+
+#endif /* os_linux_h */
diff --git a/src/setjmp.c b/src/setjmp.c
index e69de29..8901071 100644
--- a/src/setjmp.c
+++ b/src/setjmp.c
@@ -0,0 +1,52 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <libunwind.h>
+#include <setjmp.h>
+
+/* Why use K&R syntax here? setjmp() is often a macro and that
+ expands into a call to, say, __setjmp() and we need to define the
+ libunwind-version of setjmp() with the name of the actual function.
+ Using K&R syntax lets us keep the setjmp() macro while keeping the
+ syntax valid... This trick works provided setjmp() doesn't do
+ anything other than a function call. */
+
+int
+setjmp (env)
+ jmp_buf env;
+{
+ void **wp = (void **) env;
+
+#if UNW_TARGET_IA64
+ wp[0] = __builtin_dwarf_cfa () - 16;
+ wp[1] = __builtin_ia64_bsp ();
+#else
+ /* this should work on most platforms, but may not be
+ performance-optimal; check the code! */
+ wp[0] = __builtin_frame_address (0);
+ wp[1] = (void *) (uintptr_t) 0;
+#endif
+ return 0;
+}
diff --git a/src/siglongjmp.c b/src/siglongjmp.c
index e69de29..9762410 100644
--- a/src/siglongjmp.c
+++ b/src/siglongjmp.c
@@ -0,0 +1,108 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define UNW_LOCAL_ONLY
+
+#include <libunwind.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#if UNW_TARGET_IA64
+# include "ia64/rse.h"
+#endif
+
+void
+siglongjmp (sigjmp_buf env, int val)
+{
+ unw_word_t *mp, *wp = (unw_word_t *) env;
+ extern int _UI_siglongjmp_cont;
+ sigset_t current_mask;
+ unw_context_t uc;
+ unw_cursor_t c;
+ unw_word_t sp;
+
+ if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0)
+ abort ();
+
+ do
+ {
+ if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0)
+ abort ();
+ if (sp != wp[0])
+ continue;
+
+#if UNW_TARGET_IA64
+ {
+ unw_word_t bsp, pfs, sol;
+
+ if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0
+ || unw_get_reg (&c, UNW_IA64_AR_PFS, &pfs) < 0)
+ abort ();
+
+ /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */
+ sol = (pfs >> 7) & 0x7f;
+ bsp = ia64_rse_skip_regs (bsp, sol);
+
+ if (bsp != wp[4])
+ continue;
+ }
+#endif
+
+ /* found the right frame: */
+
+ if (wp[2])
+ mp = wp + 3;
+ else
+ {
+ /* sigmask wasn't saved; get it now so we can leave it unchanged. */
+ if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0)
+ abort ();
+ mp = (unw_word_t *) ¤t_mask;
+ }
+
+ if (unw_set_reg (&c, UNW_REG_EH_ARG0, wp[1]) < 0
+ || unw_set_reg (&c, UNW_REG_EH_ARG1, val) < 0
+ || unw_set_reg (&c, UNW_REG_EH_ARG2, mp[0]) < 0
+ || unw_set_reg (&c, UNW_REG_IP,
+ (unw_word_t) &_UI_siglongjmp_cont))
+ abort ();
+
+ if (_NSIG > 8 * sizeof (unw_word_t))
+ {
+ if (_NSIG > 16 * sizeof (unw_word_t))
+ abort ();
+ if (unw_set_reg (&c, UNW_REG_EH_ARG3, mp[1]) < 0)
+ abort ();
+ }
+
+ unw_resume (&c);
+
+ abort ();
+ }
+ while (unw_step (&c) >= 0);
+
+ abort ();
+}
diff --git a/src/sigsetjmp.c b/src/sigsetjmp.c
index e69de29..7378287 100644
--- a/src/sigsetjmp.c
+++ b/src/sigsetjmp.c
@@ -0,0 +1,47 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <libunwind.h>
+#include <setjmp.h>
+#include <stdlib.h>
+
+int
+sigsetjmp (sigjmp_buf env, int savemask)
+{
+ unw_word_t *wp = (unw_word_t *) env;
+
+ /* This should work on most platforms, but may not be
+ performance-optimal; check the code! */
+
+ wp[0] = (unw_word_t) __builtin_frame_address (0);
+ wp[1] = (unw_word_t) __builtin_return_address (0);
+ wp[2] = savemask;
+
+ /* Note: we assume here that "wp" has same or better alignment as
+ sigset_t. */
+ if (savemask && sigprocmask (SIG_BLOCK, NULL, (sigset_t *) (wp + 3)) < 0)
+ abort ();
+ return 0;
+}