1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-25 08:37:38 +01:00

(Logical change 1.32)

This commit is contained in:
mostang.com!davidm 2002-12-19 07:16:50 +00:00
parent 68f77774e6
commit a85267d16b
34 changed files with 1535 additions and 0 deletions

80
include/libunwind-x86.h Normal file
View file

@ -0,0 +1,80 @@
/* 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. */
#ifndef LIBUNWIND_H
#define LIBUNWIND_H
#include <stdint.h>
#include <ucontext.h>
#define UNW_TARGET x86
#define UNW_TARGET_X86 1
typedef uint32_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_X86_EAX,
UNW_X86_EBX,
UNW_X86_ECX,
UNW_X86_EDX,
UNW_X86_ESI,
UNW_X86_EDI,
UNW_X86_EBP,
UNW_X86_EIP,
UNW_X86_ESP,
UNW_TDEP_LAST_REG = UNW_X86_ESP,
UNW_TDEP_IP = UNW_X86_EIP,
UNW_TDEP_SP = UNW_X86_ESP
}
x86_regnum_t;
typedef struct unw_tdep_save_loc
{
/* Additional target-dependent info on a save location. */
}
unw_tdep_save_loc_t;
/* On x86, 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_X86_FR) < 128)
#include "libunwind-common.h"
#endif /* LIBUNWIND_H */

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

@ -0,0 +1,90 @@
/* 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. */
#ifndef TDEP_X86_H
#define TDEP_X86_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 x86_pregnum
{
X86_NUM_PREGS
};
struct x86_loc
{
unw_word_t val;
#ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see X86_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 eip;
unw_word_t esp;
struct x86_loc eip_loc;
struct x86_loc ebp_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_X86_H */

8
scripts/make-L-files Normal file
View file

@ -0,0 +1,8 @@
#!/bin/sh
set -x
for gname in G*.c; do
lname="L$(expr $gname : '.\(.*\)')"
bk edit $lname >/dev/null 2>&1
echo -e "#ifndef UNW_REMOTE_ONLY\n#define UNW_LOCAL_ONLY\n\
#include \"$gname\"\n#endif" > $lname
done

157
src/ia64/global-ia64.c Normal file
View file

@ -0,0 +1,157 @@
#include "unwind_i.h"
struct ia64_global_unwind_state unw =
{
needs_initialization: 1,
save_order: {
IA64_REG_RP, IA64_REG_PFS, IA64_REG_PSP, IA64_REG_PR,
IA64_REG_UNAT, IA64_REG_LC, IA64_REG_FPSR, IA64_REG_PRI_UNAT_GR
},
preg_index: {
struct_offset (struct cursor, pri_unat_loc)/8, /* PRI_UNAT_GR */
struct_offset (struct cursor, pri_unat_loc)/8, /* PRI_UNAT_MEM */
struct_offset (struct cursor, bsp_loc)/8,
struct_offset (struct cursor, bspstore_loc)/8,
struct_offset (struct cursor, pfs_loc)/8,
struct_offset (struct cursor, rnat_loc)/8,
struct_offset (struct cursor, psp)/8,
struct_offset (struct cursor, ip_loc)/8,
struct_offset (struct cursor, r4_loc)/8,
struct_offset (struct cursor, r5_loc)/8,
struct_offset (struct cursor, r6_loc)/8,
struct_offset (struct cursor, r7_loc)/8,
struct_offset (struct cursor, nat4_loc)/8,
struct_offset (struct cursor, nat5_loc)/8,
struct_offset (struct cursor, nat6_loc)/8,
struct_offset (struct cursor, nat7_loc)/8,
struct_offset (struct cursor, unat_loc)/8,
struct_offset (struct cursor, pr_loc)/8,
struct_offset (struct cursor, lc_loc)/8,
struct_offset (struct cursor, fpsr_loc)/8,
struct_offset (struct cursor, b1_loc)/8,
struct_offset (struct cursor, b2_loc)/8,
struct_offset (struct cursor, b3_loc)/8,
struct_offset (struct cursor, b4_loc)/8,
struct_offset (struct cursor, b5_loc)/8,
struct_offset (struct cursor, f2_loc)/8,
struct_offset (struct cursor, f3_loc)/8,
struct_offset (struct cursor, f4_loc)/8,
struct_offset (struct cursor, f5_loc)/8,
struct_offset (struct cursor, fr_loc[16 - 16])/8,
struct_offset (struct cursor, fr_loc[17 - 16])/8,
struct_offset (struct cursor, fr_loc[18 - 16])/8,
struct_offset (struct cursor, fr_loc[19 - 16])/8,
struct_offset (struct cursor, fr_loc[20 - 16])/8,
struct_offset (struct cursor, fr_loc[21 - 16])/8,
struct_offset (struct cursor, fr_loc[22 - 16])/8,
struct_offset (struct cursor, fr_loc[23 - 16])/8,
struct_offset (struct cursor, fr_loc[24 - 16])/8,
struct_offset (struct cursor, fr_loc[25 - 16])/8,
struct_offset (struct cursor, fr_loc[26 - 16])/8,
struct_offset (struct cursor, fr_loc[27 - 16])/8,
struct_offset (struct cursor, fr_loc[28 - 16])/8,
struct_offset (struct cursor, fr_loc[29 - 16])/8,
struct_offset (struct cursor, fr_loc[30 - 16])/8,
struct_offset (struct cursor, fr_loc[31 - 16])/8,
},
#if UNW_DEBUG
debug_level: 0,
preg_name: {
"pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat",
"psp", "rp",
"r4", "r5", "r6", "r7",
"ar.unat", "pr", "ar.lc", "ar.fpsr",
"b1", "b2", "b3", "b4", "b5",
"f2", "f3", "f4", "f5",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
}
#endif
};
#ifndef UNW_REMOTE_ONLY
/* Note: It might be tempting to use the LSDA to store
_U_dyn_info_list, but that wouldn't work because the
unwind-info is generally mapped read-only. */
unw_dyn_info_list_t _U_dyn_info_list;
/* Now create a special unwind-table entry which makes it easy for an
unwinder to locate the dynamic registration list. The special
entry covers address range [0-0) and is therefore guaranteed to
be the first in the unwind-table. */
asm (
" .section \".IA_64.unwind_info\", \"a\"\n"
".info: data8 (1<<48) | 1\n" /* v1, length==1 (8-byte word) */
" data8 0\n" /* 8 empty .prologue directives (nops) */
" data8 0\n" /* personality routine (ignored) */
" string \"dyn-list\"\n" /* lsda */
" data8 @segrel(_U_dyn_info_list)\n"
" .previous\n"
" .section \".IA_64.unwind\", \"a\"\n"
" data8 0, 0, @segrel(.info)\n"
" .previous\n");
#endif
HIDDEN void
ia64_init (void)
{
extern void unw_hash_index_t_is_too_narrow (void);
extern void _ULia64_local_addr_space_init (void);
uint8_t f1_bytes[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t nat_val_bytes[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t int_val_bytes[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t *lep, *bep;
long i;
mi_init ();
mempool_init (&unw.state_record_pool, sizeof (struct ia64_state_record), 0);
mempool_init (&unw.labeled_state_pool,
sizeof (struct ia64_labeled_state), 0);
unw.f0.raw.bits[0] = 0;
unw.f0.raw.bits[1] = 0;
lep = (uint8_t *) &unw.f1_le + 16;
bep = (uint8_t *) &unw.f1_be;
for (i = 0; i < 16; ++i)
{
*--lep = f1_bytes[i];
*bep++ = f1_bytes[i];
}
lep = (uint8_t *) &unw.nat_val_le + 16;
bep = (uint8_t *) &unw.nat_val_be;
for (i = 0; i < 16; ++i)
{
*--lep = nat_val_bytes[i];
*bep++ = nat_val_bytes[i];
}
lep = (uint8_t *) &unw.int_val_le + 16;
bep = (uint8_t *) &unw.int_val_be;
for (i = 0; i < 16; ++i)
{
*--lep = int_val_bytes[i];
*bep++ = int_val_bytes[i];
}
if (8*sizeof(unw_hash_index_t) < IA64_LOG_UNW_HASH_SIZE)
unw_hash_index_t_is_too_narrow ();
_Uia64_local_addr_space_init ();
_ULia64_local_addr_space_init ();
}

44
src/mi-init.c Normal file
View file

@ -0,0 +1,44 @@
/* 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 "internal.h"
HIDDEN void
mi_init (void)
{
extern void unw_cursor_t_is_too_small (void);
#if UNW_DEBUG
const char *str = getenv ("UNW_DEBUG_LEVEL");
if (str)
tdep_debug_level = atoi (str);
#endif
if (sizeof (struct cursor) > sizeof (unw_cursor_t))
unw_cursor_t_is_too_small ();
}

View file

@ -0,0 +1,42 @@
/* 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 "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) 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 "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->eip, c->as == unw_local_addr_space,
buf, buf_len, c->as_arg);
}

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

@ -0,0 +1,34 @@
/* 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 "unwind_i.h"
int
unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp)
{
struct cursor *c = (struct cursor *) cursor;
return x86_access_reg (c, regnum, valp, 0);
}

199
src/x86/Ginit-x86.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 */

55
src/x86/Ginit_local-x86.c Normal file
View file

@ -0,0 +1,55 @@
/* 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 "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 (x86_needs_initialization)
{
x86_needs_initialization = 0;
x86_init ();
}
c->as = unw_local_addr_space;
c->as_arg = uc;
return common_init (c);
}
#endif /* !UNW_REMOTE_ONLY */

View file

@ -0,0 +1,33 @@
/* 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 "unwind_i.h"
int
unw_is_signal_frame (unw_cursor_t *cursor)
{
printf ("%s: implement me\n", __FUNCTION__);
return 0;
}

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

@ -0,0 +1,56 @@
/* 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 "unwind_i.h"
HIDDEN int
x86_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
int write)
{
struct x86_loc loc = X86_LOC (0, 0);
switch (reg)
{
case UNW_X86_EIP:
if (write)
c->eip = *valp; /* also update the EIP cache */
loc = c->eip_loc;
break;
case UNW_X86_ESP:
if (write)
return -UNW_EREADONLYREG;
*valp = c->esp;
return 0;
default:
return -UNW_EBADREG;
}
if (write)
return x86_put (c, loc, *valp);
else
return x86_get (c, loc, valp);
}

132
src/x86/Gresume-x86.c Normal file
View file

@ -0,0 +1,132 @@
/* 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 "unwind_i.h"
#ifndef UNW_REMOTE_ONLY
HIDDEN inline int
x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
{
#if 1
printf ("%s: implement me\n", __FUNCTION__);
return -UNW_EINVAL;
#else
struct cursor *c = (struct cursor *) cursor;
unw_fpreg_t fpval;
ucontext_t *uc = arg;
unw_word_t val, sol;
int i, ret;
# define SET_NAT(n) \
do \
{ \
ret = x86_access_reg (c, UNW_X86_NAT + (n), &val, 0); \
if (ret < 0) \
return ret; \
if (val) \
uc->uc_mcontext.sc_nat |= (unw_word_t) 1 << n; \
} \
while (0)
# define SET_REG(f, r) \
do \
{ \
ret = x86_get (c, c->r, &val); \
if (ret < 0) \
return ret; \
uc->uc_mcontext.f = val; \
} \
while (0)
# define SET_FPREG(f, r) \
do \
{ \
ret = x86_getfp (c, c->r, &fpval); \
if (ret < 0) \
return ret; \
uc->uc_mcontext.f.u.bits[0] = fpval.raw.bits[0]; \
uc->uc_mcontext.f.u.bits[1] = fpval.raw.bits[1]; \
} \
while (0)
/* ensure c->pi is up-to-date: */
if ((ret = x86_make_proc_info (c)) < 0)
return ret;
SET_REG (sc_ar_pfs, pfs_loc);
SET_REG (sc_br[0], ip_loc);
SET_REG (sc_pr, pr_loc);
SET_REG (sc_ar_rnat, rnat_loc);
SET_REG (sc_ar_lc, lc_loc);
SET_REG (sc_ar_fpsr, fpsr_loc);
SET_REG (sc_gr[4], r4_loc); SET_REG(sc_gr[5], r5_loc);
SET_REG (sc_gr[6], r6_loc); SET_REG(sc_gr[7], r7_loc);
uc->uc_mcontext.sc_nat = 0;
SET_NAT (4); SET_NAT(5);
SET_NAT (6); SET_NAT(7);
SET_REG (sc_br[1], b1_loc);
SET_REG (sc_br[2], b2_loc);
SET_REG (sc_br[3], b3_loc);
SET_REG (sc_br[4], b4_loc);
SET_REG (sc_br[5], b5_loc);
SET_FPREG (sc_fr[2], f2_loc);
SET_FPREG (sc_fr[3], f3_loc);
SET_FPREG (sc_fr[4], f4_loc);
SET_FPREG (sc_fr[5], f5_loc);
for (i = 16; i < 32; ++i)
SET_FPREG (sc_fr[i], fr_loc[i - 16]);
if (c->is_signal_frame)
abort (); /* XXX this needs to be fixed... */
/* Account for the fact that __x86_install_context() returns via
br.ret, which will decrement bsp by size-of-locals. */
sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f;
uc->uc_mcontext.sc_ar_bsp = x86_rse_skip_regs (c->bsp, sol);
uc->uc_mcontext.sc_flags = 0;
uc->uc_mcontext.sc_gr[1] = c->pi.gp;
uc->uc_mcontext.sc_gr[12] = c->psp;
__x86_install_context (uc, c->eh_args[0], c->eh_args[1], c->eh_args[2],
c->eh_args[3]);
#endif
}
#endif /* !UNW_REMOTE_ONLY */
int
unw_resume (unw_cursor_t *cursor)
{
struct cursor *c = (struct cursor *) cursor;
#ifdef UNW_LOCAL_ONLY
return x86_local_resume (c->as, cursor, c->as_arg);
#else
return (*c->as->acc.resume) (c->as, cursor, c->as_arg);
#endif
}

34
src/x86/Gset_reg-x86.c Normal file
View file

@ -0,0 +1,34 @@
/* 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 "unwind_i.h"
int
unw_set_reg (unw_cursor_t *cursor, int regnum, unw_word_t valp)
{
struct cursor *c = (struct cursor *) cursor;
return x86_access_reg (c, regnum, &valp, 1);
}

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

@ -0,0 +1,141 @@
/* 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 "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 = x86_get (c, c->ebp_loc, &c->esp);
if (ret < 0)
return ret;
c->ebp_loc = X86_LOC (c->esp, 0);
c->eip_loc = X86_LOC (c->esp + 4, 0);
c->esp += 8;
if (X86_GET_LOC (c->ebp_loc))
{
ret = x86_get (c, c->eip_loc, &c->eip);
if (ret < 0)
return ret;
}
else
c->eip = 0;
return (c->eip == 0) ? 0 : 1;
}

View file

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

View file

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

View file

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

View file

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

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

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

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

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

View file

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

View file

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

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

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

4
src/x86/Lresume-x86.c Normal file
View file

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

4
src/x86/Lset_reg-x86.c Normal file
View file

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

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

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

37
src/x86/flush_cache-x86.c Normal file
View file

@ -0,0 +1,37 @@
/* 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 "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) 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 "unwind_i.h"
unw_accessors_t *
unw_get_accessors (unw_addr_space_t as)
{
if (x86_needs_initialization)
{
x86_needs_initialization = 0;
x86_init ();
}
return &as->acc;
}

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

@ -0,0 +1,18 @@
#include "unwind_i.h"
HIDDEN int x86_needs_initialization = 1;
#ifdef UNW_DEBUG
HIDDEN int tdep_debug_level;
#endif
HIDDEN void
x86_init (void)
{
extern void _ULx86_local_addr_space_init (void);
mi_init();
_Ux86_local_addr_space_init ();
_ULx86_local_addr_space_init ();
}

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

@ -0,0 +1,44 @@
/* 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 "unwind_i.h"
static inline int
common_init (struct cursor *c)
{
int ret;
c->eip_loc = X86_REG_LOC (c, UNW_X86_EIP);
c->ebp_loc = X86_REG_LOC (c, UNW_X86_EBP);
ret = x86_get (c, c->eip_loc, &c->eip);
if (ret < 0)
return ret;
ret = x86_get (c, X86_REG_LOC (c, UNW_X86_ESP), &c->esp);
if (ret < 0)
return ret;
return 0;
}

15
src/x86/regname-x86.c Normal file
View file

@ -0,0 +1,15 @@
#include "unwind_i.h"
static const char *regname[] =
{
"eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "eip", "esp"
};
const char *
unw_regname (unw_regnum_t reg)
{
if (reg < sizeof (regname) / sizeof (regname[0]))
return regname[reg];
else
return "???";
}

43
src/x86/tables-x86.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 _ULx86_local_addr_space;
return (as == _Ux86_local_addr_space
#ifndef UNW_REMOTE_ONLY
|| as == _ULx86_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/x86/unwind_i.h Normal file
View file

@ -0,0 +1,153 @@
/* 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. */
#ifndef unwind_i_h
#define unwind_i_h
#include <memory.h>
#include <stdint.h>
#include <libunwind-x86.h>
#include "config.h"
#include "internal.h"
#include "tdep.h"
#define X86_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY
# define X86_LOC(r, t) ((struct x86_loc) { .val = (r) })
# define X86_REG_LOC(c,r) (X86_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
# define X86_FPREG_FLOC(c,r) (X86_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
static inline int
x86_getfp (struct cursor *c, struct x86_loc loc, unw_fpreg_t *val)
{
if (!X86_GET_LOC (loc))
return -1;
*val = *(unw_fpreg_t *) X86_GET_LOC (loc);
return 0;
}
static inline int
x86_putfp (struct cursor *c, struct x86_loc loc, unw_fpreg_t *val)
{
if (!X86_GET_LOC (loc))
return -1;
*(unw_fpreg_t *) X86_GET_LOC (loc) = *val;
return 0;
}
static inline int
x86_get (struct cursor *c, struct x86_loc loc, unw_word_t *val)
{
if (!X86_GET_LOC (loc))
return -1;
*val = *(unw_word_t *) X86_GET_LOC (loc);
return 0;
}
static inline int
x86_put (struct cursor *c, struct x86_loc loc, unw_word_t val)
{
if (!X86_GET_LOC (loc))
return -1;
*(unw_word_t *) X86_GET_LOC (loc) = val;
return 0;
}
#else /* !UNW_LOCAL_ONLY */
# define X86_LOC_TYPE_FP (1 << 0)
# define X86_LOC_TYPE_REG (1 << 1)
# define X86_LOC(r, t) ((struct x86_loc) { .val = (r), .type = (t) })
# define X86_IS_REG_LOC(l) (((l).type & X86_LOC_TYPE_REG) != 0)
# define X86_IS_FP_LOC(l) (((l).type & X86_LOC_TYPE_FP) != 0)
# define X86_REG_LOC(c,r) X86_LOC((r), X86_LOC_TYPE_REG)
# define X86_FPREG_LOC(c,r) X86_LOC((r), (X86_LOC_TYPE_REG \
| X86_LOC_TYPE_FP))
static inline int
x86_getfp (struct cursor *c, struct x86_loc loc, unw_fpreg_t *val)
{
abort ();
}
static inline int
x86_putfp (struct cursor *c, struct x86_loc loc, unw_fpreg_t val)
{
abort ();
}
static inline int
x86_get (struct cursor *c, struct x86_loc loc, unw_word_t *val)
{
if (X86_IS_FP_LOC (loc))
abort ();
if (X86_IS_REG_LOC (loc))
return (*c->as->acc.access_reg)(c->as, X86_GET_LOC (loc), val, 0,
c->as_arg);
else
return (*c->as->acc.access_mem)(c->as, X86_GET_LOC (loc), val, 0,
c->as_arg);
}
static inline int
x86_put (struct cursor *c, struct x86_loc loc, unw_word_t val)
{
if (X86_IS_FP_LOC (loc))
abort ();
if (X86_IS_REG_LOC (loc))
return (*c->as->acc.access_reg)(c->as, X86_GET_LOC (loc), &val, 1,
c->as_arg);
else
return (*c->as->acc.access_mem)(c->as, X86_GET_LOC (loc), &val, 1,
c->as_arg);
}
#endif /* !UNW_LOCAL_ONLY */
#define x86_needs_initialization UNW_ARCH_OBJ(needs_initialization)
#define x86_init UNW_ARCH_OBJ(init)
#define x86_access_reg UNW_OBJ(access_reg)
#define x86_access_fpreg UNW_OBJ(access_fpreg)
#define x86_local_resume UNW_OBJ(local_resume)
#define x86_local_addr_space_init UNW_OBJ(local_addr_space_init)
extern int x86_needs_initialization;
extern void x86_init (void);
extern int x86_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
extern int x86_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
extern void x86_local_addr_space_init (void);
extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
void *arg);
#endif /* unwind_i_h */