1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-26 09:07:38 +01:00

(Logical change 1.33)

This commit is contained in:
mostang.com!davidm 2003-01-14 07:11:56 +00:00
parent 3604b05a6c
commit 6d611572ef
22 changed files with 1091 additions and 0 deletions

79
include/libunwind-hppa.h Normal file
View file

@ -0,0 +1,79 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by Scott Marovitch
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 LIBUNWIND_H
#define LIBUNWIND_H
#include <stdint.h>
#include <ucontext.h>
#define UNW_TARGET hppa
#define UNW_TARGET_HPPA 1
typedef uint64_t unw_tdep_word_t;
typedef enum
{
/* Note: general registers are excepted to start with index 0.
This convention facilitates architecture-independent
implementation of the C++ exception handling ABI. See
_Unwind_SetGR() and _Unwind_GetGR() for details. */
UNW_HPPA_GR = 0,
UNW_HPPA_SP = UNW_HPPA_GR + 30,
UNW_HPPA_FR = UNW_HPPA_GR + 32,
UNW_HPPA_IP = UNW_HPPA_FR + 32, /* instruction pointer */
/* other "preserved" registers (fpsr etc.)... */
UNW_TDEP_LAST_REG = UNW_HPPA_IP,
UNW_TDEP_IP = UNW_HPPA_IP,
UNW_TDEP_SP = UNW_HPPA_SP
}
hppa_regnum_t;
typedef struct unw_tdep_save_loc
{
/* Additional target-dependent info on a save location. */
}
unw_tdep_save_loc_t;
/* On PA-RISC, we can directly use ucontext_t as the unwind context. */
typedef ucontext_t unw_tdep_context_t;
/* XXX this is not ideal: an application should not be prevented from
using the "getcontext" name just because it's using libunwind. We
can't just use __getcontext() either, because that isn't exported
by glibc... */
#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
/* XXX fixme: */
#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 128)
#include "libunwind-common.h"
#endif /* LIBUNWIND_H */

90
include/tdep-hppa.h Normal file
View file

@ -0,0 +1,90 @@
/* 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 TDEP_HPPA_H
#define TDEP_HPPA_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
#include <stdlib.h>
#include <libunwind.h>
enum hppa_pregnum
{
HPPA_NUM_PREGS
};
struct hppa_loc
{
unw_word_t val;
#ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see HPPA_LOC_TYPE_* macros. */
#endif
};
struct unw_addr_space
{
struct unw_accessors acc;
unw_caching_policy_t caching_policy;
uint32_t cache_generation;
unw_word_t dyn_generation; /* see dyn-common.h */
};
struct cursor
{
unw_addr_space_t as;
void *as_arg;
/* IP & SP cache: */
unw_word_t ip;
unw_word_t sp;
struct hppa_loc ip_loc;
struct hppa_loc sp_loc;
};
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */
#define tdep_search_unwind_table(a,b,c,d,e,f) \
UNW_ARCH_OBJ(search_unwind_table) (a,b,c,d,e,f)
#define tdep_find_proc_info(as,ip,pi,n,a) \
UNW_ARCH_OBJ(find_proc_info) (as,ip,pi,n,a)
#define tdep_put_unwind_info(a,b,c) UNW_ARCH_OBJ(put_unwind_info)(a,b,c)
#define tdep_uc_addr(uc,reg) UNW_ARCH_OBJ(uc_addr)(uc,reg)
#define tdep_debug_level UNW_ARCH_OBJ(debug_level)
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg);
extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info,
void *arg);
extern void tdep_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg);
extern int tdep_debug_level;
#endif /* TDEP_HPPA_H */

View file

@ -0,0 +1,42 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
int
unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi)
{
#if 0
struct cursor *c = (struct cursor *) cursor;
int ret;
#endif
printf ("%s: implement me, please\n", __FUNCTION__);
#if 0
if ((ret = ia64_make_proc_info (c)) < 0)
return ret;
#endif
return 0;
}

View file

@ -0,0 +1,35 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
int
unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len)
{
struct cursor *c = (struct cursor *) cursor;
return unwi_get_proc_name (c->as, c->ip, c->as == unw_local_addr_space,
buf, buf_len, c->as_arg);
}

34
src/hppa/Gget_reg-hppa.c Normal file
View file

@ -0,0 +1,34 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
int
unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
{
struct cursor *c = (struct cursor *) cursor;
return hppa_access_reg (c, regnum, valp, 0);
}

199
src/hppa/Ginit-hppa.c Normal file
View file

@ -0,0 +1,199 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2002 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 <stdlib.h>
#include <string.h>
#include "unwind_i.h"
#ifdef UNW_REMOTE_ONLY
/* unw_local_addr_space is a NULL pointer in this case. */
unw_addr_space_t unw_local_addr_space;
#else /* !UNW_REMOTE_ONLY */
static struct unw_addr_space local_addr_space;
unw_addr_space_t unw_local_addr_space = &local_addr_space;
static inline void *
uc_addr (ucontext_t *uc, int reg)
{
void *addr;
switch (reg)
{
case UNW_X86_EAX: addr = &uc->uc_mcontext.gregs[REG_EAX]; break;
case UNW_X86_EBX: addr = &uc->uc_mcontext.gregs[REG_EBX]; break;
case UNW_X86_ECX: addr = &uc->uc_mcontext.gregs[REG_ECX]; break;
case UNW_X86_EDX: addr = &uc->uc_mcontext.gregs[REG_EDX]; break;
case UNW_X86_ESI: addr = &uc->uc_mcontext.gregs[REG_ESI]; break;
case UNW_X86_EDI: addr = &uc->uc_mcontext.gregs[REG_EDI]; break;
case UNW_X86_EBP: addr = &uc->uc_mcontext.gregs[REG_EBP]; break;
case UNW_X86_EIP: addr = &uc->uc_mcontext.gregs[REG_EIP]; break;
case UNW_X86_ESP: addr = &uc->uc_mcontext.gregs[REG_ESP]; break;
default:
addr = NULL;
}
return addr;
}
# ifdef UNW_LOCAL_ONLY
void *
_Ux86_uc_addr (ucontext_t *uc, int reg)
{
return uc_addr (uc, reg);
}
# endif /* UNW_LOCAL_ONLY */
unw_dyn_info_list_t _U_dyn_info_list;
/* XXX fix me: there is currently no way to locate the dyn-info list
by a remote unwinder. On ia64, this is done via a special
unwind-table entry. Perhaps something similar can be done with
DWARF2 unwind info. */
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
/* it's a no-op */
}
static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
*dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
return 0;
}
static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
{
if (write)
{
debug (100, "%s: mem[%x] <- %x\n", __FUNCTION__, addr, *val);
*(unw_word_t *) addr = *val;
}
else
{
*val = *(unw_word_t *) addr;
debug (100, "%s: mem[%x] -> %x\n", __FUNCTION__, addr, *val);
}
return 0;
}
static int
access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
void *arg)
{
unw_word_t *addr;
ucontext_t *uc = arg;
#if 0
if (reg >= UNW_IA64_FR && reg < UNW_IA64_FR + 128)
goto badreg;
#endif
addr = uc_addr (uc, reg);
if (!addr)
goto badreg;
if (write)
{
*(unw_word_t *) addr = *val;
debug (100, "%s: %s <- %x\n", __FUNCTION__, unw_regname (reg), *val);
}
else
{
*val = *(unw_word_t *) addr;
debug (100, "%s: %s -> %x\n", __FUNCTION__, unw_regname (reg), *val);
}
return 0;
badreg:
debug (1, "%s: bad register number %u\n", __FUNCTION__, reg);
return -UNW_EBADREG;
}
static int
access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg)
{
#if 1
printf ("access_fpreg: screams to get implemented, doesn't it?\n");
return 0;
#else
ucontext_t *uc = arg;
unw_fpreg_t *addr;
if (reg < UNW_IA64_FR || reg >= UNW_IA64_FR + 128)
goto badreg;
addr = uc_addr (uc, reg);
if (!addr)
goto badreg;
if (write)
{
debug (100, "%s: %s <- %016lx.%016lx\n", __FUNCTION__,
unw_regname (reg), val->raw.bits[1], val->raw.bits[0]);
*(unw_fpreg_t *) addr = *val;
}
else
{
*val = *(unw_fpreg_t *) addr;
debug (100, "%s: %s -> %016lx.%016lx\n", __FUNCTION__,
unw_regname (reg), val->raw.bits[1], val->raw.bits[0]);
}
return 0;
badreg:
debug (1, "%s: bad register number %u\n", __FUNCTION__, reg);
/* attempt to access a non-preserved register */
return -UNW_EBADREG;
#endif
}
HIDDEN void
x86_local_addr_space_init (void)
{
memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL;
local_addr_space.acc.find_proc_info = UNW_ARCH_OBJ (find_proc_info);
local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
local_addr_space.acc.access_mem = access_mem;
local_addr_space.acc.access_reg = access_reg;
local_addr_space.acc.access_fpreg = access_fpreg;
local_addr_space.acc.resume = x86_local_resume;
}
#endif /* !UNW_REMOTE_ONLY */

View file

@ -0,0 +1,55 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
#include "init.h"
#ifdef UNW_REMOTE_ONLY
int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
{
return -UNW_EINVAL;
}
#else /* !UNW_REMOTE_ONLY */
int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
{
struct cursor *c = (struct cursor *) cursor;
if (hppa_needs_initialization)
{
hppa_needs_initialization = 0;
hppa_init ();
}
c->as = unw_local_addr_space;
c->as_arg = uc;
return common_init (c);
}
#endif /* !UNW_REMOTE_ONLY */

56
src/hppa/Gregs-hppa.c Normal file
View file

@ -0,0 +1,56 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
HIDDEN int
hppa_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
int write)
{
struct hppa_loc loc = HPPA_LOC (0, 0);
switch (reg)
{
case UNW_HPPA_IP:
if (write)
c->ip = *valp; /* also update the IP cache */
loc = c->ip_loc;
break;
case UNW_HPPA_SP:
if (write)
return -UNW_EREADONLYREG;
*valp = c->sp;
return 0;
default:
return -UNW_EBADREG;
}
if (write)
return hppa_put (c, loc, *valp);
else
return hppa_get (c, loc, valp);
}

141
src/hppa/Gstep-hppa.c Normal file
View file

@ -0,0 +1,141 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
static inline int
update_frame_state (struct cursor *c)
{
#if 0
unw_word_t prev_ip, prev_sp, prev_bsp, ip, pr, num_regs, cfm;
int ret;
prev_ip = c->ip;
prev_sp = c->sp;
prev_bsp = c->bsp;
c->cfm_loc = c->pfs_loc;
num_regs = 0;
if (c->is_signal_frame)
{
ret = ia64_get (c, c->sp + 0x10 + SIGFRAME_ARG2_OFF, &c->sigcontext_loc);
debug (100, "%s: sigcontext_loc=%lx (ret=%d)\n",
__FUNCTION__, c->sigcontext_loc, ret);
if (ret < 0)
return ret;
if (c->ip_loc == c->sigcontext_loc + SIGCONTEXT_BR_OFF + 0*8)
{
/* Earlier kernels (before 2.4.19 and 2.5.10) had buggy
unwind info for sigtramp. Fix it up here. */
c->ip_loc = (c->sigcontext_loc + SIGCONTEXT_IP_OFF);
c->cfm_loc = (c->sigcontext_loc + SIGCONTEXT_CFM_OFF);
}
/* do what can't be described by unwind directives: */
c->pfs_loc = (c->sigcontext_loc + SIGCONTEXT_AR_PFS_OFF);
ret = ia64_get (c, c->cfm_loc, &cfm);
if (ret < 0)
return ret;
num_regs = cfm & 0x7f; /* size of frame */
}
else
{
ret = ia64_get (c, c->cfm_loc, &cfm);
if (ret < 0)
return ret;
num_regs = (cfm >> 7) & 0x7f; /* size of locals */
}
c->bsp = ia64_rse_skip_regs (c->bsp, -num_regs);
/* update the IP cache: */
ret = ia64_get (c, c->ip_loc, &ip);
if (ret < 0)
return ret;
c->ip = ip;
if ((ip & 0xc) != 0)
{
/* don't let obviously bad addresses pollute the cache */
debug (1, "%s: rejecting bad ip=0x%lx\n", __FUNCTION__, (long) c->ip);
return -UNW_EINVALIDIP;
}
if (ip == 0)
/* end of frame-chain reached */
return 0;
pr = c->pr;
c->sp = c->psp;
c->is_signal_frame = 0;
if (c->ip == prev_ip && c->sp == prev_sp && c->bsp == prev_bsp)
{
dprintf ("%s: ip, sp, and bsp unchanged; stopping here (ip=0x%lx)\n",
__FUNCTION__, (long) ip);
return -UNW_EBADFRAME;
}
/* as we unwind, the saved ar.unat becomes the primary unat: */
c->pri_unat_loc = c->unat_loc;
/* restore the predicates: */
ret = ia64_get (c, c->pr_loc, &c->pr);
if (ret < 0)
return ret;
c->pi_valid = 0;
#endif
return 0;
}
int
unw_step (unw_cursor_t *cursor)
{
struct cursor *c = (struct cursor *) cursor;
int ret;
ret = hppa_get (c, c->sp_loc, &c->sp);
if (ret < 0)
return ret;
c->sp_loc = HPPA_LOC (c->sp, 0);
c->ip_loc = HPPA_LOC (c->sp + 4, 0);
c->sp += 8;
if (HPPA_GET_LOC (c->sp_loc))
{
ret = hppa_get (c, c->ip_loc, &c->ip);
if (ret < 0)
return ret;
}
else
c->ip = 0;
return (c->ip == 0) ? 0 : 1;
}

View file

@ -0,0 +1,4 @@
#ifndef UNW_REMOTE_ONLY
#define UNW_LOCAL_ONLY
#include "Gget_proc_info-hppa.c"
#endif

View file

@ -0,0 +1,4 @@
#ifndef UNW_REMOTE_ONLY
#define UNW_LOCAL_ONLY
#include "Gget_proc_name-hppa.c"
#endif

4
src/hppa/Lget_reg-hppa.c Normal file
View file

@ -0,0 +1,4 @@
#ifndef UNW_REMOTE_ONLY
#define UNW_LOCAL_ONLY
#include "Gget_reg-hppa.c"
#endif

4
src/hppa/Linit-hppa.c Normal file
View file

@ -0,0 +1,4 @@
#ifndef UNW_REMOTE_ONLY
#define UNW_LOCAL_ONLY
#include "Ginit-hppa.c"
#endif

View file

@ -0,0 +1,4 @@
#ifndef UNW_REMOTE_ONLY
#define UNW_LOCAL_ONLY
#include "Ginit_local-hppa.c"
#endif

4
src/hppa/Lregs-hppa.c Normal file
View file

@ -0,0 +1,4 @@
#ifndef UNW_REMOTE_ONLY
#define UNW_LOCAL_ONLY
#include "Gregs-hppa.c"
#endif

4
src/hppa/Lstep-hppa.c Normal file
View file

@ -0,0 +1,4 @@
#ifndef UNW_REMOTE_ONLY
#define UNW_LOCAL_ONLY
#include "Gstep-hppa.c"
#endif

View file

@ -0,0 +1,37 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "tdep.h"
void
unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi)
{
/* This lets us flush caches lazily. The implementation currently
ignores the flush range arguments (lo-hi). This is OK because
unw_flush_cache() is allowed to flush more than the requested
range. */
++as->cache_generation;
}

View file

@ -0,0 +1,37 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
unw_accessors_t *
unw_get_accessors (unw_addr_space_t as)
{
if (hppa_needs_initialization)
{
hppa_needs_initialization = 0;
hppa_init ();
}
return &as->acc;
}

18
src/hppa/global-hppa.c Normal file
View file

@ -0,0 +1,18 @@
#include "unwind_i.h"
HIDDEN int hppa_needs_initialization = 1;
#ifdef UNW_DEBUG
HIDDEN int tdep_debug_level;
#endif
HIDDEN void
hppa_init (void)
{
extern void _ULhppa_local_addr_space_init (void);
mi_init();
_Uhppa_local_addr_space_init ();
_ULhppa_local_addr_space_init ();
}

44
src/hppa/init.h Normal file
View file

@ -0,0 +1,44 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 "unwind_i.h"
static inline int
common_init (struct cursor *c)
{
int ret;
c->ip_loc = HPPA_REG_LOC (c, UNW_HPPA_IP);
c->sp_loc = HPPA_REG_LOC (c, UNW_HPPA_SP);
ret = hppa_get (c, c->ip_loc, &c->ip);
if (ret < 0)
return ret;
ret = hppa_get (c, HPPA_REG_LOC (c, UNW_HPPA_SP), &c->sp);
if (ret < 0)
return ret;
return 0;
}

43
src/hppa/tables-hppa.c Normal file
View file

@ -0,0 +1,43 @@
#include "unwind_i.h"
static inline int
is_local_addr_space (unw_addr_space_t as)
{
extern unw_addr_space_t _ULhppa_local_addr_space;
return (as == _Uhppa_local_addr_space
#ifndef UNW_REMOTE_ONLY
|| as == _ULhppa_local_addr_space
#endif
);
}
HIDDEN int
tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info, void *arg)
{
printf ("%s: begging to get implemented...\n", __FUNCTION__);
return 0;
}
HIDDEN int
tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di,
unw_proc_info_t *pi, int need_unwind_info, void *arg)
{
printf ("%s: the biggest beggar of them all...\n", __FUNCTION__);
return 0;
}
HIDDEN void
tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg)
{
if (!pi->unwind_info)
return;
if (!is_local_addr_space (as))
{
free (pi->unwind_info);
pi->unwind_info = NULL;
}
}

153
src/hppa/unwind_i.h Normal file
View file

@ -0,0 +1,153 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co
Contributed by ...
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 unwind_i_h
#define unwind_i_h
#include <memory.h>
#include <stdint.h>
#include <libunwind-hppa.h>
#include "config.h"
#include "internal.h"
#include "tdep.h"
#define HPPA_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY
# define HPPA_LOC(r, t) ((struct hppa_loc) { .val = (r) })
# define HPPA_REG_LOC(c,r) (HPPA_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
# define HPPA_FPREG_FLOC(c,r) (HPPA_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
static inline int
hppa_getfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t *val)
{
if (!HPPA_GET_LOC (loc))
return -1;
*val = *(unw_fpreg_t *) HPPA_GET_LOC (loc);
return 0;
}
static inline int
hppa_putfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t *val)
{
if (!HPPA_GET_LOC (loc))
return -1;
*(unw_fpreg_t *) HPPA_GET_LOC (loc) = *val;
return 0;
}
static inline int
hppa_get (struct cursor *c, struct hppa_loc loc, unw_word_t *val)
{
if (!HPPA_GET_LOC (loc))
return -1;
*val = *(unw_word_t *) HPPA_GET_LOC (loc);
return 0;
}
static inline int
hppa_put (struct cursor *c, struct hppa_loc loc, unw_word_t val)
{
if (!HPPA_GET_LOC (loc))
return -1;
*(unw_word_t *) HPPA_GET_LOC (loc) = val;
return 0;
}
#else /* !UNW_LOCAL_ONLY */
# define HPPA_LOC_TYPE_FP (1 << 0)
# define HPPA_LOC_TYPE_REG (1 << 1)
# define HPPA_LOC(r, t) ((struct hppa_loc) { .val = (r), .type = (t) })
# define HPPA_IS_REG_LOC(l) (((l).type & HPPA_LOC_TYPE_REG) != 0)
# define HPPA_IS_FP_LOC(l) (((l).type & HPPA_LOC_TYPE_FP) != 0)
# define HPPA_REG_LOC(c,r) HPPA_LOC((r), HPPA_LOC_TYPE_REG)
# define HPPA_FPREG_LOC(c,r) HPPA_LOC((r), (HPPA_LOC_TYPE_REG \
| HPPA_LOC_TYPE_FP))
static inline int
hppa_getfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t *val)
{
abort ();
}
static inline int
hppa_putfp (struct cursor *c, struct hppa_loc loc, unw_fpreg_t val)
{
abort ();
}
static inline int
hppa_get (struct cursor *c, struct hppa_loc loc, unw_word_t *val)
{
if (HPPA_IS_FP_LOC (loc))
abort ();
if (HPPA_IS_REG_LOC (loc))
return (*c->as->acc.access_reg)(c->as, HPPA_GET_LOC (loc), val, 0,
c->as_arg);
else
return (*c->as->acc.access_mem)(c->as, HPPA_GET_LOC (loc), val, 0,
c->as_arg);
}
static inline int
hppa_put (struct cursor *c, struct hppa_loc loc, unw_word_t val)
{
if (HPPA_IS_FP_LOC (loc))
abort ();
if (HPPA_IS_REG_LOC (loc))
return (*c->as->acc.access_reg)(c->as, HPPA_GET_LOC (loc), &val, 1,
c->as_arg);
else
return (*c->as->acc.access_mem)(c->as, HPPA_GET_LOC (loc), &val, 1,
c->as_arg);
}
#endif /* !UNW_LOCAL_ONLY */
#define hppa_needs_initialization UNW_ARCH_OBJ(needs_initialization)
#define hppa_init UNW_ARCH_OBJ(init)
#define hppa_access_reg UNW_OBJ(access_reg)
#define hppa_access_fpreg UNW_OBJ(access_fpreg)
#define hppa_local_resume UNW_OBJ(local_resume)
#define hppa_local_addr_space_init UNW_OBJ(local_addr_space_init)
extern int hppa_needs_initialization;
extern void hppa_init (void);
extern int hppa_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
extern int hppa_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
extern void hppa_local_addr_space_init (void);
extern int hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
void *arg);
#endif /* unwind_i_h */