1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-21 23:27:39 +01:00

One time whitespace fixup.

for f in $(find src include -name '*.[ch]'); do
  expand -t 8 $f > $tmp; mv $tmp $f;
done
This commit is contained in:
Arun Sharma 2014-09-20 09:03:10 -07:00
parent 06e608d043
commit 781d5d5263
275 changed files with 7649 additions and 7649 deletions

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2001-2005 Hewlett-Packard Co Copyright (C) 2001-2005 Hewlett-Packard Co
Copyright (C) 2007 David Mosberger-Tang Copyright (C) 2007 David Mosberger-Tang
Contributed by David Mosberger-Tang <dmosberger@gmail.com> Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind. This file is part of libunwind.
@ -31,28 +31,28 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define COMPILER_H #define COMPILER_H
#ifdef __GNUC__ #ifdef __GNUC__
# define ALIGNED(x) __attribute__((aligned(x))) # define ALIGNED(x) __attribute__((aligned(x)))
# define CONST_ATTR __attribute__((__const__)) # define CONST_ATTR __attribute__((__const__))
# define UNUSED __attribute__((unused)) # define UNUSED __attribute__((unused))
# define NOINLINE __attribute__((noinline)) # define NOINLINE __attribute__((noinline))
# define NORETURN __attribute__((noreturn)) # define NORETURN __attribute__((noreturn))
# define ALIAS(name) __attribute__((alias (#name))) # define ALIAS(name) __attribute__((alias (#name)))
# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) # if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
# define ALWAYS_INLINE inline __attribute__((always_inline)) # define ALWAYS_INLINE inline __attribute__((always_inline))
# define HIDDEN __attribute__((visibility ("hidden"))) # define HIDDEN __attribute__((visibility ("hidden")))
# define PROTECTED __attribute__((visibility ("protected"))) # define PROTECTED __attribute__((visibility ("protected")))
# else # else
# define ALWAYS_INLINE # define ALWAYS_INLINE
# define HIDDEN # define HIDDEN
# define PROTECTED # define PROTECTED
# endif # endif
# define WEAK __attribute__((weak)) # define WEAK __attribute__((weak))
# if (__GNUC__ >= 3) # if (__GNUC__ >= 3)
# define likely(x) __builtin_expect ((x), 1) # define likely(x) __builtin_expect ((x), 1)
# define unlikely(x) __builtin_expect ((x), 0) # define unlikely(x) __builtin_expect ((x), 0)
# else # else
# define likely(x) (x) # define likely(x) (x)
# define unlikely(x) (x) # define unlikely(x) (x)
# endif # endif
#else #else
# define ALIGNED(x) # define ALIGNED(x)
@ -65,10 +65,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
# define HIDDEN # define HIDDEN
# define PROTECTED # define PROTECTED
# define WEAK # define WEAK
# define likely(x) (x) # define likely(x) (x)
# define unlikely(x) (x) # define unlikely(x) (x)
#endif #endif
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
#endif /* COMPILER_H */ #endif /* COMPILER_H */

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003 Hewlett-Packard Development Company, L.P. Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -58,9 +58,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
string: string:
'z': The operand for this character is a uleb128 value that gives the 'z': The operand for this character is a uleb128 value that gives the
length of the CIE augmentation body, not counting the length length of the CIE augmentation body, not counting the length
of the uleb128 operand itself. If present, this code must of the uleb128 operand itself. If present, this code must
appear as the first character in the augmentation body. appear as the first character in the augmentation body.
'L': Indicates that the FDE's augmentation body contains an LSDA 'L': Indicates that the FDE's augmentation body contains an LSDA
pointer. The operand for this character is a single byte pointer. The operand for this character is a single byte
@ -73,13 +73,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
operand for this character is a single byte that specifies operand for this character is a single byte that specifies
the pointer-encoding (PE) that is used for the the pointer-encoding (PE) that is used for the
code-pointers. Note: the "address_range" member is always code-pointers. Note: the "address_range" member is always
encoded as an absolute value. Apart from that, the specified encoded as an absolute value. Apart from that, the specified
FDE pointer-encoding applies. FDE pointer-encoding applies.
'P': Indicates the presence of a personality routine (handler). 'P': Indicates the presence of a personality routine (handler).
The first operand for this character specifies the The first operand for this character specifies the
pointer-encoding (PE) that is used for the second operand, pointer-encoding (PE) that is used for the second operand,
which specifies the address of the personality routine. which specifies the address of the personality routine.
If the augmentation string contains any other characters, the If the augmentation string contains any other characters, the
remainder of the augmentation string should be ignored. remainder of the augmentation string should be ignored.
@ -104,7 +104,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
*/ */
#define DW_EH_VERSION 1 /* The version we're implementing */ #define DW_EH_VERSION 1 /* The version we're implementing */
struct dwarf_eh_frame_hdr struct dwarf_eh_frame_hdr
{ {
@ -115,14 +115,14 @@ struct dwarf_eh_frame_hdr
/* The rest of the header is variable-length and consists of the /* The rest of the header is variable-length and consists of the
following members: following members:
encoded_t eh_frame_ptr; encoded_t eh_frame_ptr;
encoded_t fde_count; encoded_t fde_count;
struct struct
{ {
encoded_t start_ip; // first address covered by this FDE encoded_t start_ip; // first address covered by this FDE
encoded_t fde_addr; // address of the FDE encoded_t fde_addr; // address of the FDE
} }
binary_search_table[fde_count]; */ binary_search_table[fde_count]; */
}; };
#endif /* dwarf_eh_h */ #endif /* dwarf_eh_h */

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -28,7 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <libunwind.h> #include <libunwind.h>
struct dwarf_cursor; /* forward-declaration */ struct dwarf_cursor; /* forward-declaration */
struct elf_dyn_info; struct elf_dyn_info;
#include "dwarf-config.h" #include "dwarf-config.h"
@ -53,49 +53,49 @@ struct elf_dyn_info;
typedef enum typedef enum
{ {
DW_OP_addr = 0x03, DW_OP_addr = 0x03,
DW_OP_deref = 0x06, DW_OP_deref = 0x06,
DW_OP_const1u = 0x08, DW_OP_const1u = 0x08,
DW_OP_const1s = 0x09, DW_OP_const1s = 0x09,
DW_OP_const2u = 0x0a, DW_OP_const2u = 0x0a,
DW_OP_const2s = 0x0b, DW_OP_const2s = 0x0b,
DW_OP_const4u = 0x0c, DW_OP_const4u = 0x0c,
DW_OP_const4s = 0x0d, DW_OP_const4s = 0x0d,
DW_OP_const8u = 0x0e, DW_OP_const8u = 0x0e,
DW_OP_const8s = 0x0f, DW_OP_const8s = 0x0f,
DW_OP_constu = 0x10, DW_OP_constu = 0x10,
DW_OP_consts = 0x11, DW_OP_consts = 0x11,
DW_OP_dup = 0x12, DW_OP_dup = 0x12,
DW_OP_drop = 0x13, DW_OP_drop = 0x13,
DW_OP_over = 0x14, DW_OP_over = 0x14,
DW_OP_pick = 0x15, DW_OP_pick = 0x15,
DW_OP_swap = 0x16, DW_OP_swap = 0x16,
DW_OP_rot = 0x17, DW_OP_rot = 0x17,
DW_OP_xderef = 0x18, DW_OP_xderef = 0x18,
DW_OP_abs = 0x19, DW_OP_abs = 0x19,
DW_OP_and = 0x1a, DW_OP_and = 0x1a,
DW_OP_div = 0x1b, DW_OP_div = 0x1b,
DW_OP_minus = 0x1c, DW_OP_minus = 0x1c,
DW_OP_mod = 0x1d, DW_OP_mod = 0x1d,
DW_OP_mul = 0x1e, DW_OP_mul = 0x1e,
DW_OP_neg = 0x1f, DW_OP_neg = 0x1f,
DW_OP_not = 0x20, DW_OP_not = 0x20,
DW_OP_or = 0x21, DW_OP_or = 0x21,
DW_OP_plus = 0x22, DW_OP_plus = 0x22,
DW_OP_plus_uconst = 0x23, DW_OP_plus_uconst = 0x23,
DW_OP_shl = 0x24, DW_OP_shl = 0x24,
DW_OP_shr = 0x25, DW_OP_shr = 0x25,
DW_OP_shra = 0x26, DW_OP_shra = 0x26,
DW_OP_xor = 0x27, DW_OP_xor = 0x27,
DW_OP_skip = 0x2f, DW_OP_skip = 0x2f,
DW_OP_bra = 0x28, DW_OP_bra = 0x28,
DW_OP_eq = 0x29, DW_OP_eq = 0x29,
DW_OP_ge = 0x2a, DW_OP_ge = 0x2a,
DW_OP_gt = 0x2b, DW_OP_gt = 0x2b,
DW_OP_le = 0x2c, DW_OP_le = 0x2c,
DW_OP_lt = 0x2d, DW_OP_lt = 0x2d,
DW_OP_ne = 0x2e, DW_OP_ne = 0x2e,
DW_OP_lit0 = 0x30, DW_OP_lit0 = 0x30,
DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, DW_OP_lit5, DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, DW_OP_lit5,
DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, DW_OP_lit9, DW_OP_lit10, DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, DW_OP_lit9, DW_OP_lit10,
DW_OP_lit11, DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15, DW_OP_lit11, DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15,
@ -103,7 +103,7 @@ typedef enum
DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, DW_OP_lit25, DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, DW_OP_lit25,
DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, DW_OP_lit29, DW_OP_lit30, DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, DW_OP_lit29, DW_OP_lit30,
DW_OP_lit31, DW_OP_lit31,
DW_OP_reg0 = 0x50, DW_OP_reg0 = 0x50,
DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, DW_OP_reg5, DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, DW_OP_reg5,
DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, DW_OP_reg9, DW_OP_reg10, DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, DW_OP_reg9, DW_OP_reg10,
DW_OP_reg11, DW_OP_reg12, DW_OP_reg13, DW_OP_reg14, DW_OP_reg15, DW_OP_reg11, DW_OP_reg12, DW_OP_reg13, DW_OP_reg14, DW_OP_reg15,
@ -111,7 +111,7 @@ typedef enum
DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, DW_OP_reg25, DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, DW_OP_reg25,
DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, DW_OP_reg29, DW_OP_reg30, DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, DW_OP_reg29, DW_OP_reg30,
DW_OP_reg31, DW_OP_reg31,
DW_OP_breg0 = 0x70, DW_OP_breg0 = 0x70,
DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5, DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5,
DW_OP_breg6, DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10, DW_OP_breg6, DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10,
DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, DW_OP_breg14, DW_OP_breg15, DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, DW_OP_breg14, DW_OP_breg15,
@ -119,59 +119,59 @@ typedef enum
DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25, DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25,
DW_OP_breg26, DW_OP_breg27, DW_OP_breg28, DW_OP_breg29, DW_OP_breg30, DW_OP_breg26, DW_OP_breg27, DW_OP_breg28, DW_OP_breg29, DW_OP_breg30,
DW_OP_breg31, DW_OP_breg31,
DW_OP_regx = 0x90, DW_OP_regx = 0x90,
DW_OP_fbreg = 0x91, DW_OP_fbreg = 0x91,
DW_OP_bregx = 0x92, DW_OP_bregx = 0x92,
DW_OP_piece = 0x93, DW_OP_piece = 0x93,
DW_OP_deref_size = 0x94, DW_OP_deref_size = 0x94,
DW_OP_xderef_size = 0x95, DW_OP_xderef_size = 0x95,
DW_OP_nop = 0x96, DW_OP_nop = 0x96,
DW_OP_push_object_address = 0x97, DW_OP_push_object_address = 0x97,
DW_OP_call2 = 0x98, DW_OP_call2 = 0x98,
DW_OP_call4 = 0x99, DW_OP_call4 = 0x99,
DW_OP_call_ref = 0x9a, DW_OP_call_ref = 0x9a,
DW_OP_lo_user = 0xe0, DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff DW_OP_hi_user = 0xff
} }
dwarf_expr_op_t; dwarf_expr_op_t;
#define DWARF_CIE_VERSION 3 /* GCC emits version 1??? */ #define DWARF_CIE_VERSION 3 /* GCC emits version 1??? */
#define DWARF_CFA_OPCODE_MASK 0xc0 #define DWARF_CFA_OPCODE_MASK 0xc0
#define DWARF_CFA_OPERAND_MASK 0x3f #define DWARF_CFA_OPERAND_MASK 0x3f
typedef enum typedef enum
{ {
DW_CFA_advance_loc = 0x40, DW_CFA_advance_loc = 0x40,
DW_CFA_offset = 0x80, DW_CFA_offset = 0x80,
DW_CFA_restore = 0xc0, DW_CFA_restore = 0xc0,
DW_CFA_nop = 0x00, DW_CFA_nop = 0x00,
DW_CFA_set_loc = 0x01, DW_CFA_set_loc = 0x01,
DW_CFA_advance_loc1 = 0x02, DW_CFA_advance_loc1 = 0x02,
DW_CFA_advance_loc2 = 0x03, DW_CFA_advance_loc2 = 0x03,
DW_CFA_advance_loc4 = 0x04, DW_CFA_advance_loc4 = 0x04,
DW_CFA_offset_extended = 0x05, DW_CFA_offset_extended = 0x05,
DW_CFA_restore_extended = 0x06, DW_CFA_restore_extended = 0x06,
DW_CFA_undefined = 0x07, DW_CFA_undefined = 0x07,
DW_CFA_same_value = 0x08, DW_CFA_same_value = 0x08,
DW_CFA_register = 0x09, DW_CFA_register = 0x09,
DW_CFA_remember_state = 0x0a, DW_CFA_remember_state = 0x0a,
DW_CFA_restore_state = 0x0b, DW_CFA_restore_state = 0x0b,
DW_CFA_def_cfa = 0x0c, DW_CFA_def_cfa = 0x0c,
DW_CFA_def_cfa_register = 0x0d, DW_CFA_def_cfa_register = 0x0d,
DW_CFA_def_cfa_offset = 0x0e, DW_CFA_def_cfa_offset = 0x0e,
DW_CFA_def_cfa_expression = 0x0f, DW_CFA_def_cfa_expression = 0x0f,
DW_CFA_expression = 0x10, DW_CFA_expression = 0x10,
DW_CFA_offset_extended_sf = 0x11, DW_CFA_offset_extended_sf = 0x11,
DW_CFA_def_cfa_sf = 0x12, DW_CFA_def_cfa_sf = 0x12,
DW_CFA_def_cfa_offset_sf = 0x13, DW_CFA_def_cfa_offset_sf = 0x13,
DW_CFA_val_expression = 0x16, DW_CFA_val_expression = 0x16,
DW_CFA_lo_user = 0x1c, DW_CFA_lo_user = 0x1c,
DW_CFA_MIPS_advance_loc8 = 0x1d, DW_CFA_MIPS_advance_loc8 = 0x1d,
DW_CFA_GNU_window_save = 0x2d, DW_CFA_GNU_window_save = 0x2d,
DW_CFA_GNU_args_size = 0x2e, DW_CFA_GNU_args_size = 0x2e,
DW_CFA_GNU_negative_offset_extended = 0x2f, DW_CFA_GNU_negative_offset_extended = 0x2f,
DW_CFA_hi_user = 0x3c DW_CFA_hi_user = 0x3c
} }
dwarf_cfa_t; dwarf_cfa_t;
@ -186,53 +186,53 @@ dwarf_cfa_t;
engineered from GCC. engineered from GCC.
*/ */
#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */ #define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */ #define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
/* Flag bit. If set, the resulting pointer is the address of the word /* Flag bit. If set, the resulting pointer is the address of the word
that contains the final address. */ that contains the final address. */
#define DW_EH_PE_indirect 0x80 #define DW_EH_PE_indirect 0x80
/* Pointer-encoding formats: */ /* Pointer-encoding formats: */
#define DW_EH_PE_omit 0xff #define DW_EH_PE_omit 0xff
#define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */ #define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
#define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */ #define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */
#define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */ #define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */
#define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */ #define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
#define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */ #define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
#define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */ #define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */
#define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */ #define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */
#define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */ #define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
#define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */ #define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
/* Pointer-encoding application: */ /* Pointer-encoding application: */
#define DW_EH_PE_absptr 0x00 /* absolute value */ #define DW_EH_PE_absptr 0x00 /* absolute value */
#define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */ #define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */
#define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */ #define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */
#define DW_EH_PE_datarel 0x30 /* data-relative */ #define DW_EH_PE_datarel 0x30 /* data-relative */
/* The following are not documented by LSB v1.3, yet they are used by /* The following are not documented by LSB v1.3, yet they are used by
GCC, presumably they aren't documented by LSB since they aren't GCC, presumably they aren't documented by LSB since they aren't
used on Linux: */ used on Linux: */
#define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */ #define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
#define DW_EH_PE_aligned 0x50 /* aligned pointer */ #define DW_EH_PE_aligned 0x50 /* aligned pointer */
extern struct mempool dwarf_reg_state_pool; extern struct mempool dwarf_reg_state_pool;
extern struct mempool dwarf_cie_info_pool; extern struct mempool dwarf_cie_info_pool;
typedef enum typedef enum
{ {
DWARF_WHERE_UNDEF, /* register isn't saved at all */ DWARF_WHERE_UNDEF, /* register isn't saved at all */
DWARF_WHERE_SAME, /* register has same value as in prev. frame */ DWARF_WHERE_SAME, /* register has same value as in prev. frame */
DWARF_WHERE_CFAREL, /* register saved at CFA-relative address */ DWARF_WHERE_CFAREL, /* register saved at CFA-relative address */
DWARF_WHERE_REG, /* register saved in another register */ DWARF_WHERE_REG, /* register saved in another register */
DWARF_WHERE_EXPR, /* register saved */ DWARF_WHERE_EXPR, /* register saved */
DWARF_WHERE_VAL_EXPR, /* register has computed value */ DWARF_WHERE_VAL_EXPR, /* register has computed value */
} }
dwarf_where_t; dwarf_where_t;
typedef struct typedef struct
{ {
dwarf_where_t where; /* how is the register saved? */ dwarf_where_t where; /* how is the register saved? */
unw_word_t val; /* where it's saved */ unw_word_t val; /* where it's saved */
} }
dwarf_save_loc_t; dwarf_save_loc_t;
@ -246,18 +246,18 @@ dwarf_save_loc_t;
case of DWARF_WHERE_REG, member "val" gives the number of the case of DWARF_WHERE_REG, member "val" gives the number of the
base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives
the offset value. */ the offset value. */
#define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS #define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS
#define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1) #define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1)
typedef struct dwarf_reg_state typedef struct dwarf_reg_state
{ {
struct dwarf_reg_state *next; /* for rs_stack */ struct dwarf_reg_state *next; /* for rs_stack */
dwarf_save_loc_t reg[DWARF_NUM_PRESERVED_REGS + 2]; dwarf_save_loc_t reg[DWARF_NUM_PRESERVED_REGS + 2];
unw_word_t ip; /* ip this rs is for */ unw_word_t ip; /* ip this rs is for */
unw_word_t ret_addr_column; /* indicates which column in the rule table represents return address */ unw_word_t ret_addr_column; /* indicates which column in the rule table represents return address */
unsigned short lru_chain; /* used for least-recently-used chain */ unsigned short lru_chain; /* used for least-recently-used chain */
unsigned short coll_chain; /* used for hash collisions */ unsigned short coll_chain; /* used for hash collisions */
unsigned short hint; /* hint for next rs to try (or -1) */ unsigned short hint; /* hint for next rs to try (or -1) */
unsigned short valid : 1; /* optional machine-dependent signal info */ unsigned short valid : 1; /* optional machine-dependent signal info */
unsigned short signal_frame : 1; /* optional machine-dependent signal info */ unsigned short signal_frame : 1; /* optional machine-dependent signal info */
} }
@ -265,14 +265,14 @@ dwarf_reg_state_t;
typedef struct dwarf_cie_info typedef struct dwarf_cie_info
{ {
unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */ unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */
unw_word_t cie_instr_end; /* end addr. of CIE "initial_instructions" */ unw_word_t cie_instr_end; /* end addr. of CIE "initial_instructions" */
unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */ unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */
unw_word_t fde_instr_end; /* end addr. of FDE "instructions" */ unw_word_t fde_instr_end; /* end addr. of FDE "instructions" */
unw_word_t code_align; /* code-alignment factor */ unw_word_t code_align; /* code-alignment factor */
unw_word_t data_align; /* data-alignment factor */ unw_word_t data_align; /* data-alignment factor */
unw_word_t ret_addr_column; /* column of return-address register */ unw_word_t ret_addr_column; /* column of return-address register */
unw_word_t handler; /* address of personality-routine */ unw_word_t handler; /* address of personality-routine */
uint16_t abi; uint16_t abi;
uint16_t tag; uint16_t tag;
uint8_t fde_encoding; uint8_t fde_encoding;
@ -288,20 +288,20 @@ typedef struct dwarf_state_record
unsigned char fde_encoding; unsigned char fde_encoding;
unw_word_t args_size; unw_word_t args_size;
dwarf_reg_state_t rs_initial; /* reg-state after CIE instructions */ dwarf_reg_state_t rs_initial; /* reg-state after CIE instructions */
dwarf_reg_state_t rs_current; /* current reg-state */ dwarf_reg_state_t rs_current; /* current reg-state */
} }
dwarf_state_record_t; dwarf_state_record_t;
typedef struct dwarf_cursor typedef struct dwarf_cursor
{ {
void *as_arg; /* argument to address-space callbacks */ void *as_arg; /* argument to address-space callbacks */
unw_addr_space_t as; /* reference to per-address-space info */ unw_addr_space_t as; /* reference to per-address-space info */
unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */ unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */
unw_word_t ip; /* instruction pointer */ unw_word_t ip; /* instruction pointer */
unw_word_t args_size; /* size of arguments */ unw_word_t args_size; /* size of arguments */
unw_word_t ret_addr_column; /* column for return-address */ unw_word_t ret_addr_column; /* column for return-address */
unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS]; unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS];
unsigned int eh_valid_mask; unsigned int eh_valid_mask;
@ -309,33 +309,33 @@ typedef struct dwarf_cursor
unsigned int stash_frames :1; /* stash frames for fast lookup */ unsigned int stash_frames :1; /* stash frames for fast lookup */
unsigned int use_prev_instr :1; /* use previous (= call) or current (= signal) instruction? */ unsigned int use_prev_instr :1; /* use previous (= call) or current (= signal) instruction? */
unsigned int pi_valid :1; /* is proc_info valid? */ unsigned int pi_valid :1; /* is proc_info valid? */
unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */ unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */
unw_proc_info_t pi; /* info about current procedure */ unw_proc_info_t pi; /* info about current procedure */
short hint; /* faster lookup of the rs cache */ short hint; /* faster lookup of the rs cache */
short prev_rs; short prev_rs;
} }
dwarf_cursor_t; dwarf_cursor_t;
#define DWARF_LOG_UNW_CACHE_SIZE 7 #define DWARF_LOG_UNW_CACHE_SIZE 7
#define DWARF_UNW_CACHE_SIZE (1 << DWARF_LOG_UNW_CACHE_SIZE) #define DWARF_UNW_CACHE_SIZE (1 << DWARF_LOG_UNW_CACHE_SIZE)
#define DWARF_LOG_UNW_HASH_SIZE (DWARF_LOG_UNW_CACHE_SIZE + 1) #define DWARF_LOG_UNW_HASH_SIZE (DWARF_LOG_UNW_CACHE_SIZE + 1)
#define DWARF_UNW_HASH_SIZE (1 << DWARF_LOG_UNW_HASH_SIZE) #define DWARF_UNW_HASH_SIZE (1 << DWARF_LOG_UNW_HASH_SIZE)
typedef unsigned char unw_hash_index_t; typedef unsigned char unw_hash_index_t;
struct dwarf_rs_cache struct dwarf_rs_cache
{ {
pthread_mutex_t lock; pthread_mutex_t lock;
unsigned short lru_head; /* index of lead-recently used rs */ unsigned short lru_head; /* index of lead-recently used rs */
unsigned short lru_tail; /* index of most-recently used rs */ unsigned short lru_tail; /* index of most-recently used rs */
/* hash table that maps instruction pointer to rs index: */ /* hash table that maps instruction pointer to rs index: */
unsigned short hash[DWARF_UNW_HASH_SIZE]; unsigned short hash[DWARF_UNW_HASH_SIZE];
uint32_t generation; /* generation number */ uint32_t generation; /* generation number */
/* rs cache: */ /* rs cache: */
dwarf_reg_state_t buckets[DWARF_UNW_CACHE_SIZE]; dwarf_reg_state_t buckets[DWARF_UNW_CACHE_SIZE];
@ -361,74 +361,74 @@ struct unw_debug_frame_list
struct dwarf_callback_data struct dwarf_callback_data
{ {
/* in: */ /* in: */
unw_word_t ip; /* instruction-pointer we're looking for */ unw_word_t ip; /* instruction-pointer we're looking for */
unw_proc_info_t *pi; /* proc-info pointer */ unw_proc_info_t *pi; /* proc-info pointer */
int need_unwind_info; int need_unwind_info;
/* out: */ /* out: */
int single_fde; /* did we find a single FDE? (vs. a table) */ int single_fde; /* did we find a single FDE? (vs. a table) */
unw_dyn_info_t di; /* table info (if single_fde is false) */ unw_dyn_info_t di; /* table info (if single_fde is false) */
unw_dyn_info_t di_debug; /* additional table info for .debug_frame */ unw_dyn_info_t di_debug; /* additional table info for .debug_frame */
}; };
/* Convenience macros: */ /* Convenience macros: */
#define dwarf_init UNW_ARCH_OBJ (dwarf_init) #define dwarf_init UNW_ARCH_OBJ (dwarf_init)
#define dwarf_callback UNW_OBJ (dwarf_callback) #define dwarf_callback UNW_OBJ (dwarf_callback)
#define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info) #define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info)
#define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame) #define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame)
#define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table) #define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table)
#define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table) #define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table)
#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
#define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr) #define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr)
#define dwarf_extract_proc_info_from_fde \ #define dwarf_extract_proc_info_from_fde \
UNW_OBJ (dwarf_extract_proc_info_from_fde) UNW_OBJ (dwarf_extract_proc_info_from_fde)
#define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs) #define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs)
#define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record) #define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record)
#define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info) #define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info)
#define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer) #define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer)
#define dwarf_step UNW_OBJ (dwarf_step) #define dwarf_step UNW_OBJ (dwarf_step)
extern int dwarf_init (void); extern int dwarf_init (void);
#ifndef UNW_REMOTE_ONLY #ifndef UNW_REMOTE_ONLY
extern int dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr); extern int dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr);
extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
#endif /* !UNW_REMOTE_ONLY */ #endif /* !UNW_REMOTE_ONLY */
extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug,
unw_word_t ip, unw_word_t segbase, unw_word_t ip, unw_word_t segbase,
const char* obj_name, unw_word_t start, const char* obj_name, unw_word_t start,
unw_word_t end); unw_word_t end);
extern int dwarf_search_unwind_table (unw_addr_space_t as, extern int dwarf_search_unwind_table (unw_addr_space_t as,
unw_word_t ip, unw_word_t ip,
unw_dyn_info_t *di, unw_dyn_info_t *di,
unw_proc_info_t *pi, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
char *path, unw_word_t segbase, unw_word_t mapoff, char *path, unw_word_t segbase, unw_word_t mapoff,
unw_word_t ip); unw_word_t ip);
extern void dwarf_put_unwind_info (unw_addr_space_t as, extern void dwarf_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg); unw_proc_info_t *pi, void *arg);
extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr,
unw_word_t len, unw_word_t *valp, unw_word_t len, unw_word_t *valp,
int *is_register); int *is_register);
extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as, extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as,
unw_accessors_t *a, unw_accessors_t *a,
unw_word_t *fde_addr, unw_word_t *fde_addr,
unw_proc_info_t *pi, unw_proc_info_t *pi,
int need_unwind_info, int need_unwind_info,
unw_word_t base, unw_word_t base,
void *arg); void *arg);
extern int dwarf_find_save_locs (struct dwarf_cursor *c); extern int dwarf_find_save_locs (struct dwarf_cursor *c);
extern int dwarf_create_state_record (struct dwarf_cursor *c, extern int dwarf_create_state_record (struct dwarf_cursor *c,
dwarf_state_record_t *sr); dwarf_state_record_t *sr);
extern int dwarf_make_proc_info (struct dwarf_cursor *c); extern int dwarf_make_proc_info (struct dwarf_cursor *c);
extern int dwarf_read_encoded_pointer (unw_addr_space_t as, extern int dwarf_read_encoded_pointer (unw_addr_space_t as,
unw_accessors_t *a, unw_accessors_t *a,
unw_word_t *addr, unw_word_t *addr,
unsigned char encoding, unsigned char encoding,
const unw_proc_info_t *pi, const unw_proc_info_t *pi,
unw_word_t *valp, void *arg); unw_word_t *valp, void *arg);
extern int dwarf_step (struct dwarf_cursor *c); extern int dwarf_step (struct dwarf_cursor *c);
#endif /* dwarf_h */ #endif /* dwarf_h */

View file

@ -16,10 +16,10 @@
#endif #endif
#ifndef dwarf_to_unw_regnum #ifndef dwarf_to_unw_regnum
# define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map) # define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map)
extern const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH]; extern const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH];
/* REG is evaluated multiple times; it better be side-effects free! */ /* REG is evaluated multiple times; it better be side-effects free! */
# define dwarf_to_unw_regnum(reg) \ # define dwarf_to_unw_regnum(reg) \
(((reg) <= DWARF_REGNUM_MAP_LENGTH) ? dwarf_to_unw_regnum_map[reg] : 0) (((reg) <= DWARF_REGNUM_MAP_LENGTH) ? dwarf_to_unw_regnum_map[reg] : 0)
#endif #endif
@ -44,7 +44,7 @@ dwarf_misaligned_value_t;
static inline int static inline int
dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int8_t *val, void *arg) int8_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -55,7 +55,7 @@ dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int16_t *val, void *arg) int16_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -66,7 +66,7 @@ dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int32_t *val, void *arg) int32_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -77,7 +77,7 @@ dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int64_t *val, void *arg) int64_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -88,7 +88,7 @@ dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint8_t *val, void *arg) uint8_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -99,7 +99,7 @@ dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint16_t *val, void *arg) uint16_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -110,7 +110,7 @@ dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint32_t *val, void *arg) uint32_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -121,7 +121,7 @@ dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint64_t *val, void *arg) uint64_t *val, void *arg)
{ {
dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
@ -134,7 +134,7 @@ dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint8_t *valp, void *arg) uint8_t *valp, void *arg)
{ {
unw_word_t val, aligned_addr = *addr & -sizeof (unw_word_t); unw_word_t val, aligned_addr = *addr & -sizeof (unw_word_t);
unw_word_t off = *addr - aligned_addr; unw_word_t off = *addr - aligned_addr;
@ -153,7 +153,7 @@ dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint16_t *val, void *arg) uint16_t *val, void *arg)
{ {
uint8_t v0, v1; uint8_t v0, v1;
int ret; int ret;
@ -171,7 +171,7 @@ dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint32_t *val, void *arg) uint32_t *val, void *arg)
{ {
uint16_t v0, v1; uint16_t v0, v1;
int ret; int ret;
@ -189,7 +189,7 @@ dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint64_t *val, void *arg) uint64_t *val, void *arg)
{ {
uint32_t v0, v1; uint32_t v0, v1;
int ret; int ret;
@ -207,7 +207,7 @@ dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int8_t *val, void *arg) int8_t *val, void *arg)
{ {
uint8_t uval; uint8_t uval;
int ret; int ret;
@ -220,7 +220,7 @@ dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int16_t *val, void *arg) int16_t *val, void *arg)
{ {
uint16_t uval; uint16_t uval;
int ret; int ret;
@ -233,7 +233,7 @@ dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int32_t *val, void *arg) int32_t *val, void *arg)
{ {
uint32_t uval; uint32_t uval;
int ret; int ret;
@ -246,7 +246,7 @@ dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int64_t *val, void *arg) int64_t *val, void *arg)
{ {
uint64_t uval; uint64_t uval;
int ret; int ret;
@ -261,7 +261,7 @@ dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *val, void *arg) unw_word_t *val, void *arg)
{ {
uint32_t u32; uint32_t u32;
uint64_t u64; uint64_t u64;
@ -272,14 +272,14 @@ dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
case 4: case 4:
ret = dwarf_readu32 (as, a, addr, &u32, arg); ret = dwarf_readu32 (as, a, addr, &u32, arg);
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = u32; *val = u32;
return ret; return ret;
case 8: case 8:
ret = dwarf_readu64 (as, a, addr, &u64, arg); ret = dwarf_readu64 (as, a, addr, &u64, arg);
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = u64; *val = u64;
return ret; return ret;
@ -293,7 +293,7 @@ dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *valp, void *arg) unw_word_t *valp, void *arg)
{ {
unw_word_t val = 0, shift = 0; unw_word_t val = 0, shift = 0;
unsigned char byte; unsigned char byte;
@ -302,7 +302,7 @@ dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
do do
{ {
if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0) if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
return ret; return ret;
val |= ((unw_word_t) byte & 0x7f) << shift; val |= ((unw_word_t) byte & 0x7f) << shift;
shift += 7; shift += 7;
@ -318,7 +318,7 @@ dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline int static inline int
dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *valp, void *arg) unw_word_t *valp, void *arg)
{ {
unw_word_t val = 0, shift = 0; unw_word_t val = 0, shift = 0;
unsigned char byte; unsigned char byte;
@ -327,7 +327,7 @@ dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
do do
{ {
if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0) if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
return ret; return ret;
val |= ((unw_word_t) byte & 0x7f) << shift; val |= ((unw_word_t) byte & 0x7f) << shift;
shift += 7; shift += 7;
@ -344,9 +344,9 @@ dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static ALWAYS_INLINE int static ALWAYS_INLINE int
dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a, dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, unsigned char encoding, unw_word_t *addr, unsigned char encoding,
const unw_proc_info_t *pi, const unw_proc_info_t *pi,
unw_word_t *valp, void *arg) unw_word_t *valp, void *arg)
{ {
unw_word_t val, initial_addr = *addr; unw_word_t val, initial_addr = *addr;
uint16_t uval16; uint16_t uval16;
@ -375,58 +375,58 @@ dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
{ {
case DW_EH_PE_ptr: case DW_EH_PE_ptr:
if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
return ret; return ret;
break; break;
case DW_EH_PE_uleb128: case DW_EH_PE_uleb128:
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
return ret; return ret;
break; break;
case DW_EH_PE_udata2: case DW_EH_PE_udata2:
if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0) if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
return ret; return ret;
val = uval16; val = uval16;
break; break;
case DW_EH_PE_udata4: case DW_EH_PE_udata4:
if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0) if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
return ret; return ret;
val = uval32; val = uval32;
break; break;
case DW_EH_PE_udata8: case DW_EH_PE_udata8:
if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0) if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
return ret; return ret;
val = uval64; val = uval64;
break; break;
case DW_EH_PE_sleb128: case DW_EH_PE_sleb128:
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
return ret; return ret;
break; break;
case DW_EH_PE_sdata2: case DW_EH_PE_sdata2:
if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0) if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
return ret; return ret;
val = sval16; val = sval16;
break; break;
case DW_EH_PE_sdata4: case DW_EH_PE_sdata4:
if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0) if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
return ret; return ret;
val = sval32; val = sval32;
break; break;
case DW_EH_PE_sdata8: case DW_EH_PE_sdata8:
if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0) if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
return ret; return ret;
val = sval64; val = sval64;
break; break;
default: default:
Debug (1, "unexpected encoding format 0x%x\n", Debug (1, "unexpected encoding format 0x%x\n",
encoding & DW_EH_PE_FORMAT_MASK); encoding & DW_EH_PE_FORMAT_MASK);
return -UNW_EINVAL; return -UNW_EINVAL;
} }
@ -462,7 +462,7 @@ dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
"segbase" member to unw_proc_info_t. */ "segbase" member to unw_proc_info_t. */
default: default:
Debug (1, "unexpected application type 0x%x\n", Debug (1, "unexpected application type 0x%x\n",
encoding & DW_EH_PE_APPL_MASK); encoding & DW_EH_PE_APPL_MASK);
return -UNW_EINVAL; return -UNW_EINVAL;
} }
@ -480,7 +480,7 @@ dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t indirect_addr = val; unw_word_t indirect_addr = val;
if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0) if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
return ret; return ret;
} }
*valp = val; *valp = val;

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2001-2004 Hewlett-Packard Co Copyright (C) 2001-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Copyright (C) 2013 Linaro Limited Copyright (C) 2013 Linaro Limited
This file is part of libunwind. This file is part of libunwind.
@ -35,10 +35,10 @@ extern "C" {
#include <stddef.h> #include <stddef.h>
#include <ucontext.h> #include <ucontext.h>
#define UNW_TARGET aarch64 #define UNW_TARGET aarch64
#define UNW_TARGET_AARCH64 1 #define UNW_TARGET_AARCH64 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
@ -46,7 +46,7 @@ extern "C" {
relatively cheap and unwind-state copying is relatively rare, so we relatively cheap and unwind-state copying is relatively rare, so we
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
#define UNW_TDEP_CURSOR_LEN 4096 #define UNW_TDEP_CURSOR_LEN 4096
typedef uint64_t unw_word_t; typedef uint64_t unw_word_t;
typedef int64_t unw_sword_t; typedef int64_t unw_sword_t;
@ -160,7 +160,7 @@ typedef enum
aarch64_regnum_t; aarch64_regnum_t;
/* Use R0 through R3 to pass exception handling information. */ /* Use R0 through R3 to pass exception handling information. */
#define UNW_TDEP_NUM_EH_REGS 4 #define UNW_TDEP_NUM_EH_REGS 4
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -176,7 +176,7 @@ typedef ucontext_t unw_tdep_context_t;
#include "libunwind-dynamic.h" #include "libunwind-dynamic.h"
#define unw_tdep_getcontext(uc) (getcontext (uc), 0) #define unw_tdep_getcontext(uc) (getcontext (uc), 0)
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);

View file

@ -32,10 +32,10 @@ extern "C" {
#include <inttypes.h> #include <inttypes.h>
#include <stddef.h> #include <stddef.h>
#define UNW_TARGET arm #define UNW_TARGET arm
#define UNW_TARGET_ARM 1 #define UNW_TARGET_ARM 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
@ -44,7 +44,7 @@ extern "C" {
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
/* FIXME for ARM. Too big? What do other things use for similar tasks? */ /* FIXME for ARM. Too big? What do other things use for similar tasks? */
#define UNW_TDEP_CURSOR_LEN 4096 #define UNW_TDEP_CURSOR_LEN 4096
typedef uint32_t unw_word_t; typedef uint32_t unw_word_t;
typedef int32_t unw_sword_t; typedef int32_t unw_sword_t;
@ -242,7 +242,7 @@ typedef enum
} }
arm_regnum_t; arm_regnum_t;
#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for ARM. */ #define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for ARM. */
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -263,22 +263,22 @@ unw_tdep_context_t;
registers. FIXME: Not ideal, may not be sufficient for all libunwind registers. FIXME: Not ideal, may not be sufficient for all libunwind
use cases. Stores pc+8, which is only approximately correct, really. */ use cases. Stores pc+8, which is only approximately correct, really. */
#ifndef __thumb__ #ifndef __thumb__
#define unw_tdep_getcontext(uc) (({ \ #define unw_tdep_getcontext(uc) (({ \
unw_tdep_context_t *unw_ctx = (uc); \ unw_tdep_context_t *unw_ctx = (uc); \
register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \ register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"stmia %[base], {r0-r15}" \ "stmia %[base], {r0-r15}" \
: : [base] "r" (unw_base) : "memory"); \ : : [base] "r" (unw_base) : "memory"); \
}), 0) }), 0)
#else /* __thumb__ */ #else /* __thumb__ */
#define unw_tdep_getcontext(uc) (({ \ #define unw_tdep_getcontext(uc) (({ \
unw_tdep_context_t *unw_ctx = (uc); \ unw_tdep_context_t *unw_ctx = (uc); \
register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \ register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
".align 2\nbx pc\nnop\n.code 32\n" \ ".align 2\nbx pc\nnop\n.code 32\n" \
"stmia %[base], {r0-r15}\n" \ "stmia %[base], {r0-r15}\n" \
"orr %[base], pc, #1\nbx %[base]" \ "orr %[base], pc, #1\nbx %[base]" \
: [base] "+r" (unw_base) : : "memory", "cc"); \ : [base] "+r" (unw_base) : : "memory", "cc"); \
}), 0) }), 0)
#endif #endif
@ -292,7 +292,7 @@ unw_tdep_proc_info_t;
#include "libunwind-common.h" #include "libunwind-common.h"
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View file

@ -46,22 +46,22 @@ extern pid_t _UCD_get_pid(struct UCD_info *);
extern int _UCD_get_cursig(struct UCD_info *); extern int _UCD_get_cursig(struct UCD_info *);
extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename); extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename);
extern int _UCD_add_backing_file_at_vaddr(struct UCD_info *, extern int _UCD_add_backing_file_at_vaddr(struct UCD_info *,
unsigned long vaddr, unsigned long vaddr,
const char *filename); const char *filename);
extern int _UCD_find_proc_info (unw_addr_space_t, unw_word_t, extern int _UCD_find_proc_info (unw_addr_space_t, unw_word_t,
unw_proc_info_t *, int, void *); unw_proc_info_t *, int, void *);
extern void _UCD_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *); extern void _UCD_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *);
extern int _UCD_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *, extern int _UCD_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *,
void *); void *);
extern int _UCD_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int, extern int _UCD_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int,
void *); void *);
extern int _UCD_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *, extern int _UCD_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *,
int, void *); int, void *);
extern int _UCD_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, extern int _UCD_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *,
int, void *); int, void *);
extern int _UCD_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t, extern int _UCD_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t,
unw_word_t *, void *); unw_word_t *, void *);
extern int _UCD_resume (unw_addr_space_t, unw_cursor_t *, void *); extern int _UCD_resume (unw_addr_space_t, unw_cursor_t *, void *);
extern unw_accessors_t _UCD_accessors; extern unw_accessors_t _UCD_accessors;

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2002-2004 Hewlett-Packard Co Copyright (C) 2002-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -59,50 +59,50 @@ the following rules should be followed in declaring these structures:
typedef enum typedef enum
{ {
UNW_DYN_STOP = 0, /* end-of-unwind-info marker */ UNW_DYN_STOP = 0, /* end-of-unwind-info marker */
UNW_DYN_SAVE_REG, /* save register to another register */ UNW_DYN_SAVE_REG, /* save register to another register */
UNW_DYN_SPILL_FP_REL, /* frame-pointer-relative register spill */ UNW_DYN_SPILL_FP_REL, /* frame-pointer-relative register spill */
UNW_DYN_SPILL_SP_REL, /* stack-pointer-relative register spill */ UNW_DYN_SPILL_SP_REL, /* stack-pointer-relative register spill */
UNW_DYN_ADD, /* add constant value to a register */ UNW_DYN_ADD, /* add constant value to a register */
UNW_DYN_POP_FRAMES, /* drop one or more stack frames */ UNW_DYN_POP_FRAMES, /* drop one or more stack frames */
UNW_DYN_LABEL_STATE, /* name the current state */ UNW_DYN_LABEL_STATE, /* name the current state */
UNW_DYN_COPY_STATE, /* set the region's entry-state */ UNW_DYN_COPY_STATE, /* set the region's entry-state */
UNW_DYN_ALIAS /* get unwind info from an alias */ UNW_DYN_ALIAS /* get unwind info from an alias */
} }
unw_dyn_operation_t; unw_dyn_operation_t;
typedef enum typedef enum
{ {
UNW_INFO_FORMAT_DYNAMIC, /* unw_dyn_proc_info_t */ UNW_INFO_FORMAT_DYNAMIC, /* unw_dyn_proc_info_t */
UNW_INFO_FORMAT_TABLE, /* unw_dyn_table_t */ UNW_INFO_FORMAT_TABLE, /* unw_dyn_table_t */
UNW_INFO_FORMAT_REMOTE_TABLE, /* unw_dyn_remote_table_t */ UNW_INFO_FORMAT_REMOTE_TABLE, /* unw_dyn_remote_table_t */
UNW_INFO_FORMAT_ARM_EXIDX /* ARM specific unwind info */ UNW_INFO_FORMAT_ARM_EXIDX /* ARM specific unwind info */
} }
unw_dyn_info_format_t; unw_dyn_info_format_t;
typedef struct unw_dyn_op typedef struct unw_dyn_op
{ {
int8_t tag; /* what operation? */ int8_t tag; /* what operation? */
int8_t qp; /* qualifying predicate register */ int8_t qp; /* qualifying predicate register */
int16_t reg; /* what register */ int16_t reg; /* what register */
int32_t when; /* when does it take effect? */ int32_t when; /* when does it take effect? */
unw_word_t val; /* auxiliary value */ unw_word_t val; /* auxiliary value */
} }
unw_dyn_op_t; unw_dyn_op_t;
typedef struct unw_dyn_region_info typedef struct unw_dyn_region_info
{ {
struct unw_dyn_region_info *next; /* linked list of regions */ struct unw_dyn_region_info *next; /* linked list of regions */
int32_t insn_count; /* region length (# of instructions) */ int32_t insn_count; /* region length (# of instructions) */
uint32_t op_count; /* length of op-array */ uint32_t op_count; /* length of op-array */
unw_dyn_op_t op[1]; /* variable-length op-array */ unw_dyn_op_t op[1]; /* variable-length op-array */
} }
unw_dyn_region_info_t; unw_dyn_region_info_t;
typedef struct unw_dyn_proc_info typedef struct unw_dyn_proc_info
{ {
unw_word_t name_ptr; /* address of human-readable procedure name */ unw_word_t name_ptr; /* address of human-readable procedure name */
unw_word_t handler; /* address of personality routine */ unw_word_t handler; /* address of personality routine */
uint32_t flags; uint32_t flags;
int32_t pad0; int32_t pad0;
unw_dyn_region_info_t *regions; unw_dyn_region_info_t *regions;
@ -111,18 +111,18 @@ unw_dyn_proc_info_t;
typedef struct unw_dyn_table_info typedef struct unw_dyn_table_info
{ {
unw_word_t name_ptr; /* addr. of table name (e.g., library name) */ unw_word_t name_ptr; /* addr. of table name (e.g., library name) */
unw_word_t segbase; /* segment base */ unw_word_t segbase; /* segment base */
unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */ unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */
unw_word_t *table_data; unw_word_t *table_data;
} }
unw_dyn_table_info_t; unw_dyn_table_info_t;
typedef struct unw_dyn_remote_table_info typedef struct unw_dyn_remote_table_info
{ {
unw_word_t name_ptr; /* addr. of table name (e.g., library name) */ unw_word_t name_ptr; /* addr. of table name (e.g., library name) */
unw_word_t segbase; /* segment base */ unw_word_t segbase; /* segment base */
unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */ unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */
unw_word_t table_data; unw_word_t table_data;
} }
unw_dyn_remote_table_info_t; unw_dyn_remote_table_info_t;
@ -132,16 +132,16 @@ typedef struct unw_dyn_info
/* doubly-linked list of dyn-info structures: */ /* doubly-linked list of dyn-info structures: */
struct unw_dyn_info *next; struct unw_dyn_info *next;
struct unw_dyn_info *prev; struct unw_dyn_info *prev;
unw_word_t start_ip; /* first IP covered by this entry */ unw_word_t start_ip; /* first IP covered by this entry */
unw_word_t end_ip; /* first IP NOT covered by this entry */ unw_word_t end_ip; /* first IP NOT covered by this entry */
unw_word_t gp; /* global-pointer in effect for this entry */ unw_word_t gp; /* global-pointer in effect for this entry */
int32_t format; /* real type: unw_dyn_info_format_t */ int32_t format; /* real type: unw_dyn_info_format_t */
int32_t pad; int32_t pad;
union union
{ {
unw_dyn_proc_info_t pi; unw_dyn_proc_info_t pi;
unw_dyn_table_info_t ti; unw_dyn_table_info_t ti;
unw_dyn_remote_table_info_t rti; unw_dyn_remote_table_info_t rti;
} }
u; u;
} }
@ -157,9 +157,9 @@ unw_dyn_info_list_t;
/* Return the size (in bytes) of an unw_dyn_region_info_t structure that can /* Return the size (in bytes) of an unw_dyn_region_info_t structure that can
hold OP_COUNT ops. */ hold OP_COUNT ops. */
#define _U_dyn_region_info_size(op_count) \ #define _U_dyn_region_info_size(op_count) \
((char *) (((unw_dyn_region_info_t *) NULL)->op + (op_count)) \ ((char *) (((unw_dyn_region_info_t *) NULL)->op + (op_count)) \
- (char *) NULL) - (char *) NULL)
/* Register the unwind info for a single procedure. /* Register the unwind info for a single procedure.
This routine is NOT signal-safe. */ This routine is NOT signal-safe. */
@ -172,39 +172,39 @@ extern void _U_dyn_cancel (unw_dyn_info_t *);
/* Convenience routines. */ /* Convenience routines. */
#define _U_dyn_op(_tag, _qp, _when, _reg, _val) \ #define _U_dyn_op(_tag, _qp, _when, _reg, _val) \
((unw_dyn_op_t) { (_tag), (_qp), (_reg), (_when), (_val) }) ((unw_dyn_op_t) { (_tag), (_qp), (_reg), (_when), (_val) })
#define _U_dyn_op_save_reg(op, qp, when, reg, dst) \ #define _U_dyn_op_save_reg(op, qp, when, reg, dst) \
(*(op) = _U_dyn_op (UNW_DYN_SAVE_REG, (qp), (when), (reg), (dst))) (*(op) = _U_dyn_op (UNW_DYN_SAVE_REG, (qp), (when), (reg), (dst)))
#define _U_dyn_op_spill_fp_rel(op, qp, when, reg, offset) \ #define _U_dyn_op_spill_fp_rel(op, qp, when, reg, offset) \
(*(op) = _U_dyn_op (UNW_DYN_SPILL_FP_REL, (qp), (when), (reg), \ (*(op) = _U_dyn_op (UNW_DYN_SPILL_FP_REL, (qp), (when), (reg), \
(offset))) (offset)))
#define _U_dyn_op_spill_sp_rel(op, qp, when, reg, offset) \ #define _U_dyn_op_spill_sp_rel(op, qp, when, reg, offset) \
(*(op) = _U_dyn_op (UNW_DYN_SPILL_SP_REL, (qp), (when), (reg), \ (*(op) = _U_dyn_op (UNW_DYN_SPILL_SP_REL, (qp), (when), (reg), \
(offset))) (offset)))
#define _U_dyn_op_add(op, qp, when, reg, value) \ #define _U_dyn_op_add(op, qp, when, reg, value) \
(*(op) = _U_dyn_op (UNW_DYN_ADD, (qp), (when), (reg), (value))) (*(op) = _U_dyn_op (UNW_DYN_ADD, (qp), (when), (reg), (value)))
#define _U_dyn_op_pop_frames(op, qp, when, num_frames) \ #define _U_dyn_op_pop_frames(op, qp, when, num_frames) \
(*(op) = _U_dyn_op (UNW_DYN_POP_FRAMES, (qp), (when), 0, (num_frames))) (*(op) = _U_dyn_op (UNW_DYN_POP_FRAMES, (qp), (when), 0, (num_frames)))
#define _U_dyn_op_label_state(op, label) \ #define _U_dyn_op_label_state(op, label) \
(*(op) = _U_dyn_op (UNW_DYN_LABEL_STATE, _U_QP_TRUE, -1, 0, (label))) (*(op) = _U_dyn_op (UNW_DYN_LABEL_STATE, _U_QP_TRUE, -1, 0, (label)))
#define _U_dyn_op_copy_state(op, label) \ #define _U_dyn_op_copy_state(op, label) \
(*(op) = _U_dyn_op (UNW_DYN_COPY_STATE, _U_QP_TRUE, -1, 0, (label))) (*(op) = _U_dyn_op (UNW_DYN_COPY_STATE, _U_QP_TRUE, -1, 0, (label)))
#define _U_dyn_op_alias(op, qp, when, addr) \ #define _U_dyn_op_alias(op, qp, when, addr) \
(*(op) = _U_dyn_op (UNW_DYN_ALIAS, (qp), (when), 0, (addr))) (*(op) = _U_dyn_op (UNW_DYN_ALIAS, (qp), (when), 0, (addr)))
#define _U_dyn_op_stop(op) \ #define _U_dyn_op_stop(op) \
(*(op) = _U_dyn_op (UNW_DYN_STOP, _U_QP_TRUE, -1, 0, 0)) (*(op) = _U_dyn_op (UNW_DYN_STOP, _U_QP_TRUE, -1, 0, 0))
/* The target-dependent qualifying predicate which is always TRUE. On /* The target-dependent qualifying predicate which is always TRUE. On
IA-64, that's p0 (0), on non-predicated architectures, the value is IA-64, that's p0 (0), on non-predicated architectures, the value is
ignored. */ ignored. */
#define _U_QP_TRUE _U_TDEP_QP_TRUE #define _U_QP_TRUE _U_TDEP_QP_TRUE

View file

@ -32,17 +32,17 @@ extern "C" {
#include <inttypes.h> #include <inttypes.h>
#include <ucontext.h> #include <ucontext.h>
#define UNW_TARGET hppa #define UNW_TARGET hppa
#define UNW_TARGET_HPPA 1 #define UNW_TARGET_HPPA 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
require recompiling all users of this library. Stack allocation is require recompiling all users of this library. Stack allocation is
relatively cheap and unwind-state copying is relatively rare, so we relatively cheap and unwind-state copying is relatively rare, so we
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
#define UNW_TDEP_CURSOR_LEN 511 #define UNW_TDEP_CURSOR_LEN 511
typedef uint32_t unw_word_t; typedef uint32_t unw_word_t;
typedef int32_t unw_sword_t; typedef int32_t unw_sword_t;
@ -61,13 +61,13 @@ typedef enum
implementation of the C++ exception handling ABI. See implementation of the C++ exception handling ABI. See
_Unwind_SetGR() and _Unwind_GetGR() for details. */ _Unwind_SetGR() and _Unwind_GetGR() for details. */
UNW_HPPA_GR = 0, UNW_HPPA_GR = 0,
UNW_HPPA_RP = 2, /* return pointer */ UNW_HPPA_RP = 2, /* return pointer */
UNW_HPPA_FP = 3, /* frame pointer */ UNW_HPPA_FP = 3, /* frame pointer */
UNW_HPPA_SP = UNW_HPPA_GR + 30, UNW_HPPA_SP = UNW_HPPA_GR + 30,
UNW_HPPA_FR = UNW_HPPA_GR + 32, UNW_HPPA_FR = UNW_HPPA_GR + 32,
UNW_HPPA_IP = UNW_HPPA_FR + 32, /* instruction pointer */ UNW_HPPA_IP = UNW_HPPA_FR + 32, /* instruction pointer */
/* other "preserved" registers (fpsr etc.)... */ /* other "preserved" registers (fpsr etc.)... */
@ -76,10 +76,10 @@ typedef enum
exception-handling registers which we then alias to the actual exception-handling registers which we then alias to the actual
physical register. */ physical register. */
UNW_HPPA_EH0 = UNW_HPPA_IP + 1, /* alias for UNW_HPPA_GR + 20 */ UNW_HPPA_EH0 = UNW_HPPA_IP + 1, /* alias for UNW_HPPA_GR + 20 */
UNW_HPPA_EH1 = UNW_HPPA_EH0 + 1, /* alias for UNW_HPPA_GR + 21 */ UNW_HPPA_EH1 = UNW_HPPA_EH0 + 1, /* alias for UNW_HPPA_GR + 21 */
UNW_HPPA_EH2 = UNW_HPPA_EH1 + 1, /* alias for UNW_HPPA_GR + 22 */ UNW_HPPA_EH2 = UNW_HPPA_EH1 + 1, /* alias for UNW_HPPA_GR + 22 */
UNW_HPPA_EH3 = UNW_HPPA_EH2 + 1, /* alias for UNW_HPPA_GR + 31 */ UNW_HPPA_EH3 = UNW_HPPA_EH2 + 1, /* alias for UNW_HPPA_GR + 31 */
/* frame info (read-only) */ /* frame info (read-only) */
UNW_HPPA_CFA, UNW_HPPA_CFA,
@ -92,7 +92,7 @@ typedef enum
} }
hppa_regnum_t; hppa_regnum_t;
#define UNW_TDEP_NUM_EH_REGS 4 #define UNW_TDEP_NUM_EH_REGS 4
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -103,7 +103,7 @@ unw_tdep_save_loc_t;
/* On PA-RISC, we can directly use ucontext_t as the unwind context. */ /* On PA-RISC, we can directly use ucontext_t as the unwind context. */
typedef ucontext_t unw_tdep_context_t; typedef ucontext_t unw_tdep_context_t;
#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 32) #define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 32)
#include "libunwind-dynamic.h" #include "libunwind-dynamic.h"
@ -115,7 +115,7 @@ unw_tdep_proc_info_t;
#include "libunwind-common.h" #include "libunwind-common.h"
#define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext) #define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext)
extern int unw_tdep_getcontext (unw_tdep_context_t *); extern int unw_tdep_getcontext (unw_tdep_context_t *);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2001-2004 Hewlett-Packard Co Copyright (C) 2001-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -47,24 +47,24 @@ extern "C" {
# define UNW_GENERIC_ONLY # define UNW_GENERIC_ONLY
#endif #endif
#define UNW_TARGET ia64 #define UNW_TARGET ia64
#define UNW_TARGET_IA64 1 #define UNW_TARGET_IA64 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
require recompiling all users of this library. Stack allocation is require recompiling all users of this library. Stack allocation is
relatively cheap and unwind-state copying is relatively rare, so we relatively cheap and unwind-state copying is relatively rare, so we
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
#define UNW_TDEP_CURSOR_LEN 511 #define UNW_TDEP_CURSOR_LEN 511
/* If this bit is it indicates that the procedure saved all of ar.bsp, /* If this bit is it indicates that the procedure saved all of ar.bsp,
ar.bspstore, and ar.rnat. If, additionally, ar.bsp != saved ar.bsp, ar.bspstore, and ar.rnat. If, additionally, ar.bsp != saved ar.bsp,
then this procedure has performed a register-backing-store switch. */ then this procedure has performed a register-backing-store switch. */
#define UNW_PI_FLAG_IA64_RBS_SWITCH_BIT (UNW_PI_FLAG_FIRST_TDEP_BIT + 0) #define UNW_PI_FLAG_IA64_RBS_SWITCH_BIT (UNW_PI_FLAG_FIRST_TDEP_BIT + 0)
#define UNW_PI_FLAG_IA64_RBS_SWITCH (1 << UNW_PI_FLAG_IA64_RBS_SWITCH_BIT) #define UNW_PI_FLAG_IA64_RBS_SWITCH (1 << UNW_PI_FLAG_IA64_RBS_SWITCH_BIT)
typedef uint64_t unw_word_t; typedef uint64_t unw_word_t;
typedef int64_t unw_sword_t; typedef int64_t unw_sword_t;
@ -76,7 +76,7 @@ typedef int64_t unw_sword_t;
typedef union typedef union
{ {
struct { unw_word_t bits[2]; } raw; struct { unw_word_t bits[2]; } raw;
long double dummy; /* dummy to force 16-byte alignment */ long double dummy; /* dummy to force 16-byte alignment */
} }
unw_tdep_fpreg_t; unw_tdep_fpreg_t;
@ -92,15 +92,15 @@ typedef enum
This convention facilitates architecture-independent This convention facilitates architecture-independent
implementation of the C++ exception handling ABI. See implementation of the C++ exception handling ABI. See
_Unwind_SetGR() and _Unwind_GetGR() for details. */ _Unwind_SetGR() and _Unwind_GetGR() for details. */
UNW_IA64_GR = 0, /* general registers (r0..r127) */ UNW_IA64_GR = 0, /* general registers (r0..r127) */
UNW_IA64_GP = UNW_IA64_GR + 1, UNW_IA64_GP = UNW_IA64_GR + 1,
UNW_IA64_TP = UNW_IA64_GR + 13, UNW_IA64_TP = UNW_IA64_GR + 13,
UNW_IA64_NAT = UNW_IA64_GR + 128, /* NaT registers (nat0..nat127) */ UNW_IA64_NAT = UNW_IA64_GR + 128, /* NaT registers (nat0..nat127) */
UNW_IA64_FR = UNW_IA64_NAT + 128, /* fp registers (f0..f127) */ UNW_IA64_FR = UNW_IA64_NAT + 128, /* fp registers (f0..f127) */
UNW_IA64_AR = UNW_IA64_FR + 128, /* application registers (ar0..r127) */ UNW_IA64_AR = UNW_IA64_FR + 128, /* application registers (ar0..r127) */
UNW_IA64_AR_RSC = UNW_IA64_AR + 16, UNW_IA64_AR_RSC = UNW_IA64_AR + 16,
UNW_IA64_AR_BSP = UNW_IA64_AR + 17, UNW_IA64_AR_BSP = UNW_IA64_AR + 17,
UNW_IA64_AR_BSPSTORE = UNW_IA64_AR + 18, UNW_IA64_AR_BSPSTORE = UNW_IA64_AR + 18,
@ -115,9 +115,9 @@ typedef enum
UNW_IA64_AR_LC = UNW_IA64_AR + 65, UNW_IA64_AR_LC = UNW_IA64_AR + 65,
UNW_IA64_AR_EC = UNW_IA64_AR + 66, UNW_IA64_AR_EC = UNW_IA64_AR + 66,
UNW_IA64_BR = UNW_IA64_AR + 128, /* branch registers (b0..p7) */ UNW_IA64_BR = UNW_IA64_AR + 128, /* branch registers (b0..p7) */
UNW_IA64_RP = UNW_IA64_BR + 0, /* return pointer (rp) */ UNW_IA64_RP = UNW_IA64_BR + 0, /* return pointer (rp) */
UNW_IA64_PR = UNW_IA64_BR + 8, /* predicate registers (p0..p63) */ UNW_IA64_PR = UNW_IA64_BR + 8, /* predicate registers (p0..p63) */
UNW_IA64_CFM, UNW_IA64_CFM,
/* frame info: */ /* frame info: */
@ -133,7 +133,7 @@ typedef enum
} }
ia64_regnum_t; ia64_regnum_t;
#define UNW_TDEP_NUM_EH_REGS 4 /* r15-r18 are exception args */ #define UNW_TDEP_NUM_EH_REGS 4 /* r15-r18 are exception args */
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -150,7 +150,7 @@ unw_tdep_save_loc_t;
/* On IA-64, we can directly use ucontext_t as the unwind context. */ /* On IA-64, we can directly use ucontext_t as the unwind context. */
typedef ucontext_t unw_tdep_context_t; typedef ucontext_t unw_tdep_context_t;
#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_IA64_FR) < 128) #define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_IA64_FR) < 128)
#include "libunwind-dynamic.h" #include "libunwind-dynamic.h"
#include "libunwind-common.h" #include "libunwind-common.h"
@ -159,9 +159,9 @@ typedef ucontext_t unw_tdep_context_t;
/* In theory, we could use _Uia64_getcontext() on HP-UX as well, but /* In theory, we could use _Uia64_getcontext() on HP-UX as well, but
the benefit of doing so would be marginal given that it can't the benefit of doing so would be marginal given that it can't
support UNW_LOCAL_ONLY. */ support UNW_LOCAL_ONLY. */
# define unw_tdep_getcontext getcontext # define unw_tdep_getcontext getcontext
#else #else
# define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext) # define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext)
extern int unw_tdep_getcontext (unw_tdep_context_t *); extern int unw_tdep_getcontext (unw_tdep_context_t *);
#endif #endif
@ -171,17 +171,17 @@ typedef ucontext_t unw_tdep_context_t;
with malloc(), and should be free()d during the put_unwind_info() with malloc(), and should be free()d during the put_unwind_info()
callback. This routine is signal-safe for the local-address-space callback. This routine is signal-safe for the local-address-space
case ONLY. */ case ONLY. */
#define unw_search_ia64_unwind_table UNW_OBJ(search_unwind_table) #define unw_search_ia64_unwind_table UNW_OBJ(search_unwind_table)
extern int unw_search_ia64_unwind_table (unw_addr_space_t, unw_word_t, extern int unw_search_ia64_unwind_table (unw_addr_space_t, unw_word_t,
unw_dyn_info_t *, unw_proc_info_t *, unw_dyn_info_t *, unw_proc_info_t *,
int, void *); int, void *);
/* This is a helper routine which the get_dyn_info_list_addr() /* This is a helper routine which the get_dyn_info_list_addr()
callback can use to locate the special dynamic-info list entry in callback can use to locate the special dynamic-info list entry in
an IA-64 unwind table. If the entry exists in the table, the an IA-64 unwind table. If the entry exists in the table, the
list-address is returned. In all other cases, 0 is returned. */ list-address is returned. In all other cases, 0 is returned. */
extern unw_word_t _Uia64_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *, extern unw_word_t _Uia64_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *,
void *); void *);
/* This is a helper routine to obtain the kernel-unwind info. It is /* This is a helper routine to obtain the kernel-unwind info. It is
signal-safe. */ signal-safe. */

View file

@ -36,10 +36,10 @@ extern "C" {
# undef mips # undef mips
#endif #endif
#define UNW_TARGET mips #define UNW_TARGET mips
#define UNW_TARGET_MIPS 1 #define UNW_TARGET_MIPS 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
@ -48,7 +48,7 @@ extern "C" {
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
/* FIXME for MIPS. Too big? What do other things use for similar tasks? */ /* FIXME for MIPS. Too big? What do other things use for similar tasks? */
#define UNW_TDEP_CURSOR_LEN 4096 #define UNW_TDEP_CURSOR_LEN 4096
/* The size of a "word" varies on MIPS. This type is used for memory /* The size of a "word" varies on MIPS. This type is used for memory
addresses and register values. To allow a single library to support addresses and register values. To allow a single library to support
@ -119,7 +119,7 @@ typedef enum
} }
mips_abi_t; mips_abi_t;
#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for MIPS. */ #define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for MIPS. */
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -147,7 +147,7 @@ unw_tdep_proc_info_t;
#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) #define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext)
extern int unw_tdep_getcontext (ucontext_t *uc); extern int unw_tdep_getcontext (ucontext_t *uc);
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View file

@ -39,10 +39,10 @@ extern "C" {
#include <inttypes.h> #include <inttypes.h>
#include <ucontext.h> #include <ucontext.h>
#define UNW_TARGET ppc32 #define UNW_TARGET ppc32
#define UNW_TARGET_PPC32 1 #define UNW_TARGET_PPC32 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* /*
* This needs to be big enough to accommodate "struct cursor", while * This needs to be big enough to accommodate "struct cursor", while
@ -170,7 +170,7 @@ ppc32_regnum_t;
* passing parameters to exception handlers. * passing parameters to exception handlers.
*/ */
#define UNW_TDEP_NUM_EH_REGS 4 #define UNW_TDEP_NUM_EH_REGS 4
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -185,7 +185,7 @@ typedef ucontext_t unw_tdep_context_t;
using the "getcontext" name just because it's using libunwind. We using the "getcontext" name just because it's using libunwind. We
can't just use __getcontext() either, because that isn't exported can't just use __getcontext() either, because that isn't exported
by glibc... */ by glibc... */
#define unw_tdep_getcontext(uc) (getcontext (uc), 0) #define unw_tdep_getcontext(uc) (getcontext (uc), 0)
#include "libunwind-dynamic.h" #include "libunwind-dynamic.h"
@ -197,7 +197,7 @@ unw_tdep_proc_info_t;
#include "libunwind-common.h" #include "libunwind-common.h"
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View file

@ -39,10 +39,10 @@ extern "C" {
#include <inttypes.h> #include <inttypes.h>
#include <ucontext.h> #include <ucontext.h>
#define UNW_TARGET ppc64 #define UNW_TARGET ppc64
#define UNW_TARGET_PPC64 1 #define UNW_TARGET_PPC64 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* /*
* This needs to be big enough to accommodate "struct cursor", while * This needs to be big enough to accommodate "struct cursor", while
@ -234,7 +234,7 @@ ppc64_abi_t;
* passing parameters to exception handlers. * passing parameters to exception handlers.
*/ */
#define UNW_TDEP_NUM_EH_REGS 4 #define UNW_TDEP_NUM_EH_REGS 4
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -249,7 +249,7 @@ typedef ucontext_t unw_tdep_context_t;
using the "getcontext" name just because it's using libunwind. We using the "getcontext" name just because it's using libunwind. We
can't just use __getcontext() either, because that isn't exported can't just use __getcontext() either, because that isn't exported
by glibc... */ by glibc... */
#define unw_tdep_getcontext(uc) (getcontext (uc), 0) #define unw_tdep_getcontext(uc) (getcontext (uc), 0)
#include "libunwind-dynamic.h" #include "libunwind-dynamic.h"
@ -261,7 +261,7 @@ unw_tdep_proc_info_t;
#include "libunwind-common.h" #include "libunwind-common.h"
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -40,18 +40,18 @@ extern "C" {
extern void *_UPT_create (pid_t); extern void *_UPT_create (pid_t);
extern void _UPT_destroy (void *); extern void _UPT_destroy (void *);
extern int _UPT_find_proc_info (unw_addr_space_t, unw_word_t, extern int _UPT_find_proc_info (unw_addr_space_t, unw_word_t,
unw_proc_info_t *, int, void *); unw_proc_info_t *, int, void *);
extern void _UPT_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *); extern void _UPT_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *);
extern int _UPT_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *, extern int _UPT_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *,
void *); void *);
extern int _UPT_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int, extern int _UPT_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int,
void *); void *);
extern int _UPT_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *, extern int _UPT_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *,
int, void *); int, void *);
extern int _UPT_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, extern int _UPT_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *,
int, void *); int, void *);
extern int _UPT_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t, extern int _UPT_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t,
unw_word_t *, void *); unw_word_t *, void *);
extern int _UPT_resume (unw_addr_space_t, unw_cursor_t *, void *); extern int _UPT_resume (unw_addr_space_t, unw_cursor_t *, void *);
extern unw_accessors_t _UPT_accessors; extern unw_accessors_t _UPT_accessors;

View file

@ -34,10 +34,10 @@ extern "C" {
#include <stddef.h> #include <stddef.h>
#include <ucontext.h> #include <ucontext.h>
#define UNW_TARGET sh #define UNW_TARGET sh
#define UNW_TARGET_SH 1 #define UNW_TARGET_SH 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
@ -45,7 +45,7 @@ extern "C" {
relatively cheap and unwind-state copying is relatively rare, so we relatively cheap and unwind-state copying is relatively rare, so we
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
#define UNW_TDEP_CURSOR_LEN 4096 #define UNW_TDEP_CURSOR_LEN 4096
typedef uint32_t unw_word_t; typedef uint32_t unw_word_t;
typedef int32_t unw_sword_t; typedef int32_t unw_sword_t;
@ -82,11 +82,11 @@ typedef enum
} }
sh_regnum_t; sh_regnum_t;
#define UNW_TDEP_NUM_EH_REGS 2 #define UNW_TDEP_NUM_EH_REGS 2
typedef ucontext_t unw_tdep_context_t; typedef ucontext_t unw_tdep_context_t;
#define unw_tdep_getcontext(uc) (getcontext (uc), 0) #define unw_tdep_getcontext(uc) (getcontext (uc), 0)
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -104,7 +104,7 @@ unw_tdep_proc_info_t;
#include "libunwind-common.h" #include "libunwind-common.h"
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2002-2004 Hewlett-Packard Co Copyright (C) 2002-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -34,17 +34,17 @@ extern "C" {
#include <inttypes.h> #include <inttypes.h>
#include <ucontext.h> #include <ucontext.h>
#define UNW_TARGET x86 #define UNW_TARGET x86
#define UNW_TARGET_X86 1 #define UNW_TARGET_X86 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
require recompiling all users of this library. Stack allocation is require recompiling all users of this library. Stack allocation is
relatively cheap and unwind-state copying is relatively rare, so we relatively cheap and unwind-state copying is relatively rare, so we
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
#define UNW_TDEP_CURSOR_LEN 127 #define UNW_TDEP_CURSOR_LEN 127
typedef uint32_t unw_word_t; typedef uint32_t unw_word_t;
typedef int32_t unw_sword_t; typedef int32_t unw_sword_t;
@ -72,78 +72,78 @@ typedef enum
DWARF, but that doesn't work because the libunwind requires DWARF, but that doesn't work because the libunwind requires
that the exception argument registers be consecutive, which the that the exception argument registers be consecutive, which the
wouldn't be with the DWARF numbering. */ wouldn't be with the DWARF numbering. */
UNW_X86_EAX, /* scratch (exception argument 1) */ UNW_X86_EAX, /* scratch (exception argument 1) */
UNW_X86_EDX, /* scratch (exception argument 2) */ UNW_X86_EDX, /* scratch (exception argument 2) */
UNW_X86_ECX, /* scratch */ UNW_X86_ECX, /* scratch */
UNW_X86_EBX, /* preserved */ UNW_X86_EBX, /* preserved */
UNW_X86_ESI, /* preserved */ UNW_X86_ESI, /* preserved */
UNW_X86_EDI, /* preserved */ UNW_X86_EDI, /* preserved */
UNW_X86_EBP, /* (optional) frame-register */ UNW_X86_EBP, /* (optional) frame-register */
UNW_X86_ESP, /* (optional) frame-register */ UNW_X86_ESP, /* (optional) frame-register */
UNW_X86_EIP, /* frame-register */ UNW_X86_EIP, /* frame-register */
UNW_X86_EFLAGS, /* scratch (except for "direction", which is fixed */ UNW_X86_EFLAGS, /* scratch (except for "direction", which is fixed */
UNW_X86_TRAPNO, /* scratch */ UNW_X86_TRAPNO, /* scratch */
/* MMX/stacked-fp registers */ /* MMX/stacked-fp registers */
UNW_X86_ST0, /* fp return value */ UNW_X86_ST0, /* fp return value */
UNW_X86_ST1, /* scratch */ UNW_X86_ST1, /* scratch */
UNW_X86_ST2, /* scratch */ UNW_X86_ST2, /* scratch */
UNW_X86_ST3, /* scratch */ UNW_X86_ST3, /* scratch */
UNW_X86_ST4, /* scratch */ UNW_X86_ST4, /* scratch */
UNW_X86_ST5, /* scratch */ UNW_X86_ST5, /* scratch */
UNW_X86_ST6, /* scratch */ UNW_X86_ST6, /* scratch */
UNW_X86_ST7, /* scratch */ UNW_X86_ST7, /* scratch */
UNW_X86_FCW, /* scratch */ UNW_X86_FCW, /* scratch */
UNW_X86_FSW, /* scratch */ UNW_X86_FSW, /* scratch */
UNW_X86_FTW, /* scratch */ UNW_X86_FTW, /* scratch */
UNW_X86_FOP, /* scratch */ UNW_X86_FOP, /* scratch */
UNW_X86_FCS, /* scratch */ UNW_X86_FCS, /* scratch */
UNW_X86_FIP, /* scratch */ UNW_X86_FIP, /* scratch */
UNW_X86_FEA, /* scratch */ UNW_X86_FEA, /* scratch */
UNW_X86_FDS, /* scratch */ UNW_X86_FDS, /* scratch */
/* SSE registers */ /* SSE registers */
UNW_X86_XMM0_lo, /* scratch */ UNW_X86_XMM0_lo, /* scratch */
UNW_X86_XMM0_hi, /* scratch */ UNW_X86_XMM0_hi, /* scratch */
UNW_X86_XMM1_lo, /* scratch */ UNW_X86_XMM1_lo, /* scratch */
UNW_X86_XMM1_hi, /* scratch */ UNW_X86_XMM1_hi, /* scratch */
UNW_X86_XMM2_lo, /* scratch */ UNW_X86_XMM2_lo, /* scratch */
UNW_X86_XMM2_hi, /* scratch */ UNW_X86_XMM2_hi, /* scratch */
UNW_X86_XMM3_lo, /* scratch */ UNW_X86_XMM3_lo, /* scratch */
UNW_X86_XMM3_hi, /* scratch */ UNW_X86_XMM3_hi, /* scratch */
UNW_X86_XMM4_lo, /* scratch */ UNW_X86_XMM4_lo, /* scratch */
UNW_X86_XMM4_hi, /* scratch */ UNW_X86_XMM4_hi, /* scratch */
UNW_X86_XMM5_lo, /* scratch */ UNW_X86_XMM5_lo, /* scratch */
UNW_X86_XMM5_hi, /* scratch */ UNW_X86_XMM5_hi, /* scratch */
UNW_X86_XMM6_lo, /* scratch */ UNW_X86_XMM6_lo, /* scratch */
UNW_X86_XMM6_hi, /* scratch */ UNW_X86_XMM6_hi, /* scratch */
UNW_X86_XMM7_lo, /* scratch */ UNW_X86_XMM7_lo, /* scratch */
UNW_X86_XMM7_hi, /* scratch */ UNW_X86_XMM7_hi, /* scratch */
UNW_X86_MXCSR, /* scratch */ UNW_X86_MXCSR, /* scratch */
/* segment registers */ /* segment registers */
UNW_X86_GS, /* special */ UNW_X86_GS, /* special */
UNW_X86_FS, /* special */ UNW_X86_FS, /* special */
UNW_X86_ES, /* special */ UNW_X86_ES, /* special */
UNW_X86_DS, /* special */ UNW_X86_DS, /* special */
UNW_X86_SS, /* special */ UNW_X86_SS, /* special */
UNW_X86_CS, /* special */ UNW_X86_CS, /* special */
UNW_X86_TSS, /* special */ UNW_X86_TSS, /* special */
UNW_X86_LDT, /* special */ UNW_X86_LDT, /* special */
/* frame info (read-only) */ /* frame info (read-only) */
UNW_X86_CFA, UNW_X86_CFA,
UNW_X86_XMM0, /* scratch */ UNW_X86_XMM0, /* scratch */
UNW_X86_XMM1, /* scratch */ UNW_X86_XMM1, /* scratch */
UNW_X86_XMM2, /* scratch */ UNW_X86_XMM2, /* scratch */
UNW_X86_XMM3, /* scratch */ UNW_X86_XMM3, /* scratch */
UNW_X86_XMM4, /* scratch */ UNW_X86_XMM4, /* scratch */
UNW_X86_XMM5, /* scratch */ UNW_X86_XMM5, /* scratch */
UNW_X86_XMM6, /* scratch */ UNW_X86_XMM6, /* scratch */
UNW_X86_XMM7, /* scratch */ UNW_X86_XMM7, /* scratch */
UNW_TDEP_LAST_REG = UNW_X86_XMM7, UNW_TDEP_LAST_REG = UNW_X86_XMM7,
@ -153,7 +153,7 @@ typedef enum
} }
x86_regnum_t; x86_regnum_t;
#define UNW_TDEP_NUM_EH_REGS 2 /* eax and edx are exception args */ #define UNW_TDEP_NUM_EH_REGS 2 /* eax and edx are exception args */
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -174,10 +174,10 @@ unw_tdep_proc_info_t;
#include "libunwind-common.h" #include "libunwind-common.h"
#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) #define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext)
extern int unw_tdep_getcontext (unw_tdep_context_t *); extern int unw_tdep_getcontext (unw_tdep_context_t *);
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2002-2004 Hewlett-Packard Co Copyright (C) 2002-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com> Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@ -36,17 +36,17 @@ extern "C" {
#include <inttypes.h> #include <inttypes.h>
#include <ucontext.h> #include <ucontext.h>
#define UNW_TARGET x86_64 #define UNW_TARGET x86_64
#define UNW_TARGET_X86_64 1 #define UNW_TARGET_X86_64 1
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
/* This needs to be big enough to accommodate "struct cursor", while /* This needs to be big enough to accommodate "struct cursor", while
leaving some slack for future expansion. Changing this value will leaving some slack for future expansion. Changing this value will
require recompiling all users of this library. Stack allocation is require recompiling all users of this library. Stack allocation is
relatively cheap and unwind-state copying is relatively rare, so we relatively cheap and unwind-state copying is relatively rare, so we
want to err on making it rather too big than too small. */ want to err on making it rather too big than too small. */
#define UNW_TDEP_CURSOR_LEN 127 #define UNW_TDEP_CURSOR_LEN 127
typedef uint64_t unw_word_t; typedef uint64_t unw_word_t;
typedef int64_t unw_sword_t; typedef int64_t unw_sword_t;
@ -106,7 +106,7 @@ typedef enum
} }
x86_64_regnum_t; x86_64_regnum_t;
#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ #define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */
typedef struct unw_tdep_save_loc typedef struct unw_tdep_save_loc
{ {
@ -128,8 +128,8 @@ unw_tdep_proc_info_t;
#include "libunwind-dynamic.h" #include "libunwind-dynamic.h"
#include "libunwind-common.h" #include "libunwind-common.h"
#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) #define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext)
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_getcontext (unw_tdep_context_t *); extern int unw_tdep_getcontext (unw_tdep_context_t *);
extern int unw_tdep_is_fpreg (int); extern int unw_tdep_is_fpreg (int);

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2001-2005 Hewlett-Packard Co Copyright (C) 2001-2005 Hewlett-Packard Co
Copyright (C) 2007 David Mosberger-Tang Copyright (C) 2007 David Mosberger-Tang
Contributed by David Mosberger-Tang <dmosberger@gmail.com> Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind. This file is part of libunwind.
@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* Platform-independent libunwind-internal declarations. */ /* Platform-independent libunwind-internal declarations. */
#include <sys/types.h> /* HP-UX needs this before include of pthread.h */ #include <sys/types.h> /* HP-UX needs this before include of pthread.h */
#include <assert.h> #include <assert.h>
#include <libunwind.h> #include <libunwind.h>
@ -70,8 +70,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#elif defined(HAVE_SYS_ENDIAN_H) #elif defined(HAVE_SYS_ENDIAN_H)
# include <sys/endian.h> # include <sys/endian.h>
#else #else
# define __LITTLE_ENDIAN 1234 # define __LITTLE_ENDIAN 1234
# define __BIG_ENDIAN 4321 # define __BIG_ENDIAN 4321
# if defined(__hpux) # if defined(__hpux)
# define __BYTE_ORDER __BIG_ENDIAN # define __BYTE_ORDER __BIG_ENDIAN
# elif defined(__QNX__) # elif defined(__QNX__)
@ -94,9 +94,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#endif #endif
#ifdef DEBUG #ifdef DEBUG
# define UNW_DEBUG 1 # define UNW_DEBUG 1
#else #else
# define UNW_DEBUG 0 # define UNW_DEBUG 0
#endif #endif
/* Make it easy to write thread-safe code which may or may not be /* Make it easy to write thread-safe code which may or may not be
@ -108,12 +108,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#pragma weak pthread_mutex_lock #pragma weak pthread_mutex_lock
#pragma weak pthread_mutex_unlock #pragma weak pthread_mutex_unlock
#define mutex_init(l) \ #define mutex_init(l) \
(pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0) (pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0)
#define mutex_lock(l) \ #define mutex_lock(l) \
(pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0) (pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0)
#define mutex_unlock(l) \ #define mutex_unlock(l) \
(pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0) (pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0)
#ifdef HAVE_ATOMIC_OPS_H #ifdef HAVE_ATOMIC_OPS_H
# include <atomic_ops.h> # include <atomic_ops.h>
@ -130,8 +130,8 @@ cmpxchg_ptr (void *addr, void *old, void *new)
u.vp = addr; u.vp = addr;
return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new); return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new);
} }
# define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr) # define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr)
# define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value) # define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value)
/* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */ /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */
# if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) # if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
# define HAVE_CMPXCHG # define HAVE_CMPXCHG
@ -154,14 +154,14 @@ cmpxchg_ptr (void *addr, void *old, void *new)
u.vp = addr; u.vp = addr;
return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new); return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new);
} }
# define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1) # define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1)
# define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value) # define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value)
# define HAVE_CMPXCHG # define HAVE_CMPXCHG
# define HAVE_FETCH_AND_ADD # define HAVE_FETCH_AND_ADD
#endif #endif
#define atomic_read(ptr) (*(ptr)) #define atomic_read(ptr) (*(ptr))
#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn)) #define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn) #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
#define unwi_full_mask UNWI_ARCH_OBJ(full_mask) #define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
@ -195,85 +195,85 @@ static inline void mark_as_used(void *v UNUSED) {
#define define_lock(name) \ #define define_lock(name) \
pthread_mutex_t name = UNW_PTHREAD_MUTEX_INITIALIZER pthread_mutex_t name = UNW_PTHREAD_MUTEX_INITIALIZER
#define lock_init(l) mutex_init (l) #define lock_init(l) mutex_init (l)
#define lock_acquire(l,m) \ #define lock_acquire(l,m) \
do { \ do { \
SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \ SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \
mutex_lock (l); \ mutex_lock (l); \
} while (0) } while (0)
#define lock_release(l,m) \ #define lock_release(l,m) \
do { \ do { \
mutex_unlock (l); \ mutex_unlock (l); \
SIGPROCMASK (SIG_SETMASK, &(m), NULL); \ SIGPROCMASK (SIG_SETMASK, &(m), NULL); \
} while (0) } while (0)
#define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */ #define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */
#ifndef MAP_ANONYMOUS #ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS MAP_ANON # define MAP_ANONYMOUS MAP_ANON
#endif #endif
#define GET_MEMORY(mem, size) \ #define GET_MEMORY(mem, size) \
do { \ do { \
/* Hopefully, mmap() goes straight through to a system call stub... */ \ /* Hopefully, mmap() goes straight through to a system call stub... */ \
mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \ mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
if (mem == MAP_FAILED) \ if (mem == MAP_FAILED) \
mem = NULL; \ mem = NULL; \
} while (0) } while (0)
#define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info) #define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info)
#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info) #define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info)
#define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info) #define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info)
#define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info) #define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info)
#define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info) #define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info)
#define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache) #define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache)
extern int unwi_find_dynamic_proc_info (unw_addr_space_t as, extern int unwi_find_dynamic_proc_info (unw_addr_space_t as,
unw_word_t ip, unw_word_t ip,
unw_proc_info_t *pi, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as, extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as,
unw_word_t ip, unw_word_t ip,
unw_proc_info_t *pi, unw_proc_info_t *pi,
unw_dyn_info_t *di, unw_dyn_info_t *di,
int need_unwind_info, int need_unwind_info,
void *arg); void *arg);
extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as, extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg); unw_proc_info_t *pi, void *arg);
/* These handle the remote (cross-address-space) case of accessing /* These handle the remote (cross-address-space) case of accessing
dynamic unwind info. */ dynamic unwind info. */
extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as, extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as,
unw_word_t ip, unw_word_t ip,
unw_proc_info_t *pi, unw_proc_info_t *pi,
int need_unwind_info, int need_unwind_info,
void *arg); void *arg);
extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, unw_proc_info_t *pi,
void *arg); void *arg);
extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg); extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg);
extern unw_dyn_info_list_t _U_dyn_info_list; extern unw_dyn_info_list_t _U_dyn_info_list;
extern pthread_mutex_t _U_dyn_info_list_lock; extern pthread_mutex_t _U_dyn_info_list_lock;
#if UNW_DEBUG #if UNW_DEBUG
#define unwi_debug_level UNWI_ARCH_OBJ(debug_level) #define unwi_debug_level UNWI_ARCH_OBJ(debug_level)
extern long unwi_debug_level; extern long unwi_debug_level;
# include <stdio.h> # include <stdio.h>
# define Debug(level,format...) \ # define Debug(level,format...) \
do { \ do { \
if (unwi_debug_level >= level) \ if (unwi_debug_level >= level) \
{ \ { \
int _n = level; \ int _n = level; \
if (_n > 16) \ if (_n > 16) \
_n = 16; \ _n = 16; \
fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \ fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \
fprintf (stderr, format); \ fprintf (stderr, format); \
} \ } \
} while (0) } while (0)
# define Dprintf(format...) fprintf (stderr, format) # define Dprintf(format...) fprintf (stderr, format)
#else #else
# define Debug(level,format...) # define Debug(level,format...)
# define Dprintf(format...) # define Dprintf(format...)
@ -285,17 +285,17 @@ print_error (const char *string)
return write (2, string, strlen (string)); return write (2, string, strlen (string));
} }
#define mi_init UNWI_ARCH_OBJ(mi_init) #define mi_init UNWI_ARCH_OBJ(mi_init)
extern void mi_init (void); /* machine-independent initializations */ extern void mi_init (void); /* machine-independent initializations */
extern unw_word_t _U_dyn_info_list_addr (void); extern unw_word_t _U_dyn_info_list_addr (void);
/* This is needed/used by ELF targets only. */ /* This is needed/used by ELF targets only. */
struct elf_image struct elf_image
{ {
void *image; /* pointer to mmap'd image */ void *image; /* pointer to mmap'd image */
size_t size; /* (file-) size of the image */ size_t size; /* (file-) size of the image */
}; };
struct elf_dyn_info struct elf_dyn_info
@ -335,21 +335,21 @@ static inline void invalidate_edi (struct elf_dyn_info *edi)
/* Define GNU and processor specific values for the Phdr p_type field in case /* Define GNU and processor specific values for the Phdr p_type field in case
they aren't defined by <elf.h>. */ they aren't defined by <elf.h>. */
#ifndef PT_GNU_EH_FRAME #ifndef PT_GNU_EH_FRAME
# define PT_GNU_EH_FRAME 0x6474e550 # define PT_GNU_EH_FRAME 0x6474e550
#endif /* !PT_GNU_EH_FRAME */ #endif /* !PT_GNU_EH_FRAME */
#ifndef PT_ARM_EXIDX #ifndef PT_ARM_EXIDX
# define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */ # define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */
#endif /* !PT_ARM_EXIDX */ #endif /* !PT_ARM_EXIDX */
#include "tdep/libunwind_i.h" #include "tdep/libunwind_i.h"
#ifndef tdep_get_func_addr #ifndef tdep_get_func_addr
# define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0) # define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0)
#endif #endif
#ifndef DWARF_VAL_LOC #ifndef DWARF_VAL_LOC
# define DWARF_IS_VAL_LOC(l) 0 # define DWARF_IS_VAL_LOC(l) 0
# define DWARF_VAL_LOC(c,v) DWARF_NULL_LOC # define DWARF_VAL_LOC(c,v) DWARF_NULL_LOC
#endif #endif
#define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) #define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL))

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2002-2003 Hewlett-Packard Co Copyright (C) 2002-2003 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -51,23 +51,23 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "libunwind_i.h" #include "libunwind_i.h"
#define sos_alloc(s) UNWI_ARCH_OBJ(_sos_alloc)(s) #define sos_alloc(s) UNWI_ARCH_OBJ(_sos_alloc)(s)
#define mempool_init(p,s,r) UNWI_ARCH_OBJ(_mempool_init)(p,s,r) #define mempool_init(p,s,r) UNWI_ARCH_OBJ(_mempool_init)(p,s,r)
#define mempool_alloc(p) UNWI_ARCH_OBJ(_mempool_alloc)(p) #define mempool_alloc(p) UNWI_ARCH_OBJ(_mempool_alloc)(p)
#define mempool_free(p,o) UNWI_ARCH_OBJ(_mempool_free)(p,o) #define mempool_free(p,o) UNWI_ARCH_OBJ(_mempool_free)(p,o)
/* The mempool structure should be treated as an opaque object. It's /* The mempool structure should be treated as an opaque object. It's
declared here only to enable static allocation of mempools. */ declared here only to enable static allocation of mempools. */
struct mempool struct mempool
{ {
pthread_mutex_t lock; pthread_mutex_t lock;
size_t obj_size; /* object size (rounded up for alignment) */ size_t obj_size; /* object size (rounded up for alignment) */
size_t chunk_size; /* allocation granularity */ size_t chunk_size; /* allocation granularity */
unsigned int reserve; /* minimum (desired) size of the free-list */ unsigned int reserve; /* minimum (desired) size of the free-list */
unsigned int num_free; /* number of objects on the free-list */ unsigned int num_free; /* number of objects on the free-list */
struct object struct object
{ {
struct object *next; struct object *next;
} }
*free_list; *free_list;
}; };
@ -82,7 +82,7 @@ extern void *sos_alloc (size_t size);
tight memory situations. If it is zero, mempool attempts to pick a tight memory situations. If it is zero, mempool attempts to pick a
reasonable default value. */ reasonable default value. */
extern void mempool_init (struct mempool *pool, extern void mempool_init (struct mempool *pool,
size_t obj_size, size_t reserve); size_t obj_size, size_t reserve);
extern void *mempool_alloc (struct mempool *pool); extern void *mempool_alloc (struct mempool *pool);
extern void mempool_free (struct mempool *pool, void *object); extern void mempool_free (struct mempool *pool, void *object);

View file

@ -9,7 +9,7 @@
static inline int static inline int
fetch8 (unw_addr_space_t as, unw_accessors_t *a, fetch8 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int8_t *valp, void *arg) unw_word_t *addr, int8_t *valp, void *arg)
{ {
*valp = *(int8_t *) (uintptr_t) *addr; *valp = *(int8_t *) (uintptr_t) *addr;
*addr += 1; *addr += 1;
@ -18,7 +18,7 @@ fetch8 (unw_addr_space_t as, unw_accessors_t *a,
static inline int static inline int
fetch16 (unw_addr_space_t as, unw_accessors_t *a, fetch16 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int16_t *valp, void *arg) unw_word_t *addr, int16_t *valp, void *arg)
{ {
*valp = *(int16_t *) (uintptr_t) *addr; *valp = *(int16_t *) (uintptr_t) *addr;
*addr += 2; *addr += 2;
@ -27,7 +27,7 @@ fetch16 (unw_addr_space_t as, unw_accessors_t *a,
static inline int static inline int
fetch32 (unw_addr_space_t as, unw_accessors_t *a, fetch32 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int32_t *valp, void *arg) unw_word_t *addr, int32_t *valp, void *arg)
{ {
*valp = *(int32_t *) (uintptr_t) *addr; *valp = *(int32_t *) (uintptr_t) *addr;
*addr += 4; *addr += 4;
@ -36,7 +36,7 @@ fetch32 (unw_addr_space_t as, unw_accessors_t *a,
static inline int static inline int
fetchw (unw_addr_space_t as, unw_accessors_t *a, fetchw (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, unw_word_t *valp, void *arg) unw_word_t *addr, unw_word_t *valp, void *arg)
{ {
*valp = *(unw_word_t *) (uintptr_t) *addr; *valp = *(unw_word_t *) (uintptr_t) *addr;
*addr += sizeof (unw_word_t); *addr += sizeof (unw_word_t);
@ -45,11 +45,11 @@ fetchw (unw_addr_space_t as, unw_accessors_t *a,
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
#define WSIZE (sizeof (unw_word_t)) #define WSIZE (sizeof (unw_word_t))
static inline int static inline int
fetch8 (unw_addr_space_t as, unw_accessors_t *a, fetch8 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int8_t *valp, void *arg) unw_word_t *addr, int8_t *valp, void *arg)
{ {
unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
int ret; int ret;
@ -69,7 +69,7 @@ fetch8 (unw_addr_space_t as, unw_accessors_t *a,
static inline int static inline int
fetch16 (unw_addr_space_t as, unw_accessors_t *a, fetch16 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int16_t *valp, void *arg) unw_word_t *addr, int16_t *valp, void *arg)
{ {
unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
int ret; int ret;
@ -91,7 +91,7 @@ fetch16 (unw_addr_space_t as, unw_accessors_t *a,
static inline int static inline int
fetch32 (unw_addr_space_t as, unw_accessors_t *a, fetch32 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int32_t *valp, void *arg) unw_word_t *addr, int32_t *valp, void *arg)
{ {
unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
int ret; int ret;
@ -113,7 +113,7 @@ fetch32 (unw_addr_space_t as, unw_accessors_t *a,
static inline int static inline int
fetchw (unw_addr_space_t as, unw_accessors_t *a, fetchw (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, unw_word_t *valp, void *arg) unw_word_t *addr, unw_word_t *valp, void *arg)
{ {
int ret; int ret;

View file

@ -29,22 +29,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* This matches the value udes by GCC (see /* This matches the value udes by GCC (see
gcc/config/aarch64/aarch64.h:DWARF_FRAME_REGISTERS. */ gcc/config/aarch64/aarch64.h:DWARF_FRAME_REGISTERS. */
#define DWARF_NUM_PRESERVED_REGS 97 #define DWARF_NUM_PRESERVED_REGS 97
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) 0 #define dwarf_is_big_endian(addr_space) 0
#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_AARCH64_V31) ? (reg) : 0) #define dwarf_to_unw_regnum(reg) (((reg) <= UNW_AARCH64_V31) ? (reg) : 0)
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -27,7 +27,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* FIXME for AArch64 */ /* FIXME for AArch64 */
#define JB_SP 13 #define JB_SP 13
#define JB_RP 14 #define JB_RP 14
#define JB_MASK_SAVED 15 #define JB_MASK_SAVED 15
#define JB_MASK 16 #define JB_MASK 16

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2001-2005 Hewlett-Packard Co Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Copyright (C) 2013 Linaro Limited Copyright (C) 2013 Linaro Limited
This file is part of libunwind. This file is part of libunwind.
@ -84,7 +84,7 @@ struct unw_addr_space
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
}; };
@ -93,7 +93,7 @@ struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
unw_tdep_frame_t frame_info; /* quick tracing assist info */ unw_tdep_frame_t frame_info; /* quick tracing assist info */
enum enum
{ {
@ -261,21 +261,21 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) #define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace)
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_OBJ(uc_addr) #define tdep_uc_addr UNW_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) #define tdep_stash_frame UNW_OBJ(tdep_stash_frame)
#define tdep_trace UNW_OBJ(tdep_trace) #define tdep_trace UNW_OBJ(tdep_trace)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
@ -300,19 +300,19 @@ extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 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, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n);
extern void tdep_stash_frame (struct dwarf_cursor *c, extern void tdep_stash_frame (struct dwarf_cursor *c,
struct dwarf_reg_state *rs); struct dwarf_reg_state *rs);
extern int tdep_getcontext_trace (unw_tdep_context_t *); extern int tdep_getcontext_trace (unw_tdep_context_t *);
#endif /* AARCH64_LIBUNWIND_I_H */ #endif /* AARCH64_LIBUNWIND_I_H */

View file

@ -28,22 +28,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not /* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not
explicitly defined. */ explicitly defined. */
#define DWARF_NUM_PRESERVED_REGS 128 #define DWARF_NUM_PRESERVED_REGS 128
#define dwarf_to_unw_regnum(reg) (((reg) < 16) ? (reg) : 0) #define dwarf_to_unw_regnum(reg) (((reg) < 16) ? (reg) : 0)
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) 0 #define dwarf_is_big_endian(addr_space) 0
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -44,9 +44,9 @@ struct arm_exbuf_data
uint32_t data; uint32_t data;
}; };
#define arm_exidx_extract UNW_OBJ(arm_exidx_extract) #define arm_exidx_extract UNW_OBJ(arm_exidx_extract)
#define arm_exidx_decode UNW_OBJ(arm_exidx_decode) #define arm_exidx_decode UNW_OBJ(arm_exidx_decode)
#define arm_exidx_apply_cmd UNW_OBJ(arm_exidx_apply_cmd) #define arm_exidx_apply_cmd UNW_OBJ(arm_exidx_apply_cmd)
int arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf); int arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf);
int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c); int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c);

View file

@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* FIXME for ARM! */ /* FIXME for ARM! */
#define JB_SP 4 #define JB_SP 4
#define JB_RP 5 #define JB_RP 5
#define JB_MASK_SAVED 6 #define JB_MASK_SAVED 6
#define JB_MASK 7 #define JB_MASK 7

View file

@ -68,17 +68,17 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
}; };
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
unw_tdep_frame_t frame_info; /* quick tracing assist info */ unw_tdep_frame_t frame_info; /* quick tracing assist info */
enum enum
{ {
@ -95,18 +95,18 @@ struct cursor
int validate; int validate;
}; };
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -145,18 +145,18 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
} }
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -170,15 +170,15 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
0, c->as_arg)) < 0) 0, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
c->as_arg); c->as_arg);
} }
static inline int static inline int
@ -193,15 +193,15 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
1, c->as_arg)) < 0) 1, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
1, c->as_arg); 1, c->as_arg);
} }
static inline int static inline int
@ -218,10 +218,10 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -238,74 +238,74 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
#define arm_find_proc_info UNW_OBJ(find_proc_info) #define arm_find_proc_info UNW_OBJ(find_proc_info)
#define arm_put_unwind_info UNW_OBJ(put_unwind_info) #define arm_put_unwind_info UNW_OBJ(put_unwind_info)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table UNW_OBJ(search_unwind_table) #define tdep_search_unwind_table UNW_OBJ(search_unwind_table)
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) #define tdep_stash_frame UNW_OBJ(tdep_stash_frame)
#define tdep_trace UNW_OBJ(tdep_trace) #define tdep_trace UNW_OBJ(tdep_trace)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
arm_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ arm_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
arm_put_unwind_info((as), (pi), (arg)) arm_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_big_endian(as) ((as)->big_endian) #define tdep_big_endian(as) ((as)->big_endian)
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info, unw_proc_info_t *pi, int need_unwind_info,
void *arg); void *arg);
extern void arm_put_unwind_info (unw_addr_space_t as, extern void arm_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg); unw_proc_info_t *pi, void *arg);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 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, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n);
extern void tdep_stash_frame (struct dwarf_cursor *c, extern void tdep_stash_frame (struct dwarf_cursor *c,
struct dwarf_reg_state *rs); struct dwarf_reg_state *rs);
/* unwinding method selection support */ /* unwinding method selection support */
#define UNW_ARM_METHOD_ALL 0xFF #define UNW_ARM_METHOD_ALL 0xFF

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2004 Hewlett-Packard Development Company, L.P. Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -27,26 +27,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define dwarf_config_h #define dwarf_config_h
/* See DWARF_FRAME_REGNUM() macro in gcc/config/pa/pa32-regs.h: */ /* See DWARF_FRAME_REGNUM() macro in gcc/config/pa/pa32-regs.h: */
#define dwarf_to_unw_regnum(reg) \ #define dwarf_to_unw_regnum(reg) \
(((reg) < DWARF_NUM_PRESERVED_REGS) ? (reg) : 0) (((reg) < DWARF_NUM_PRESERVED_REGS) ? (reg) : 0)
/* This matches the value used by GCC (see /* This matches the value used by GCC (see
gcc/config/pa/pa32-regs.h:FIRST_PSEUDO_REGISTER), which leaves gcc/config/pa/pa32-regs.h:FIRST_PSEUDO_REGISTER), which leaves
plenty of room for expansion. */ plenty of room for expansion. */
#define DWARF_NUM_PRESERVED_REGS 89 #define DWARF_NUM_PRESERVED_REGS 89
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) 1 #define dwarf_is_big_endian(addr_space) 1
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see X86_LOC_TYPE_* macros. */ unw_word_t type; /* see X86_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -26,8 +26,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ /* Use glibc's jump-buffer indices; NPTL peeks at SP: */
#ifndef JB_SP #ifndef JB_SP
# define JB_SP 19 # define JB_SP 19
#endif #endif
#define JB_RP 20 #define JB_RP 20
#define JB_MASK_SAVED 21 #define JB_MASK_SAVED 21
#define JB_MASK 22 #define JB_MASK 22

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003-2005 Hewlett-Packard Co Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -51,39 +51,39 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
}; };
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
/* Format of sigcontext structure and address at which it is /* Format of sigcontext structure and address at which it is
stored: */ stored: */
enum enum
{ {
HPPA_SCF_NONE, /* no signal frame encountered */ HPPA_SCF_NONE, /* no signal frame encountered */
HPPA_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ HPPA_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
} }
sigcontext_format; sigcontext_format;
unw_word_t sigcontext_addr; unw_word_t sigcontext_addr;
}; };
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -122,18 +122,18 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
} }
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -147,15 +147,15 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
0, c->as_arg)) < 0) 0, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
c->as_arg); c->as_arg);
} }
static inline int static inline int
@ -170,15 +170,15 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
1, c->as_arg)) < 0) 1, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
1, c->as_arg); 1, c->as_arg);
} }
static inline int static inline int
@ -195,10 +195,10 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -215,63 +215,63 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame(c,rs) do {} while(0) #define tdep_stash_frame(c,rs) do {} while(0)
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) #define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
dwarf_put_unwind_info((as), (pi), (arg)) dwarf_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_big_endian(as) 1 #define tdep_big_endian(as) 1
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 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, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg); extern void *tdep_uc_addr (ucontext_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
#endif /* HPPA_LIBUNWIND_I_H */ #endif /* HPPA_LIBUNWIND_I_H */

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -25,8 +25,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* Use glibc's jump-buffer indices; NPTL peeks at SP and BSP: */ /* Use glibc's jump-buffer indices; NPTL peeks at SP and BSP: */
#define JB_SP 0 #define JB_SP 0
#define JB_RP 8 #define JB_RP 8
#define JB_BSP 17 #define JB_BSP 17
#define JB_MASK_SAVED 70 #define JB_MASK_SAVED 70
#define JB_MASK 71 #define JB_MASK 71

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2001-2005 Hewlett-Packard Co Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -45,11 +45,11 @@ enum ia64_pregnum
IA64_REG_PRI_UNAT_MEM, IA64_REG_PRI_UNAT_MEM,
/* memory stack (order matters: see build_script() */ /* memory stack (order matters: see build_script() */
IA64_REG_PSP, /* previous memory stack pointer */ IA64_REG_PSP, /* previous memory stack pointer */
/* register stack */ /* register stack */
IA64_REG_BSP, /* register stack pointer */ IA64_REG_BSP, /* register stack pointer */
IA64_REG_BSPSTORE, IA64_REG_BSPSTORE,
IA64_REG_PFS, /* previous function state */ IA64_REG_PFS, /* previous function state */
IA64_REG_RNAT, IA64_REG_RNAT,
/* instruction pointer: */ /* instruction pointer: */
IA64_REG_IP, IA64_REG_IP,
@ -83,19 +83,19 @@ ia64_loc_t;
#include "script.h" #include "script.h"
#define ABI_UNKNOWN 0 #define ABI_UNKNOWN 0
#define ABI_LINUX 1 #define ABI_LINUX 1
#define ABI_HPUX 2 #define ABI_HPUX 2
#define ABI_FREEBSD 3 #define ABI_FREEBSD 3
#define ABI_OPENVMS 4 #define ABI_OPENVMS 4
#define ABI_NSK 5 /* Tandem/HP Non-Stop Kernel */ #define ABI_NSK 5 /* Tandem/HP Non-Stop Kernel */
#define ABI_WINDOWS 6 #define ABI_WINDOWS 6
struct unw_addr_space struct unw_addr_space
{ {
struct unw_accessors acc; struct unw_accessors acc;
int big_endian; int big_endian;
int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */ int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */
unw_caching_policy_t caching_policy; unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H #ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation; AO_t cache_generation;
@ -103,7 +103,7 @@ struct unw_addr_space
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; unw_word_t dyn_generation;
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
#ifndef UNW_REMOTE_ONLY #ifndef UNW_REMOTE_ONLY
unsigned long long shared_object_removals; unsigned long long shared_object_removals;
#endif #endif
@ -113,47 +113,47 @@ struct unw_addr_space
/* Note: The ABI numbers in the ABI-markers (.unwabi directive) are /* Note: The ABI numbers in the ABI-markers (.unwabi directive) are
not the same as the above ABI numbers. */ not the same as the above ABI numbers. */
#define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's') #define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's')
#define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i') #define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i')
#define ABI_MARKER_HP_UX_SIGTRAMP ((1 << 8) | 1) #define ABI_MARKER_HP_UX_SIGTRAMP ((1 << 8) | 1)
#define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's') #define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's')
#define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i') #define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i')
struct cursor struct cursor
{ {
void *as_arg; /* argument to address-space callbacks */ void *as_arg; /* argument to address-space callbacks */
unw_addr_space_t as; /* reference to per-address-space info */ unw_addr_space_t as; /* reference to per-address-space info */
/* IP, CFM, and predicate cache (these are always equal to the /* IP, CFM, and predicate cache (these are always equal to the
values stored in ip_loc, cfm_loc, and pr_loc, values stored in ip_loc, cfm_loc, and pr_loc,
respectively). */ respectively). */
unw_word_t ip; /* instruction pointer value */ unw_word_t ip; /* instruction pointer value */
unw_word_t cfm; /* current frame mask */ unw_word_t cfm; /* current frame mask */
unw_word_t pr; /* current predicate values */ unw_word_t pr; /* current predicate values */
/* current frame info: */ /* current frame info: */
unw_word_t bsp; /* backing store pointer value */ unw_word_t bsp; /* backing store pointer value */
unw_word_t sp; /* stack pointer value */ unw_word_t sp; /* stack pointer value */
unw_word_t psp; /* previous sp value */ unw_word_t psp; /* previous sp value */
ia64_loc_t cfm_loc; /* cfm save location (or NULL) */ ia64_loc_t cfm_loc; /* cfm save location (or NULL) */
ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */ ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */
ia64_loc_t loc[IA64_NUM_PREGS]; ia64_loc_t loc[IA64_NUM_PREGS];
unw_word_t eh_args[4]; /* exception handler arguments */ unw_word_t eh_args[4]; /* exception handler arguments */
unw_word_t sigcontext_addr; /* address of sigcontext or 0 */ unw_word_t sigcontext_addr; /* address of sigcontext or 0 */
unw_word_t sigcontext_off; /* sigcontext-offset relative to signal sp */ unw_word_t sigcontext_off; /* sigcontext-offset relative to signal sp */
short hint; short hint;
short prev_script; short prev_script;
uint8_t nat_bitnr[4]; /* NaT bit numbers for r4-r7 */ uint8_t nat_bitnr[4]; /* NaT bit numbers for r4-r7 */
uint16_t abi_marker; /* abi_marker for current frame (if any) */ uint16_t abi_marker; /* abi_marker for current frame (if any) */
uint16_t last_abi_marker; /* last abi_marker encountered so far */ uint16_t last_abi_marker; /* last abi_marker encountered so far */
uint8_t eh_valid_mask; uint8_t eh_valid_mask;
unsigned int pi_valid :1; /* is proc_info valid? */ unsigned int pi_valid :1; /* is proc_info valid? */
unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */ unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */
unw_proc_info_t pi; /* info about current procedure */ unw_proc_info_t pi; /* info about current procedure */
/* In case of stack-discontiguities, such as those introduced by /* In case of stack-discontiguities, such as those introduced by
signal-delivery on an alternate signal-stack (see signal-delivery on an alternate signal-stack (see
@ -171,20 +171,20 @@ struct cursor
register may not have gotten spilled until much later, when a register may not have gotten spilled until much later, when a
possibly different rbs-area might have been in effect possibly different rbs-area might have been in effect
already. */ already. */
uint8_t rbs_curr; /* index of curr. rbs-area (contains c->bsp) */ uint8_t rbs_curr; /* index of curr. rbs-area (contains c->bsp) */
uint8_t rbs_left_edge; /* index of inner-most valid rbs-area */ uint8_t rbs_left_edge; /* index of inner-most valid rbs-area */
struct rbs_area struct rbs_area
{ {
unw_word_t end; unw_word_t end;
unw_word_t size; unw_word_t size;
ia64_loc_t rnat_loc; ia64_loc_t rnat_loc;
} }
rbs_area[96 + 2]; /* 96 stacked regs + 1 extra stack on each side... */ rbs_area[96 + 2]; /* 96 stacked regs + 1 extra stack on each side... */
}; };
struct ia64_global_unwind_state struct ia64_global_unwind_state
{ {
pthread_mutex_t lock; /* global data lock */ pthread_mutex_t lock; /* global data lock */
volatile char init_done; volatile char init_done;
@ -200,9 +200,9 @@ struct ia64_global_unwind_state
*/ */
struct struct
{ {
unw_word_t r0; /* r0 is byte-order neutral */ unw_word_t r0; /* r0 is byte-order neutral */
unw_fpreg_t f0; /* f0 is byte-order neutral */ unw_fpreg_t f0; /* f0 is byte-order neutral */
unw_fpreg_t f1_le, f1_be; /* f1 is byte-order dependent */ unw_fpreg_t f1_le, f1_be; /* f1 is byte-order dependent */
} }
read_only; read_only;
unw_fpreg_t nat_val_le, nat_val_be; unw_fpreg_t nat_val_le, nat_val_be;
@ -217,63 +217,63 @@ struct ia64_global_unwind_state
}; };
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done unw.init_done #define tdep_init_done unw.init_done
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table unw_search_ia64_unwind_table #define tdep_search_unwind_table unw_search_ia64_unwind_table
#define tdep_find_unwind_table ia64_find_unwind_table #define tdep_find_unwind_table ia64_find_unwind_table
#define tdep_find_proc_info UNW_OBJ(find_proc_info) #define tdep_find_proc_info UNW_OBJ(find_proc_info)
#define tdep_uc_addr UNW_OBJ(uc_addr) #define tdep_uc_addr UNW_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame(c,rs) do {} while(0) #define tdep_stash_frame(c,rs) do {} while(0)
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) #define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
#define tdep_get_as(c) ((c)->as) #define tdep_get_as(c) ((c)->as)
#define tdep_get_as_arg(c) ((c)->as_arg) #define tdep_get_as_arg(c) ((c)->as_arg)
#define tdep_get_ip(c) ((c)->ip) #define tdep_get_ip(c) ((c)->ip)
#define tdep_big_endian(as) ((c)->as->big_endian != 0) #define tdep_big_endian(as) ((c)->as->big_endian != 0)
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
# define tdep_put_unwind_info UNW_OBJ(put_unwind_info) # define tdep_put_unwind_info UNW_OBJ(put_unwind_info)
#endif #endif
/* This can't be an UNW_ARCH_OBJ() because we need separate /* This can't be an UNW_ARCH_OBJ() because we need separate
unw.initialized flags for the local-only and generic versions of unw.initialized flags for the local-only and generic versions of
the library. Also, if we wanted to have a single, shared global the library. Also, if we wanted to have a single, shared global
data structure, we couldn't declare "unw" as HIDDEN/PROTECTED. */ data structure, we couldn't declare "unw" as HIDDEN/PROTECTED. */
#define unw UNW_OBJ(data) #define unw UNW_OBJ(data)
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_find_unwind_table (struct elf_dyn_info *edi, extern int tdep_find_unwind_table (struct elf_dyn_info *edi,
unw_addr_space_t as, char *path, unw_addr_space_t as, char *path,
unw_word_t segbase, unw_word_t mapoff, unw_word_t segbase, unw_word_t mapoff,
unw_word_t ip); unw_word_t ip);
extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info, unw_proc_info_t *pi, int need_unwind_info,
void *arg); void *arg);
extern void tdep_put_unwind_info (unw_addr_space_t as, extern void tdep_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg); unw_proc_info_t *pi, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum, extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum,
uint8_t *nat_bitnr); uint8_t *nat_bitnr);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
extern struct ia64_global_unwind_state unw; extern struct ia64_global_unwind_state unw;
/* In user-level, we have no reasonable way of determining the base of /* In user-level, we have no reasonable way of determining the base of
an arbitrary backing-store. We default to half the an arbitrary backing-store. We default to half the
address-space. */ address-space. */
#define rbs_get_base(c,bspstore,rbs_basep) \ #define rbs_get_base(c,bspstore,rbs_basep) \
(*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0) (*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0)
#endif /* IA64_LIBUNWIND_I_H */ #endif /* IA64_LIBUNWIND_I_H */

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co * Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* *
* Register stack engine related helper functions. This file may be * Register stack engine related helper functions. This file may be
* used in applications, so be careful about the name-space and give * used in applications, so be careful about the name-space and give
@ -15,7 +15,7 @@
static inline uint64_t static inline uint64_t
rse_slot_num (uint64_t addr) rse_slot_num (uint64_t addr)
{ {
return (addr >> 3) & 0x3f; return (addr >> 3) & 0x3f;
} }
/* /*
@ -24,7 +24,7 @@ rse_slot_num (uint64_t addr)
static inline uint64_t static inline uint64_t
rse_is_rnat_slot (uint64_t addr) rse_is_rnat_slot (uint64_t addr)
{ {
return rse_slot_num (addr) == 0x3f; return rse_slot_num (addr) == 0x3f;
} }
/* /*
@ -34,7 +34,7 @@ rse_is_rnat_slot (uint64_t addr)
static inline uint64_t static inline uint64_t
rse_rnat_addr (uint64_t slot_addr) rse_rnat_addr (uint64_t slot_addr)
{ {
return slot_addr | (0x3f << 3); return slot_addr | (0x3f << 3);
} }
/* /*
@ -45,9 +45,9 @@ rse_rnat_addr (uint64_t slot_addr)
static inline uint64_t static inline uint64_t
rse_num_regs (uint64_t bspstore, uint64_t bsp) rse_num_regs (uint64_t bspstore, uint64_t bsp)
{ {
uint64_t slots = (bsp - bspstore) >> 3; uint64_t slots = (bsp - bspstore) >> 3;
return slots - (rse_slot_num(bspstore) + slots)/0x40; return slots - (rse_slot_num(bspstore) + slots)/0x40;
} }
/* /*
@ -57,11 +57,11 @@ rse_num_regs (uint64_t bspstore, uint64_t bsp)
static inline uint64_t static inline uint64_t
rse_skip_regs (uint64_t addr, long num_regs) rse_skip_regs (uint64_t addr, long num_regs)
{ {
long delta = rse_slot_num(addr) + num_regs; long delta = rse_slot_num(addr) + num_regs;
if (num_regs < 0) if (num_regs < 0)
delta -= 0x3e; delta -= 0x3e;
return addr + ((num_regs + delta/0x3f) << 3); return addr + ((num_regs + delta/0x3f) << 3);
} }
#endif /* RSE_H */ #endif /* RSE_H */

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2001-2002 Hewlett-Packard Co Copyright (C) 2001-2002 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -23,17 +23,17 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define IA64_LOG_UNW_CACHE_SIZE 7 #define IA64_LOG_UNW_CACHE_SIZE 7
#define IA64_UNW_CACHE_SIZE (1 << IA64_LOG_UNW_CACHE_SIZE) #define IA64_UNW_CACHE_SIZE (1 << IA64_LOG_UNW_CACHE_SIZE)
#define IA64_LOG_UNW_HASH_SIZE (IA64_LOG_UNW_CACHE_SIZE + 1) #define IA64_LOG_UNW_HASH_SIZE (IA64_LOG_UNW_CACHE_SIZE + 1)
#define IA64_UNW_HASH_SIZE (1 << IA64_LOG_UNW_HASH_SIZE) #define IA64_UNW_HASH_SIZE (1 << IA64_LOG_UNW_HASH_SIZE)
typedef unsigned char unw_hash_index_t; typedef unsigned char unw_hash_index_t;
struct ia64_script_insn struct ia64_script_insn
{ {
unsigned int opc; /* see enum ia64_script_insn_opcode */ unsigned int opc; /* see enum ia64_script_insn_opcode */
unsigned int dst; unsigned int dst;
unw_word_t val; unw_word_t val;
}; };
@ -41,18 +41,18 @@ struct ia64_script_insn
/* Updating each preserved register may result in one script /* Updating each preserved register may result in one script
instruction each. At the end of the script, psp gets popped, instruction each. At the end of the script, psp gets popped,
accounting for one more instruction. */ accounting for one more instruction. */
#define IA64_MAX_SCRIPT_LEN (IA64_NUM_PREGS + 1) #define IA64_MAX_SCRIPT_LEN (IA64_NUM_PREGS + 1)
struct ia64_script struct ia64_script
{ {
unw_word_t ip; /* ip this script is for */ unw_word_t ip; /* ip this script is for */
unw_word_t pr_mask; /* mask of predicates script depends on */ unw_word_t pr_mask; /* mask of predicates script depends on */
unw_word_t pr_val; /* predicate values this script is for */ unw_word_t pr_val; /* predicate values this script is for */
unw_proc_info_t pi; /* info about underlying procedure */ unw_proc_info_t pi; /* info about underlying procedure */
unsigned short lru_chain; /* used for least-recently-used chain */ unsigned short lru_chain; /* used for least-recently-used chain */
unsigned short coll_chain; /* used for hash collisions */ unsigned short coll_chain; /* used for hash collisions */
unsigned short hint; /* hint for next script to try (or -1) */ unsigned short hint; /* hint for next script to try (or -1) */
unsigned short count; /* number of instructions in script */ unsigned short count; /* number of instructions in script */
unsigned short abi_marker; unsigned short abi_marker;
struct ia64_script_insn insn[IA64_MAX_SCRIPT_LEN]; struct ia64_script_insn insn[IA64_MAX_SCRIPT_LEN];
}; };
@ -60,26 +60,26 @@ struct ia64_script
struct ia64_script_cache struct ia64_script_cache
{ {
#ifdef HAVE_ATOMIC_OPS_H #ifdef HAVE_ATOMIC_OPS_H
AO_TS_t busy; /* is the script-cache busy? */ AO_TS_t busy; /* is the script-cache busy? */
#else #else
pthread_mutex_t lock; pthread_mutex_t lock;
#endif #endif
unsigned short lru_head; /* index of lead-recently used script */ unsigned short lru_head; /* index of lead-recently used script */
unsigned short lru_tail; /* index of most-recently used script */ unsigned short lru_tail; /* index of most-recently used script */
/* hash table that maps instruction pointer to script index: */ /* hash table that maps instruction pointer to script index: */
unsigned short hash[IA64_UNW_HASH_SIZE]; unsigned short hash[IA64_UNW_HASH_SIZE];
uint32_t generation; /* generation number */ uint32_t generation; /* generation number */
/* script cache: */ /* script cache: */
struct ia64_script buckets[IA64_UNW_CACHE_SIZE]; struct ia64_script buckets[IA64_UNW_CACHE_SIZE];
}; };
#define ia64_cache_proc_info UNW_OBJ(cache_proc_info) #define ia64_cache_proc_info UNW_OBJ(cache_proc_info)
#define ia64_get_cached_proc_info UNW_OBJ(get_cached_proc_info) #define ia64_get_cached_proc_info UNW_OBJ(get_cached_proc_info)
struct cursor; /* forward declaration */ struct cursor; /* forward declaration */
extern int ia64_cache_proc_info (struct cursor *c); extern int ia64_cache_proc_info (struct cursor *c);
extern int ia64_get_cached_proc_info (struct cursor *c); extern int ia64_get_cached_proc_info (struct cursor *c);

View file

@ -28,25 +28,25 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not /* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not
explicitly defined. */ explicitly defined. */
#define DWARF_NUM_PRESERVED_REGS 188 #define DWARF_NUM_PRESERVED_REGS 188
#define dwarf_to_unw_regnum(reg) (((reg) < 32) ? (reg) : 0) #define dwarf_to_unw_regnum(reg) (((reg) < 32) ? (reg) : 0)
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) #define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian)
/* Return the size of an address, for DWARF purposes. */ /* Return the size of an address, for DWARF purposes. */
#define dwarf_addr_size(addr_space) ((addr_space)->addr_size) #define dwarf_addr_size(addr_space) ((addr_space)->addr_size)
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* FIXME for MIPS! */ /* FIXME for MIPS! */
#define JB_SP 4 #define JB_SP 4
#define JB_RP 5 #define JB_RP 5
#define JB_MASK_SAVED 6 #define JB_MASK_SAVED 6
#define JB_MASK 7 #define JB_MASK 7

View file

@ -59,21 +59,21 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
}; };
#define tdep_big_endian(as) ((as)->big_endian) #define tdep_big_endian(as) ((as)->big_endian)
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
unw_word_t sigcontext_addr; unw_word_t sigcontext_addr;
}; };
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifndef UNW_REMOTE_ONLY #ifndef UNW_REMOTE_ONLY
# if _MIPS_SIM == _ABIN32 # if _MIPS_SIM == _ABIN32
@ -84,15 +84,15 @@ typedef long mips_reg_t;
#endif #endif
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
/* FIXME: Implement these for the MIPS FPU. */ /* FIXME: Implement these for the MIPS FPU. */
static inline int static inline int
@ -132,18 +132,18 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
} }
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
static inline int static inline int
read_s32 (struct dwarf_cursor *c, unw_word_t addr, unw_word_t *val) read_s32 (struct dwarf_cursor *c, unw_word_t addr, unw_word_t *val)
@ -196,15 +196,15 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
0, c->as_arg)) < 0) 0, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
c->as_arg); c->as_arg);
} }
static inline int static inline int
@ -219,15 +219,15 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
1, c->as_arg)) < 0) 1, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
1, c->as_arg); 1, c->as_arg);
} }
static inline int static inline int
@ -244,12 +244,12 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
else if (c->as->abi == UNW_MIPS_ABI_O32) else if (c->as->abi == UNW_MIPS_ABI_O32)
return read_s32 (c, DWARF_GET_LOC (loc), val); return read_s32 (c, DWARF_GET_LOC (loc), val);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -266,64 +266,64 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else if (c->as->abi == UNW_MIPS_ABI_O32) else if (c->as->abi == UNW_MIPS_ABI_O32)
return write_s32 (c, DWARF_GET_LOC (loc), &val); return write_s32 (c, DWARF_GET_LOC (loc), &val);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame(c,rs) do {} while(0) #define tdep_stash_frame(c,rs) do {} while(0)
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) #define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
dwarf_put_unwind_info((as), (pi), (arg)) dwarf_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 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, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg); extern void *tdep_uc_addr (ucontext_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
#endif /* MIPS_LIBUNWIND_I_H */ #endif /* MIPS_LIBUNWIND_I_H */

View file

@ -33,22 +33,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define dwarf_config_h #define dwarf_config_h
/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ /* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */
#define DWARF_NUM_PRESERVED_REGS 115 #define DWARF_NUM_PRESERVED_REGS 115
#define DWARF_REGNUM_MAP_LENGTH 115 #define DWARF_REGNUM_MAP_LENGTH 115
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) 1 #define dwarf_is_big_endian(addr_space) 1
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see X86_LOC_TYPE_* macros. */ unw_word_t type; /* see X86_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -31,7 +31,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ /* Use glibc's jump-buffer indices; NPTL peeks at SP: */
#define JB_SP 6 #define JB_SP 6
#define JB_RP 7 #define JB_RP 7
#define JB_MASK_SAVED 8 #define JB_MASK_SAVED 8
#define JB_MASK 9 #define JB_MASK 9

View file

@ -57,8 +57,8 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
int validate; int validate;
@ -66,53 +66,53 @@ struct unw_addr_space
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
/* Format of sigcontext structure and address at which it is /* Format of sigcontext structure and address at which it is
stored: */ stored: */
enum enum
{ {
PPC_SCF_NONE, /* no signal frame encountered */ PPC_SCF_NONE, /* no signal frame encountered */
PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
} }
sigcontext_format; sigcontext_format;
unw_word_t sigcontext_addr; unw_word_t sigcontext_addr;
}; };
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_IS_FP_LOC(l) 0 # define DWARF_IS_FP_LOC(l) 0
# define DWARF_IS_V_LOC(l) 0 # define DWARF_IS_V_LOC(l) 0
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_LOC_TYPE_V (1 << 2) # define DWARF_LOC_TYPE_V (1 << 2)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) # define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_V)) | DWARF_LOC_TYPE_V))
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
@ -131,12 +131,12 @@ dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
0, c->as_arg)) < 0) 0, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg);
@ -157,11 +157,11 @@ dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
1, c->as_arg)) < 0) 1, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg);
@ -181,7 +181,7 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg);
@ -202,7 +202,7 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
@ -224,10 +224,10 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -245,68 +245,68 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame(c,rs) do {} while(0) #define tdep_stash_frame(c,rs) do {} while(0)
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) #define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
#define tdep_get_func_addr UNW_OBJ(get_func_addr) #define tdep_get_func_addr UNW_OBJ(get_func_addr)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
dwarf_put_unwind_info((as), (pi), (arg)) dwarf_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip,
int need_unwind_info); int need_unwind_info);
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_big_endian(as) 1 #define tdep_big_endian(as) 1
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t * di, unw_dyn_info_t * di,
unw_proc_info_t * pi, unw_proc_info_t * pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t * uc, int reg); extern void *tdep_uc_addr (ucontext_t * uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t * valp, int write); unw_word_t * valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t * valp, int write); unw_fpreg_t * valp, int write);
extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr,
unw_word_t *entry_point); unw_word_t *entry_point);
#endif /* PPC64_LIBUNWIND_I_H */ #endif /* PPC64_LIBUNWIND_I_H */

View file

@ -33,22 +33,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define dwarf_config_h #define dwarf_config_h
/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ /* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */
#define DWARF_NUM_PRESERVED_REGS 115 #define DWARF_NUM_PRESERVED_REGS 115
#define DWARF_REGNUM_MAP_LENGTH 115 #define DWARF_REGNUM_MAP_LENGTH 115
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) #define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian)
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see X86_LOC_TYPE_* macros. */ unw_word_t type; /* see X86_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -31,7 +31,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ /* Use glibc's jump-buffer indices; NPTL peeks at SP: */
#define JB_SP 6 #define JB_SP 6
#define JB_RP 7 #define JB_RP 7
#define JB_MASK_SAVED 8 #define JB_MASK_SAVED 8
#define JB_MASK 9 #define JB_MASK 9

View file

@ -59,8 +59,8 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
int validate; int validate;
@ -68,53 +68,53 @@ struct unw_addr_space
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
/* Format of sigcontext structure and address at which it is /* Format of sigcontext structure and address at which it is
stored: */ stored: */
enum enum
{ {
PPC_SCF_NONE, /* no signal frame encountered */ PPC_SCF_NONE, /* no signal frame encountered */
PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
} }
sigcontext_format; sigcontext_format;
unw_word_t sigcontext_addr; unw_word_t sigcontext_addr;
}; };
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_IS_FP_LOC(l) 0 # define DWARF_IS_FP_LOC(l) 0
# define DWARF_IS_V_LOC(l) 0 # define DWARF_IS_V_LOC(l) 0
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_LOC_TYPE_V (1 << 2) # define DWARF_LOC_TYPE_V (1 << 2)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) # define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_V)) | DWARF_LOC_TYPE_V))
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
@ -133,12 +133,12 @@ dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
0, c->as_arg)) < 0) 0, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg);
@ -159,11 +159,11 @@ dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp,
1, c->as_arg)) < 0) 1, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg);
@ -183,7 +183,7 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg);
@ -204,7 +204,7 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
@ -226,10 +226,10 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -247,68 +247,68 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame(c,rs) do {} while(0) #define tdep_stash_frame(c,rs) do {} while(0)
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) #define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
#define tdep_get_func_addr UNW_OBJ(get_func_addr) #define tdep_get_func_addr UNW_OBJ(get_func_addr)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
dwarf_put_unwind_info((as), (pi), (arg)) dwarf_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip,
int need_unwind_info); int need_unwind_info);
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_big_endian(as) ((as)->big_endian) #define tdep_big_endian(as) ((as)->big_endian)
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t * di, unw_dyn_info_t * di,
unw_proc_info_t * pi, unw_proc_info_t * pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t * uc, int reg); extern void *tdep_uc_addr (ucontext_t * uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t * valp, int write); unw_word_t * valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t * valp, int write); unw_fpreg_t * valp, int write);
extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr,
unw_word_t *entry_point); unw_word_t *entry_point);
#endif /* PPC64_LIBUNWIND_I_H */ #endif /* PPC64_LIBUNWIND_I_H */

View file

@ -26,22 +26,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef dwarf_config_h #ifndef dwarf_config_h
#define dwarf_config_h #define dwarf_config_h
#define DWARF_NUM_PRESERVED_REGS 18 #define DWARF_NUM_PRESERVED_REGS 18
#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_SH_PR) ? (reg) : 0) #define dwarf_to_unw_regnum(reg) (((reg) <= UNW_SH_PR) ? (reg) : 0)
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) #define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian)
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
* 14. fr15 * 14. fr15
*/ */
#define JB_SP 7 #define JB_SP 7
#define JB_RP 8 #define JB_RP 8
#define JB_MASK_SAVED 15 #define JB_MASK_SAVED 15
#define JB_MASK 16 #define JB_MASK 16

View file

@ -52,15 +52,15 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
}; };
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
enum enum
{ {
SH_SCF_NONE, /* no signal frame */ SH_SCF_NONE, /* no signal frame */
@ -73,18 +73,18 @@ struct cursor
unw_word_t sigcontext_pc; unw_word_t sigcontext_pc;
}; };
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0)) tdep_uc_addr((c)->as_arg, (r)), 0))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -123,18 +123,18 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
} }
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -148,15 +148,15 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
0, c->as_arg)) < 0) 0, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
c->as_arg); c->as_arg);
} }
static inline int static inline int
@ -171,15 +171,15 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
1, c->as_arg)) < 0) 1, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
1, c->as_arg); 1, c->as_arg);
} }
static inline int static inline int
@ -196,10 +196,10 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -216,63 +216,63 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame(c,rs) do {} while(0) #define tdep_stash_frame(c,rs) do {} while(0)
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) #define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
dwarf_put_unwind_info((as), (pi), (arg)) dwarf_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_big_endian(as) ((as)->big_endian) #define tdep_big_endian(as) ((as)->big_endian)
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 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, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
#endif /* SH_LIBUNWIND_I_H */ #endif /* SH_LIBUNWIND_I_H */

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003 Hewlett-Packard Development Company, L.P. Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -29,22 +29,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* This matches the value used by GCC (see /* This matches the value used by GCC (see
gcc/config/i386.h:DWARF_FRAME_REGISTERS), which leaves plenty of gcc/config/i386.h:DWARF_FRAME_REGISTERS), which leaves plenty of
room for expansion. */ room for expansion. */
#define DWARF_NUM_PRESERVED_REGS 17 #define DWARF_NUM_PRESERVED_REGS 17
#define DWARF_REGNUM_MAP_LENGTH 19 #define DWARF_REGNUM_MAP_LENGTH 19
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) 0 #define dwarf_is_big_endian(addr_space) 0
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see X86_LOC_TYPE_* macros. */ unw_word_t type; /* see X86_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -27,16 +27,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#if defined __linux__ #if defined __linux__
#define JB_SP 4 #define JB_SP 4
#define JB_RP 5 #define JB_RP 5
#define JB_MASK_SAVED 6 #define JB_MASK_SAVED 6
#define JB_MASK 7 #define JB_MASK 7
#elif defined __FreeBSD__ #elif defined __FreeBSD__
#define JB_SP 2 #define JB_SP 2
#define JB_RP 0 #define JB_RP 0
#define JB_MASK_SAVED 11 #define JB_MASK_SAVED 11
#define JB_MASK 7 #define JB_MASK 7
#endif #endif

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2002-2005 Hewlett-Packard Co Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -51,27 +51,27 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
}; };
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
/* Format of sigcontext structure and address at which it is /* Format of sigcontext structure and address at which it is
stored: */ stored: */
enum enum
{ {
X86_SCF_NONE, /* no signal frame encountered */ X86_SCF_NONE, /* no signal frame encountered */
X86_SCF_LINUX_SIGFRAME, /* Linux x86 sigcontext */ X86_SCF_LINUX_SIGFRAME, /* Linux x86 sigcontext */
X86_SCF_LINUX_RT_SIGFRAME, /* POSIX ucontext_t */ X86_SCF_LINUX_RT_SIGFRAME, /* POSIX ucontext_t */
X86_SCF_FREEBSD_SIGFRAME, /* FreeBSD x86 sigcontext */ X86_SCF_FREEBSD_SIGFRAME, /* FreeBSD x86 sigcontext */
X86_SCF_FREEBSD_SIGFRAME4, /* FreeBSD 4.x x86 sigcontext */ X86_SCF_FREEBSD_SIGFRAME4, /* FreeBSD 4.x x86 sigcontext */
X86_SCF_FREEBSD_OSIGFRAME, /* FreeBSD pre-4.x x86 sigcontext */ X86_SCF_FREEBSD_OSIGFRAME, /* FreeBSD pre-4.x x86 sigcontext */
X86_SCF_FREEBSD_SYSCALL, /* FreeBSD x86 syscall */ X86_SCF_FREEBSD_SYSCALL, /* FreeBSD x86 syscall */
} }
sigcontext_format; sigcontext_format;
unw_word_t sigcontext_addr; unw_word_t sigcontext_addr;
@ -86,18 +86,18 @@ dwarf_get_uc(const struct dwarf_cursor *cursor)
return c->uc; return c->uc;
} }
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) tdep_uc_addr(dwarf_get_uc(c), (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) tdep_uc_addr(dwarf_get_uc(c), (r)), 0))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -123,7 +123,7 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
if (!DWARF_GET_LOC (loc)) if (!DWARF_GET_LOC (loc))
return -1; return -1;
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -132,22 +132,22 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (!DWARF_GET_LOC (loc)) if (!DWARF_GET_LOC (loc))
return -1; return -1;
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
static inline int static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
@ -161,15 +161,15 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
val, 0, c->as_arg); val, 0, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
0, c->as_arg)) < 0) 0, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
c->as_arg); c->as_arg);
} }
static inline int static inline int
@ -184,15 +184,15 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
&val, 1, c->as_arg); &val, 1, c->as_arg);
addr = DWARF_GET_LOC (loc); addr = DWARF_GET_LOC (loc);
if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
1, c->as_arg)) < 0) 1, c->as_arg)) < 0)
return ret; return ret;
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
1, c->as_arg); 1, c->as_arg);
} }
static inline int static inline int
@ -209,10 +209,10 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
} }
static inline int static inline int
@ -229,63 +229,63 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
#define tdep_getcontext_trace unw_getcontext #define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_fetch_frame(c,ip,n) do {} while(0) #define tdep_fetch_frame(c,ip,n) do {} while(0)
#define tdep_cache_frame(c,rs) do {} while(0) #define tdep_cache_frame(c,rs) do {} while(0)
#define tdep_reuse_frame(c,rs) do {} while(0) #define tdep_reuse_frame(c,rs) do {} while(0)
#define tdep_stash_frame(c,rs) do {} while(0) #define tdep_stash_frame(c,rs) do {} while(0)
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) #define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
dwarf_put_unwind_info((as), (pi), (arg)) dwarf_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_big_endian(as) 0 #define tdep_big_endian(as) 0
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 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, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg); extern void *tdep_uc_addr (ucontext_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
#endif /* X86_LIBUNWIND_I_H */ #endif /* X86_LIBUNWIND_I_H */

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com> Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@ -33,25 +33,25 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* XXX need to verify if this value is correct */ /* XXX need to verify if this value is correct */
#ifdef CONFIG_MSABI_SUPPORT #ifdef CONFIG_MSABI_SUPPORT
#define DWARF_NUM_PRESERVED_REGS 33 #define DWARF_NUM_PRESERVED_REGS 33
#else #else
#define DWARF_NUM_PRESERVED_REGS 17 #define DWARF_NUM_PRESERVED_REGS 17
#endif #endif
#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS #define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) 0 #define dwarf_is_big_endian(addr_space) 0
/* Convert a pointer to a dwarf_cursor structure to a pointer to /* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */ unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc typedef struct dwarf_loc
{ {
unw_word_t val; unw_word_t val;
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see X86_LOC_TYPE_* macros. */ unw_word_t type; /* see X86_LOC_TYPE_* macros. */
#endif #endif
} }
dwarf_loc_t; dwarf_loc_t;

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -27,17 +27,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ /* Use glibc's jump-buffer indices; NPTL peeks at SP: */
#define JB_SP 6 #define JB_SP 6
#define JB_RP 7 #define JB_RP 7
#define JB_MASK_SAVED 8 #define JB_MASK_SAVED 8
#define JB_MASK 9 #define JB_MASK 9
#elif defined __FreeBSD__ #elif defined __FreeBSD__
#define JB_SP 2 #define JB_SP 2
#define JB_RP 0 #define JB_RP 0
/* Pretend the ip cannot be 0 and mask is always saved */ /* Pretend the ip cannot be 0 and mask is always saved */
#define JB_MASK_SAVED 0 #define JB_MASK_SAVED 0
#define JB_MASK 9 #define JB_MASK 9
#endif #endif

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2002-2005 Hewlett-Packard Co Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com> Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
@ -68,26 +68,26 @@ struct unw_addr_space
#else #else
uint32_t cache_generation; uint32_t cache_generation;
#endif #endif
unw_word_t dyn_generation; /* see dyn-common.h */ unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
struct dwarf_rs_cache global_cache; struct dwarf_rs_cache global_cache;
struct unw_debug_frame_list *debug_frames; struct unw_debug_frame_list *debug_frames;
}; };
struct cursor struct cursor
{ {
struct dwarf_cursor dwarf; /* must be first */ struct dwarf_cursor dwarf; /* must be first */
unw_tdep_frame_t frame_info; /* quick tracing assist info */ unw_tdep_frame_t frame_info; /* quick tracing assist info */
/* Format of sigcontext structure and address at which it is /* Format of sigcontext structure and address at which it is
stored: */ stored: */
enum enum
{ {
X86_64_SCF_NONE, /* no signal frame encountered */ X86_64_SCF_NONE, /* no signal frame encountered */
X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */ X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */
X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */ X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */
X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */ X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */
} }
sigcontext_format; sigcontext_format;
unw_word_t sigcontext_addr; unw_word_t sigcontext_addr;
@ -102,40 +102,40 @@ dwarf_get_uc(const struct dwarf_cursor *cursor)
return c->uc; return c->uc;
} }
#define DWARF_GET_LOC(l) ((l).val) #define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0 # define DWARF_IS_REG_LOC(l) 0
# define DWARF_IS_MEM_LOC(l) 1 # define DWARF_IS_MEM_LOC(l) 1
# define DWARF_IS_VAL_LOC(l) 0 # define DWARF_IS_VAL_LOC(l) 0
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0))
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0))
# define DWARF_VAL_LOC(c,v) DWARF_NULL_LOC # define DWARF_VAL_LOC(c,v) DWARF_NULL_LOC
#else /* !UNW_LOCAL_ONLY */ #else /* !UNW_LOCAL_ONLY */
# define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_FP (1 << 0)
# define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_LOC_TYPE_REG (1 << 1)
# define DWARF_LOC_TYPE_VAL (1 << 2) # define DWARF_LOC_TYPE_VAL (1 << 2)
# define DWARF_NULL_LOC DWARF_LOC (0, 0) # define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) \ # define DWARF_IS_NULL_LOC(l) \
({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
# define DWARF_IS_MEM_LOC(l) ((l).type == 0) # define DWARF_IS_MEM_LOC(l) ((l).type == 0)
# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) # define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0)
# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
| DWARF_LOC_TYPE_FP)) | DWARF_LOC_TYPE_FP))
# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) # define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL)
#endif /* !UNW_LOCAL_ONLY */ #endif /* !UNW_LOCAL_ONLY */
@ -165,10 +165,10 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
if (DWARF_IS_MEM_LOC (loc)) if (DWARF_IS_MEM_LOC (loc))
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
0, c->as_arg); 0, c->as_arg);
assert(DWARF_IS_VAL_LOC (loc)); assert(DWARF_IS_VAL_LOC (loc));
*val = DWARF_GET_LOC (loc); *val = DWARF_GET_LOC (loc);
return 0; return 0;
@ -184,79 +184,79 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
if (DWARF_IS_REG_LOC (loc)) if (DWARF_IS_REG_LOC (loc))
return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
else else
return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
1, c->as_arg); 1, c->as_arg);
} }
#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) #define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace)
#define tdep_init_done UNW_OBJ(init_done) #define tdep_init_done UNW_OBJ(init_done)
#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) #define tdep_init_mem_validate UNW_OBJ(init_mem_validate)
#define tdep_init UNW_OBJ(init) #define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */ tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table #define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_find_unwind_table dwarf_find_unwind_table #define tdep_find_unwind_table dwarf_find_unwind_table
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg) #define tdep_access_fpreg UNW_OBJ(access_fpreg)
#if __linux__ #if __linux__
# define tdep_fetch_frame UNW_OBJ(fetch_frame) # define tdep_fetch_frame UNW_OBJ(fetch_frame)
# define tdep_cache_frame UNW_OBJ(cache_frame) # define tdep_cache_frame UNW_OBJ(cache_frame)
# define tdep_reuse_frame UNW_OBJ(reuse_frame) # define tdep_reuse_frame UNW_OBJ(reuse_frame)
#else #else
# define tdep_fetch_frame(c,ip,n) do {} while(0) # define tdep_fetch_frame(c,ip,n) do {} while(0)
# define tdep_cache_frame(c,rs) do {} while(0) # define tdep_cache_frame(c,rs) do {} while(0)
# define tdep_reuse_frame(c,rs) do {} while(0) # define tdep_reuse_frame(c,rs) do {} while(0)
#endif #endif
#define tdep_stash_frame UNW_OBJ(stash_frame) #define tdep_stash_frame UNW_OBJ(stash_frame)
#define tdep_trace UNW_OBJ(tdep_trace) #define tdep_trace UNW_OBJ(tdep_trace)
#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr) #define x86_64_r_uc_addr UNW_OBJ(r_uc_addr)
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
dwarf_put_unwind_info((as), (pi), (arg)) dwarf_put_unwind_info((as), (pi), (arg))
#else #else
# define tdep_find_proc_info(c,ip,n) \ # define tdep_find_proc_info(c,ip,n) \
(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
(c)->as_arg) (c)->as_arg)
# define tdep_put_unwind_info(as,pi,arg) \ # define tdep_put_unwind_info(as,pi,arg) \
(*(as)->acc.put_unwind_info)((as), (pi), (arg)) (*(as)->acc.put_unwind_info)((as), (pi), (arg))
#endif #endif
#define tdep_get_as(c) ((c)->dwarf.as) #define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_big_endian(as) 0 #define tdep_big_endian(as) 0
extern int tdep_init_done; extern int tdep_init_done;
extern void tdep_init (void); extern void tdep_init (void);
extern void tdep_init_mem_validate (void); extern void tdep_init_mem_validate (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 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, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg); int need_unwind_info, void *arg);
extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, unsigned long *segbase, unsigned long *mapoff,
char *path, size_t pathlen); char *path, size_t pathlen);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write); unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write); unw_fpreg_t *valp, int write);
#if __linux__ #if __linux__
extern void tdep_fetch_frame (struct dwarf_cursor *c, unw_word_t ip, extern void tdep_fetch_frame (struct dwarf_cursor *c, unw_word_t ip,
int need_unwind_info); int need_unwind_info);
extern void tdep_cache_frame (struct dwarf_cursor *c, extern void tdep_cache_frame (struct dwarf_cursor *c,
struct dwarf_reg_state *rs); struct dwarf_reg_state *rs);
extern void tdep_reuse_frame (struct dwarf_cursor *c, extern void tdep_reuse_frame (struct dwarf_cursor *c,
struct dwarf_reg_state *rs); struct dwarf_reg_state *rs);
extern void tdep_stash_frame (struct dwarf_cursor *c, extern void tdep_stash_frame (struct dwarf_cursor *c,
struct dwarf_reg_state *rs); struct dwarf_reg_state *rs);
#endif #endif
extern int tdep_getcontext_trace (unw_tdep_context_t *); extern int tdep_getcontext_trace (unw_tdep_context_t *);

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co Copyright (C) 2003 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -35,7 +35,7 @@ extern "C" {
/* Minimal interface as per C++ ABI draft standard: /* Minimal interface as per C++ ABI draft standard:
http://www.codesourcery.com/cxx-abi/abi-eh.html */ http://www.codesourcery.com/cxx-abi/abi-eh.html */
typedef enum typedef enum
{ {
@ -53,22 +53,22 @@ _Unwind_Reason_Code;
typedef int _Unwind_Action; typedef int _Unwind_Action;
#define _UA_SEARCH_PHASE 1 #define _UA_SEARCH_PHASE 1
#define _UA_CLEANUP_PHASE 2 #define _UA_CLEANUP_PHASE 2
#define _UA_HANDLER_FRAME 4 #define _UA_HANDLER_FRAME 4
#define _UA_FORCE_UNWIND 8 #define _UA_FORCE_UNWIND 8
struct _Unwind_Context; /* opaque data-structure */ struct _Unwind_Context; /* opaque data-structure */
struct _Unwind_Exception; /* forward-declaration */ struct _Unwind_Exception; /* forward-declaration */
typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
struct _Unwind_Exception *); struct _Unwind_Exception *);
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action, typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action,
uint64_t, uint64_t,
struct _Unwind_Exception *, struct _Unwind_Exception *,
struct _Unwind_Context *, struct _Unwind_Context *,
void *); void *);
/* The C++ ABI requires exception_class, private_1, and private_2 to /* The C++ ABI requires exception_class, private_1, and private_2 to
be of type uint64 and the entire structure to be be of type uint64 and the entire structure to be
@ -84,7 +84,7 @@ struct _Unwind_Exception
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
_Unwind_Stop_Fn, void *); _Unwind_Stop_Fn, void *);
extern void _Unwind_Resume (struct _Unwind_Exception *); extern void _Unwind_Resume (struct _Unwind_Exception *);
extern void _Unwind_DeleteException (struct _Unwind_Exception *); extern void _Unwind_DeleteException (struct _Unwind_Exception *);
extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int); extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int);
@ -100,17 +100,17 @@ extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *);
/* Callback for _Unwind_Backtrace(). The backtrace stops immediately /* Callback for _Unwind_Backtrace(). The backtrace stops immediately
if the callback returns any value other than _URC_NO_REASON. */ if the callback returns any value other than _URC_NO_REASON. */
typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *, typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *,
void *); void *);
/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why /* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why
_UA_END_OF_STACK exists. */ _UA_END_OF_STACK exists. */
# define _UA_END_OF_STACK 16 # define _UA_END_OF_STACK 16
/* If the unwind was initiated due to a forced unwind, resume that /* If the unwind was initiated due to a forced unwind, resume that
operation, else re-raise the exception. This is used by operation, else re-raise the exception. This is used by
__cxa_rethrow(). */ __cxa_rethrow(). */
extern _Unwind_Reason_Code extern _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why /* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why
_Unwind_GetBSP() exists. */ _Unwind_GetBSP() exists. */

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -25,7 +25,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ /* Use glibc's jump-buffer indices; NPTL peeks at SP: */
#define JB_SP 4 #define JB_SP 4
#define JB_RP 5 #define JB_RP 5
#define JB_MASK_SAVED 6 #define JB_MASK_SAVED 6
#define JB_MASK 7 #define JB_MASK 7

View file

@ -72,7 +72,7 @@ unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc)
break; break;
default: default:
loc = DWARF_NULL_LOC; /* default to "not saved" */ loc = DWARF_NULL_LOC; /* default to "not saved" */
break; break;
} }

View file

@ -50,7 +50,7 @@ tdep_init (void)
#ifndef UNW_REMOTE_ONLY #ifndef UNW_REMOTE_ONLY
aarch64_local_addr_space_init (); aarch64_local_addr_space_init ();
#endif #endif
tdep_init_done = 1; /* signal that we're initialized... */ tdep_init_done = 1; /* signal that we're initialized... */
} }
out: out:
lock_release (&aarch64_lock, saved_mask); lock_release (&aarch64_lock, saved_mask);

View file

@ -74,7 +74,7 @@ put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
static int static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg) void *arg)
{ {
*dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
return 0; return 0;
@ -82,7 +82,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
static int static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg) void *arg)
{ {
if (write) if (write)
{ {
@ -99,7 +99,7 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
static int static int
access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
void *arg) void *arg)
{ {
unw_word_t *addr; unw_word_t *addr;
ucontext_t *uc = arg; ucontext_t *uc = arg;
@ -129,7 +129,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
static int static int
access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg) int write, void *arg)
{ {
ucontext_t *uc = arg; ucontext_t *uc = arg;
unw_fpreg_t *addr; unw_fpreg_t *addr;
@ -143,14 +143,14 @@ access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
if (write) if (write)
{ {
Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg),
((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
*(unw_fpreg_t *) addr = *val; *(unw_fpreg_t *) addr = *val;
} }
else else
{ {
*val = *(unw_fpreg_t *) addr; *val = *(unw_fpreg_t *) addr;
Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg),
((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
} }
return 0; return 0;
@ -162,8 +162,8 @@ access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
static int static int
get_static_proc_name (unw_addr_space_t as, unw_word_t ip, get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp, char *buf, size_t buf_len, unw_word_t *offp,
void *arg) void *arg)
{ {
return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
} }

View file

@ -28,7 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
HIDDEN int HIDDEN int
tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
int write) int write)
{ {
dwarf_loc_t loc = DWARF_NULL_LOC; dwarf_loc_t loc = DWARF_NULL_LOC;
unsigned int mask; unsigned int mask;
@ -106,7 +106,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
HIDDEN int HIDDEN int
tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
int write) int write)
{ {
Debug (1, "bad register number %u\n", reg); Debug (1, "bad register number %u\n", reg);
return -UNW_EBADREG; return -UNW_EBADREG;

View file

@ -39,7 +39,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
if (c->sigcontext_format == AARCH64_SCF_NONE) if (c->sigcontext_format == AARCH64_SCF_NONE)
{ {
/* Since there are no signals involved here we restore the non scratch /* Since there are no signals involved here we restore the non scratch
registers only. */ registers only. */
unsigned long regs[11]; unsigned long regs[11];
regs[0] = uc->uc_mcontext.regs[19]; regs[0] = uc->uc_mcontext.regs[19];
regs[1] = uc->uc_mcontext.regs[20]; regs[1] = uc->uc_mcontext.regs[20];
@ -143,15 +143,15 @@ establish_machine_state (struct cursor *c)
{ {
Debug (16, "copying %s %d\n", unw_regname (reg), reg); Debug (16, "copying %s %d\n", unw_regname (reg), reg);
if (unw_is_fpreg (reg)) if (unw_is_fpreg (reg))
{ {
if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
as->acc.access_fpreg (as, reg, &fpval, 1, arg); as->acc.access_fpreg (as, reg, &fpval, 1, arg);
} }
else else
{ {
if (tdep_access_reg (c, reg, &val, 0) >= 0) if (tdep_access_reg (c, reg, &val, 0) >= 0)
as->acc.access_reg (as, reg, &val, 1, arg); as->acc.access_reg (as, reg, &val, 1, arg);
} }
} }
} }
@ -165,7 +165,7 @@ unw_resume (unw_cursor_t *cursor)
if (!c->dwarf.ip) if (!c->dwarf.ip)
{ {
/* This can happen easily when the frame-chain gets truncated /* This can happen easily when the frame-chain gets truncated
due to bad or missing unwind-info. */ due to bad or missing unwind-info. */
Debug (1, "refusing to resume execution at address 0\n"); Debug (1, "refusing to resume execution at address 0\n");
return -UNW_EINVAL; return -UNW_EINVAL;
} }
@ -173,5 +173,5 @@ unw_resume (unw_cursor_t *cursor)
establish_machine_state (c); establish_machine_state (c);
return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c,
c->dwarf.as_arg); c->dwarf.as_arg);
} }

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY
Copyright (C) 2014 CERN and Aalto University Copyright (C) 2014 CERN and Aalto University
Contributed by Filip Nyback Contributed by Filip Nyback
This file is part of libunwind. This file is part of libunwind.
@ -33,16 +33,16 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
unw_tdep_frame_t *f = &c->frame_info; unw_tdep_frame_t *f = &c->frame_info;
Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld"
" ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] " " ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] "
"sp [where=%d val=%ld @0x%lx]\n", "sp [where=%d val=%ld @0x%lx]\n",
d->ip, d->cfa, f->frame_type, d->ip, d->cfa, f->frame_type,
rs->reg[DWARF_CFA_REG_COLUMN].where, rs->reg[DWARF_CFA_REG_COLUMN].where,
rs->reg[DWARF_CFA_REG_COLUMN].val, rs->reg[DWARF_CFA_REG_COLUMN].val,
rs->reg[DWARF_CFA_OFF_COLUMN].val, rs->reg[DWARF_CFA_OFF_COLUMN].val,
DWARF_GET_LOC(d->loc[d->ret_addr_column]), DWARF_GET_LOC(d->loc[d->ret_addr_column]),
rs->reg[FP].where, rs->reg[FP].val, DWARF_GET_LOC(d->loc[FP]), rs->reg[FP].where, rs->reg[FP].val, DWARF_GET_LOC(d->loc[FP]),
rs->reg[LR].where, rs->reg[LR].val, DWARF_GET_LOC(d->loc[LR]), rs->reg[LR].where, rs->reg[LR].val, DWARF_GET_LOC(d->loc[LR]),
rs->reg[SP].where, rs->reg[SP].val, DWARF_GET_LOC(d->loc[SP])); rs->reg[SP].where, rs->reg[SP].val, DWARF_GET_LOC(d->loc[SP]));
/* A standard frame is defined as: /* A standard frame is defined as:
- CFA is register-relative offset off FP or SP; - CFA is register-relative offset off FP or SP;
@ -53,24 +53,24 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
if (f->frame_type == UNW_AARCH64_FRAME_OTHER if (f->frame_type == UNW_AARCH64_FRAME_OTHER
&& (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) && (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG)
&& (rs->reg[DWARF_CFA_REG_COLUMN].val == FP && (rs->reg[DWARF_CFA_REG_COLUMN].val == FP
|| rs->reg[DWARF_CFA_REG_COLUMN].val == SP) || rs->reg[DWARF_CFA_REG_COLUMN].val == SP)
&& labs(rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29) && labs(rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29)
&& d->ret_addr_column == LR && d->ret_addr_column == LR
&& (rs->reg[FP].where == DWARF_WHERE_UNDEF && (rs->reg[FP].where == DWARF_WHERE_UNDEF
|| rs->reg[FP].where == DWARF_WHERE_SAME || rs->reg[FP].where == DWARF_WHERE_SAME
|| (rs->reg[FP].where == DWARF_WHERE_CFAREL || (rs->reg[FP].where == DWARF_WHERE_CFAREL
&& labs(rs->reg[FP].val) < (1 << 29) && labs(rs->reg[FP].val) < (1 << 29)
&& rs->reg[FP].val+1 != 0)) && rs->reg[FP].val+1 != 0))
&& (rs->reg[LR].where == DWARF_WHERE_UNDEF && (rs->reg[LR].where == DWARF_WHERE_UNDEF
|| rs->reg[LR].where == DWARF_WHERE_SAME || rs->reg[LR].where == DWARF_WHERE_SAME
|| (rs->reg[LR].where == DWARF_WHERE_CFAREL || (rs->reg[LR].where == DWARF_WHERE_CFAREL
&& labs(rs->reg[LR].val) < (1 << 29) && labs(rs->reg[LR].val) < (1 << 29)
&& rs->reg[LR].val+1 != 0)) && rs->reg[LR].val+1 != 0))
&& (rs->reg[SP].where == DWARF_WHERE_UNDEF && (rs->reg[SP].where == DWARF_WHERE_UNDEF
|| rs->reg[SP].where == DWARF_WHERE_SAME || rs->reg[SP].where == DWARF_WHERE_SAME
|| (rs->reg[SP].where == DWARF_WHERE_CFAREL || (rs->reg[SP].where == DWARF_WHERE_CFAREL
&& labs(rs->reg[SP].val) < (1 << 29) && labs(rs->reg[SP].val) < (1 << 29)
&& rs->reg[SP].val+1 != 0))) && rs->reg[SP].val+1 != 0)))
{ {
/* Save information for a standard frame. */ /* Save information for a standard frame. */
f->frame_type = UNW_AARCH64_FRAME_STANDARD; f->frame_type = UNW_AARCH64_FRAME_STANDARD;

View file

@ -112,7 +112,7 @@ unw_step (unw_cursor_t *cursor)
int ret; int ret;
Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n", Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n",
c, c->dwarf.ip, c->dwarf.cfa); c, c->dwarf.ip, c->dwarf.cfa);
/* Check if this is a signal frame. */ /* Check if this is a signal frame. */
if (unw_is_signal_frame (cursor)) if (unw_is_signal_frame (cursor))

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY
Copyright (C) 2014 CERN and Aalto University Copyright (C) 2014 CERN and Aalto University
Contributed by Filip Nyback Contributed by Filip Nyback
This file is part of libunwind. This file is part of libunwind.
@ -43,7 +43,7 @@ typedef struct
size_t log_size; size_t log_size;
size_t used; size_t used;
size_t dtor_count; /* Counts how many times our destructor has already size_t dtor_count; /* Counts how many times our destructor has already
been called. */ been called. */
} unw_trace_cache_t; } unw_trace_cache_t;
static const unw_tdep_frame_t empty_frame = { 0, UNW_AARCH64_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; static const unw_tdep_frame_t empty_frame = { 0, UNW_AARCH64_FRAME_OTHER, -1, -1, 0, -1, -1, -1 };
@ -65,7 +65,7 @@ trace_cache_free (void *arg)
/* Not yet our turn to get destroyed. Re-install ourselves into the key. */ /* Not yet our turn to get destroyed. Re-install ourselves into the key. */
pthread_setspecific(trace_cache_key, cache); pthread_setspecific(trace_cache_key, cache);
Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, Debug(5, "delayed freeing cache %p (%zx to go)\n", cache,
PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count);
return; return;
} }
tls_cache_destroyed = 1; tls_cache_destroyed = 1;
@ -111,7 +111,7 @@ trace_cache_create (void)
/* The current thread is in the process of exiting. Don't recreate /* The current thread is in the process of exiting. Don't recreate
cache, as we wouldn't have another chance to free it. */ cache, as we wouldn't have another chance to free it. */
Debug(5, "refusing to reallocate cache: " Debug(5, "refusing to reallocate cache: "
"thread-locals are being deallocated\n"); "thread-locals are being deallocated\n");
return NULL; return NULL;
} }
@ -214,11 +214,11 @@ trace_cache_get (void)
highly unusual unwind info which uses these creatively. */ highly unusual unwind info which uses these creatively. */
static unw_tdep_frame_t * static unw_tdep_frame_t *
trace_init_addr (unw_tdep_frame_t *f, trace_init_addr (unw_tdep_frame_t *f,
unw_cursor_t *cursor, unw_cursor_t *cursor,
unw_word_t cfa, unw_word_t cfa,
unw_word_t pc, unw_word_t pc,
unw_word_t fp, unw_word_t fp,
unw_word_t sp) unw_word_t sp)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
struct dwarf_cursor *d = &c->dwarf; struct dwarf_cursor *d = &c->dwarf;
@ -261,9 +261,9 @@ trace_init_addr (unw_tdep_frame_t *f,
f->last_frame = -1; f->last_frame = -1;
Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n",
f->virtual_address, f->frame_type, f->last_frame, f->virtual_address, f->frame_type, f->last_frame,
f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset, f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset,
f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset);
return f; return f;
} }
@ -274,11 +274,11 @@ trace_init_addr (unw_tdep_frame_t *f,
frame cache slot which describes RIP. */ frame cache slot which describes RIP. */
static unw_tdep_frame_t * static unw_tdep_frame_t *
trace_lookup (unw_cursor_t *cursor, trace_lookup (unw_cursor_t *cursor,
unw_trace_cache_t *cache, unw_trace_cache_t *cache,
unw_word_t cfa, unw_word_t cfa,
unw_word_t pc, unw_word_t pc,
unw_word_t fp, unw_word_t fp,
unw_word_t sp) unw_word_t sp)
{ {
/* First look up for previously cached information using cache as /* First look up for previously cached information using cache as
linear probing hash table with probe step of 1. Majority of linear probing hash table with probe step of 1. Majority of
@ -441,7 +441,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
{ {
pc -= d->use_prev_instr; pc -= d->use_prev_instr;
Debug (2, "depth %d cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", Debug (2, "depth %d cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n",
depth, cfa, pc, sp, fp); depth, cfa, pc, sp, fp);
/* See if we have this address cached. If not, evaluate enough of /* See if we have this address cached. If not, evaluate enough of
the dwarf unwind information to fill the cache line data, or to the dwarf unwind information to fill the cache line data, or to
@ -483,7 +483,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
/* Advance standard traceable frame. */ /* Advance standard traceable frame. */
cfa = (f->cfa_reg_sp ? sp : fp) + f->cfa_reg_offset; cfa = (f->cfa_reg_sp ? sp : fp) + f->cfa_reg_offset;
if (likely(f->lr_cfa_offset != -1)) if (likely(f->lr_cfa_offset != -1))
ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc);
else if (lr != 0) else if (lr != 0)
{ {
/* Use the saved link register as the new pc. */ /* Use the saved link register as the new pc. */
@ -491,7 +491,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
lr = 0; lr = 0;
} }
if (likely(ret >= 0) && likely(f->fp_cfa_offset != -1)) if (likely(ret >= 0) && likely(f->fp_cfa_offset != -1))
ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->fp_cfa_offset, fp); ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->fp_cfa_offset, fp);
/* Don't bother reading SP from DWARF, CFA becomes new SP. */ /* Don't bother reading SP from DWARF, CFA becomes new SP. */
sp = cfa; sp = cfa;
@ -523,14 +523,14 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
default: default:
/* We cannot trace through this frame, give up and tell the /* We cannot trace through this frame, give up and tell the
caller we had to stop. Data collected so far may still be caller we had to stop. Data collected so far may still be
useful to the caller, so let it know how far we got. */ useful to the caller, so let it know how far we got. */
ret = -UNW_ESTOPUNWIND; ret = -UNW_ESTOPUNWIND;
break; break;
} }
Debug (4, "new cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", Debug (4, "new cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n",
cfa, pc, sp, fp); cfa, pc, sp, fp);
/* If we failed or ended up somewhere bogus, stop. */ /* If we failed or ended up somewhere bogus, stop. */
if (unlikely(ret < 0 || pc < 0x4000)) if (unlikely(ret < 0 || pc < 0x4000))

View file

@ -4,46 +4,46 @@
/* Offsets for AArch64 Linux "ucontext_t": */ /* Offsets for AArch64 Linux "ucontext_t": */
#define LINUX_UC_FLAGS_OFF 0x0 #define LINUX_UC_FLAGS_OFF 0x0
#define LINUX_UC_LINK_OFF 0x8 #define LINUX_UC_LINK_OFF 0x8
#define LINUX_UC_STACK_OFF 0x10 #define LINUX_UC_STACK_OFF 0x10
#define LINUX_UC_SIGMASK_OFF 0x28 #define LINUX_UC_SIGMASK_OFF 0x28
#define LINUX_UC_MCONTEXT_OFF 0xb0 #define LINUX_UC_MCONTEXT_OFF 0xb0
/* Offsets for AArch64 Linux "struct sigcontext": */ /* Offsets for AArch64 Linux "struct sigcontext": */
#define LINUX_SC_FAULTADDRESS_OFF 0x00 #define LINUX_SC_FAULTADDRESS_OFF 0x00
#define LINUX_SC_X0_OFF 0x008 #define LINUX_SC_X0_OFF 0x008
#define LINUX_SC_X1_OFF 0x010 #define LINUX_SC_X1_OFF 0x010
#define LINUX_SC_X2_OFF 0x018 #define LINUX_SC_X2_OFF 0x018
#define LINUX_SC_X3_OFF 0x020 #define LINUX_SC_X3_OFF 0x020
#define LINUX_SC_X4_OFF 0x028 #define LINUX_SC_X4_OFF 0x028
#define LINUX_SC_X5_OFF 0x030 #define LINUX_SC_X5_OFF 0x030
#define LINUX_SC_X6_OFF 0x038 #define LINUX_SC_X6_OFF 0x038
#define LINUX_SC_X7_OFF 0x040 #define LINUX_SC_X7_OFF 0x040
#define LINUX_SC_X8_OFF 0x048 #define LINUX_SC_X8_OFF 0x048
#define LINUX_SC_X9_OFF 0x050 #define LINUX_SC_X9_OFF 0x050
#define LINUX_SC_X10_OFF 0x058 #define LINUX_SC_X10_OFF 0x058
#define LINUX_SC_X11_OFF 0x060 #define LINUX_SC_X11_OFF 0x060
#define LINUX_SC_X12_OFF 0x068 #define LINUX_SC_X12_OFF 0x068
#define LINUX_SC_X13_OFF 0x070 #define LINUX_SC_X13_OFF 0x070
#define LINUX_SC_X14_OFF 0x078 #define LINUX_SC_X14_OFF 0x078
#define LINUX_SC_X15_OFF 0x080 #define LINUX_SC_X15_OFF 0x080
#define LINUX_SC_X16_OFF 0x088 #define LINUX_SC_X16_OFF 0x088
#define LINUX_SC_X17_OFF 0x090 #define LINUX_SC_X17_OFF 0x090
#define LINUX_SC_X18_OFF 0x098 #define LINUX_SC_X18_OFF 0x098
#define LINUX_SC_X19_OFF 0x0a0 #define LINUX_SC_X19_OFF 0x0a0
#define LINUX_SC_X20_OFF 0x0a8 #define LINUX_SC_X20_OFF 0x0a8
#define LINUX_SC_X21_OFF 0x0b0 #define LINUX_SC_X21_OFF 0x0b0
#define LINUX_SC_X22_OFF 0x0b8 #define LINUX_SC_X22_OFF 0x0b8
#define LINUX_SC_X23_OFF 0x0c0 #define LINUX_SC_X23_OFF 0x0c0
#define LINUX_SC_X24_OFF 0x0c8 #define LINUX_SC_X24_OFF 0x0c8
#define LINUX_SC_X25_OFF 0x0d0 #define LINUX_SC_X25_OFF 0x0d0
#define LINUX_SC_X26_OFF 0x0d8 #define LINUX_SC_X26_OFF 0x0d8
#define LINUX_SC_X27_OFF 0x0e0 #define LINUX_SC_X27_OFF 0x0e0
#define LINUX_SC_X28_OFF 0x0e8 #define LINUX_SC_X28_OFF 0x0e8
#define LINUX_SC_X29_OFF 0x0f0 #define LINUX_SC_X29_OFF 0x0f0
#define LINUX_SC_X30_OFF 0x0f8 #define LINUX_SC_X30_OFF 0x0f8
#define LINUX_SC_SP_OFF 0x100 #define LINUX_SC_SP_OFF 0x100
#define LINUX_SC_PC_OFF 0x108 #define LINUX_SC_PC_OFF 0x108
#define LINUX_SC_PSTATE_OFF 0x110 #define LINUX_SC_PSTATE_OFF 0x110

View file

@ -33,19 +33,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "libunwind_i.h" #include "libunwind_i.h"
/* DWARF column numbers for AArch64: */ /* DWARF column numbers for AArch64: */
#define X29 29 #define X29 29
#define FP 29 #define FP 29
#define X30 30 #define X30 30
#define LR 30 #define LR 30
#define SP 31 #define SP 31
#define aarch64_lock UNW_OBJ(lock) #define aarch64_lock UNW_OBJ(lock)
#define aarch64_local_resume UNW_OBJ(local_resume) #define aarch64_local_resume UNW_OBJ(local_resume)
#define aarch64_local_addr_space_init UNW_OBJ(local_addr_space_init) #define aarch64_local_addr_space_init UNW_OBJ(local_addr_space_init)
extern void aarch64_local_addr_space_init (void); extern void aarch64_local_addr_space_init (void);
extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
void *arg); void *arg);
/* By-pass calls to access_mem() when known to be safe. */ /* By-pass calls to access_mem() when known to be safe. */
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY

View file

@ -30,14 +30,14 @@ http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
#include "libunwind_i.h" #include "libunwind_i.h"
#define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f) #define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f)
#define ARM_EXBUF_COUNT(x) ((x) & 0x0f) #define ARM_EXBUF_COUNT(x) ((x) & 0x0f)
#define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x)) #define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x))
#define ARM_EXIDX_CANT_UNWIND 0x00000001 #define ARM_EXIDX_CANT_UNWIND 0x00000001
#define ARM_EXIDX_COMPACT 0x80000000 #define ARM_EXIDX_COMPACT 0x80000000
#define ARM_EXTBL_OP_FINISH 0xb0 #define ARM_EXTBL_OP_FINISH 0xb0
enum arm_exbuf_cmd_flags { enum arm_exbuf_cmd_flags {
ARM_EXIDX_VFP_SHIFT_16 = 1 << 16, ARM_EXIDX_VFP_SHIFT_16 = 1 << 16,
@ -61,7 +61,7 @@ prel31_read (uint32_t prel31)
static inline int static inline int
prel31_to_addr (unw_addr_space_t as, void *arg, unw_word_t prel31, prel31_to_addr (unw_addr_space_t as, void *arg, unw_word_t prel31,
unw_word_t *val) unw_word_t *val)
{ {
unw_word_t offset; unw_word_t offset;
@ -88,7 +88,7 @@ arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c)
case ARM_EXIDX_CMD_FINISH: case ARM_EXIDX_CMD_FINISH:
/* Set LR to PC if not set already. */ /* Set LR to PC if not set already. */
if (DWARF_IS_NULL_LOC (c->loc[UNW_ARM_R15])) if (DWARF_IS_NULL_LOC (c->loc[UNW_ARM_R15]))
c->loc[UNW_ARM_R15] = c->loc[UNW_ARM_R14]; c->loc[UNW_ARM_R15] = c->loc[UNW_ARM_R14];
/* Set IP. */ /* Set IP. */
dwarf_get (c, c->loc[UNW_ARM_R15], &c->ip); dwarf_get (c, c->loc[UNW_ARM_R15], &c->ip);
break; break;
@ -102,15 +102,15 @@ arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c)
break; break;
case ARM_EXIDX_CMD_REG_POP: case ARM_EXIDX_CMD_REG_POP:
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
if (edata->data & (1 << i)) if (edata->data & (1 << i))
{ {
Debug (2, "pop {r%d}\n", i); Debug (2, "pop {r%d}\n", i);
c->loc[UNW_ARM_R0 + i] = DWARF_LOC (c->cfa, 0); c->loc[UNW_ARM_R0 + i] = DWARF_LOC (c->cfa, 0);
c->cfa += 4; c->cfa += 4;
} }
/* Set cfa in case the SP got popped. */ /* Set cfa in case the SP got popped. */
if (edata->data & (1 << 13)) if (edata->data & (1 << 13))
dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa);
break; break;
case ARM_EXIDX_CMD_REG_TO_SP: case ARM_EXIDX_CMD_REG_TO_SP:
assert (edata->data < 16); assert (edata->data < 16);
@ -121,20 +121,20 @@ arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c)
case ARM_EXIDX_CMD_VFP_POP: case ARM_EXIDX_CMD_VFP_POP:
/* Skip VFP registers, but be sure to adjust stack */ /* Skip VFP registers, but be sure to adjust stack */
for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data);
i++) i++)
c->cfa += 8; c->cfa += 8;
if (!(edata->data & ARM_EXIDX_VFP_DOUBLE)) if (!(edata->data & ARM_EXIDX_VFP_DOUBLE))
c->cfa += 4; c->cfa += 4;
break; break;
case ARM_EXIDX_CMD_WREG_POP: case ARM_EXIDX_CMD_WREG_POP:
for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data);
i++) i++)
c->cfa += 8; c->cfa += 8;
break; break;
case ARM_EXIDX_CMD_WCGR_POP: case ARM_EXIDX_CMD_WCGR_POP:
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (edata->data & (1 << i)) if (edata->data & (1 << i))
c->cfa += 4; c->cfa += 4;
break; break;
case ARM_EXIDX_CMD_REFUSED: case ARM_EXIDX_CMD_REFUSED:
case ARM_EXIDX_CMD_RESERVED: case ARM_EXIDX_CMD_RESERVED:
@ -163,119 +163,119 @@ arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c)
{ {
uint8_t op = READ_OP (); uint8_t op = READ_OP ();
if ((op & 0xc0) == 0x00) if ((op & 0xc0) == 0x00)
{ {
edata.cmd = ARM_EXIDX_CMD_DATA_POP; edata.cmd = ARM_EXIDX_CMD_DATA_POP;
edata.data = (((int)op & 0x3f) << 2) + 4; edata.data = (((int)op & 0x3f) << 2) + 4;
} }
else if ((op & 0xc0) == 0x40) else if ((op & 0xc0) == 0x40)
{ {
edata.cmd = ARM_EXIDX_CMD_DATA_PUSH; edata.cmd = ARM_EXIDX_CMD_DATA_PUSH;
edata.data = (((int)op & 0x3f) << 2) + 4; edata.data = (((int)op & 0x3f) << 2) + 4;
} }
else if ((op & 0xf0) == 0x80) else if ((op & 0xf0) == 0x80)
{ {
uint8_t op2 = READ_OP (); uint8_t op2 = READ_OP ();
if (op == 0x80 && op2 == 0x00) if (op == 0x80 && op2 == 0x00)
edata.cmd = ARM_EXIDX_CMD_REFUSED; edata.cmd = ARM_EXIDX_CMD_REFUSED;
else else
{ {
edata.cmd = ARM_EXIDX_CMD_REG_POP; edata.cmd = ARM_EXIDX_CMD_REG_POP;
edata.data = ((op & 0xf) << 8) | op2; edata.data = ((op & 0xf) << 8) | op2;
edata.data = edata.data << 4; edata.data = edata.data << 4;
} }
} }
else if ((op & 0xf0) == 0x90) else if ((op & 0xf0) == 0x90)
{ {
if (op == 0x9d || op == 0x9f) if (op == 0x9d || op == 0x9f)
edata.cmd = ARM_EXIDX_CMD_RESERVED; edata.cmd = ARM_EXIDX_CMD_RESERVED;
else else
{ {
edata.cmd = ARM_EXIDX_CMD_REG_TO_SP; edata.cmd = ARM_EXIDX_CMD_REG_TO_SP;
edata.data = op & 0x0f; edata.data = op & 0x0f;
} }
} }
else if ((op & 0xf0) == 0xa0) else if ((op & 0xf0) == 0xa0)
{ {
unsigned end = (op & 0x07); unsigned end = (op & 0x07);
edata.data = (1 << (end + 1)) - 1; edata.data = (1 << (end + 1)) - 1;
edata.data = edata.data << 4; edata.data = edata.data << 4;
if (op & 0x08) if (op & 0x08)
edata.data |= 1 << 14; edata.data |= 1 << 14;
edata.cmd = ARM_EXIDX_CMD_REG_POP; edata.cmd = ARM_EXIDX_CMD_REG_POP;
} }
else if (op == ARM_EXTBL_OP_FINISH) else if (op == ARM_EXTBL_OP_FINISH)
{ {
edata.cmd = ARM_EXIDX_CMD_FINISH; edata.cmd = ARM_EXIDX_CMD_FINISH;
buf = end; buf = end;
} }
else if (op == 0xb1) else if (op == 0xb1)
{ {
uint8_t op2 = READ_OP (); uint8_t op2 = READ_OP ();
if (op2 == 0 || (op2 & 0xf0)) if (op2 == 0 || (op2 & 0xf0))
edata.cmd = ARM_EXIDX_CMD_RESERVED; edata.cmd = ARM_EXIDX_CMD_RESERVED;
else else
{ {
edata.cmd = ARM_EXIDX_CMD_REG_POP; edata.cmd = ARM_EXIDX_CMD_REG_POP;
edata.data = op2 & 0x0f; edata.data = op2 & 0x0f;
} }
} }
else if (op == 0xb2) else if (op == 0xb2)
{ {
uint32_t offset = 0; uint32_t offset = 0;
uint8_t byte, shift = 0; uint8_t byte, shift = 0;
do do
{ {
byte = READ_OP (); byte = READ_OP ();
offset |= (byte & 0x7f) << shift; offset |= (byte & 0x7f) << shift;
shift += 7; shift += 7;
} }
while (byte & 0x80); while (byte & 0x80);
edata.data = offset * 4 + 0x204; edata.data = offset * 4 + 0x204;
edata.cmd = ARM_EXIDX_CMD_DATA_POP; edata.cmd = ARM_EXIDX_CMD_DATA_POP;
} }
else if (op == 0xb3 || op == 0xc8 || op == 0xc9) else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
{ {
edata.cmd = ARM_EXIDX_CMD_VFP_POP; edata.cmd = ARM_EXIDX_CMD_VFP_POP;
edata.data = READ_OP (); edata.data = READ_OP ();
if (op == 0xc8) if (op == 0xc8)
edata.data |= ARM_EXIDX_VFP_SHIFT_16; edata.data |= ARM_EXIDX_VFP_SHIFT_16;
if (op != 0xb3) if (op != 0xb3)
edata.data |= ARM_EXIDX_VFP_DOUBLE; edata.data |= ARM_EXIDX_VFP_DOUBLE;
} }
else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
{ {
edata.cmd = ARM_EXIDX_CMD_VFP_POP; edata.cmd = ARM_EXIDX_CMD_VFP_POP;
edata.data = 0x80 | (op & 0x07); edata.data = 0x80 | (op & 0x07);
if ((op & 0xf8) == 0xd0) if ((op & 0xf8) == 0xd0)
edata.data |= ARM_EXIDX_VFP_DOUBLE; edata.data |= ARM_EXIDX_VFP_DOUBLE;
} }
else if (op >= 0xc0 && op <= 0xc5) else if (op >= 0xc0 && op <= 0xc5)
{ {
edata.cmd = ARM_EXIDX_CMD_WREG_POP; edata.cmd = ARM_EXIDX_CMD_WREG_POP;
edata.data = 0xa0 | (op & 0x07); edata.data = 0xa0 | (op & 0x07);
} }
else if (op == 0xc6) else if (op == 0xc6)
{ {
edata.cmd = ARM_EXIDX_CMD_WREG_POP; edata.cmd = ARM_EXIDX_CMD_WREG_POP;
edata.data = READ_OP (); edata.data = READ_OP ();
} }
else if (op == 0xc7) else if (op == 0xc7)
{ {
uint8_t op2 = READ_OP (); uint8_t op2 = READ_OP ();
if (op2 == 0 || (op2 & 0xf0)) if (op2 == 0 || (op2 & 0xf0))
edata.cmd = ARM_EXIDX_CMD_RESERVED; edata.cmd = ARM_EXIDX_CMD_RESERVED;
else else
{ {
edata.cmd = ARM_EXIDX_CMD_WCGR_POP; edata.cmd = ARM_EXIDX_CMD_WCGR_POP;
edata.data = op2 & 0x0f; edata.data = op2 & 0x0f;
} }
} }
else else
edata.cmd = ARM_EXIDX_CMD_RESERVED; edata.cmd = ARM_EXIDX_CMD_RESERVED;
ret = arm_exidx_apply_cmd (&edata, c); ret = arm_exidx_apply_cmd (&edata, c);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
return 0; return 0;
} }
@ -299,7 +299,7 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
* if set to 0x1: the function cannot be unwound (EXIDX_CANTUNWIND) * if set to 0x1: the function cannot be unwound (EXIDX_CANTUNWIND)
* if bit 31 is one: this is a table entry itself (ARM_EXIDX_COMPACT) * if bit 31 is one: this is a table entry itself (ARM_EXIDX_COMPACT)
* if bit 31 is zero: this is a prel31 offset of the start of the * if bit 31 is zero: this is a prel31 offset of the start of the
table entry for this function */ table entry for this function */
if (prel31_to_addr(c->as, c->as_arg, entry, &addr) < 0) if (prel31_to_addr(c->as, c->as_arg, entry, &addr) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
@ -314,7 +314,7 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
else if (data & ARM_EXIDX_COMPACT) else if (data & ARM_EXIDX_COMPACT)
{ {
Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr,
(data >> 24) & 0x7f, data); (data >> 24) & 0x7f, data);
buf[nbuf++] = data >> 16; buf[nbuf++] = data >> 16;
buf[nbuf++] = data >> 8; buf[nbuf++] = data >> 8;
buf[nbuf++] = data; buf[nbuf++] = data;
@ -328,51 +328,51 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
return -UNW_EINVAL; return -UNW_EINVAL;
if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, c->as_arg) < 0) if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, c->as_arg) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
if (data & ARM_EXIDX_COMPACT) if (data & ARM_EXIDX_COMPACT)
{ {
int pers = (data >> 24) & 0x0f; int pers = (data >> 24) & 0x0f;
Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, pers, data); Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, pers, data);
if (pers == 1 || pers == 2) if (pers == 1 || pers == 2)
{ {
n_table_words = (data >> 16) & 0xff; n_table_words = (data >> 16) & 0xff;
extbl_data += 4; extbl_data += 4;
} }
else else
buf[nbuf++] = data >> 16; buf[nbuf++] = data >> 16;
buf[nbuf++] = data >> 8; buf[nbuf++] = data >> 8;
buf[nbuf++] = data; buf[nbuf++] = data;
} }
else else
{ {
unw_word_t pers; unw_word_t pers;
if (prel31_to_addr (c->as, c->as_arg, extbl_data, &pers) < 0) if (prel31_to_addr (c->as, c->as_arg, extbl_data, &pers) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
Debug (2, "%p Personality routine: %8p\n", (void *)addr, Debug (2, "%p Personality routine: %8p\n", (void *)addr,
(void *)pers); (void *)pers);
if ((*c->as->acc.access_mem)(c->as, extbl_data + 4, &data, 0, if ((*c->as->acc.access_mem)(c->as, extbl_data + 4, &data, 0,
c->as_arg) < 0) c->as_arg) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
n_table_words = data >> 24; n_table_words = data >> 24;
buf[nbuf++] = data >> 16; buf[nbuf++] = data >> 16;
buf[nbuf++] = data >> 8; buf[nbuf++] = data >> 8;
buf[nbuf++] = data; buf[nbuf++] = data;
extbl_data += 8; extbl_data += 8;
} }
assert (n_table_words <= 5); assert (n_table_words <= 5);
unsigned j; unsigned j;
for (j = 0; j < n_table_words; j++) for (j = 0; j < n_table_words; j++)
{ {
if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0,
c->as_arg) < 0) c->as_arg) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
extbl_data += 4; extbl_data += 4;
buf[nbuf++] = data >> 24; buf[nbuf++] = data >> 24;
buf[nbuf++] = data >> 16; buf[nbuf++] = data >> 16;
buf[nbuf++] = data >> 8; buf[nbuf++] = data >> 8;
buf[nbuf++] = data >> 0; buf[nbuf++] = data >> 0;
} }
} }
if (nbuf > 0 && buf[nbuf - 1] != ARM_EXTBL_OP_FINISH) if (nbuf > 0 && buf[nbuf - 1] != ARM_EXTBL_OP_FINISH)
@ -383,71 +383,71 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
PROTECTED int PROTECTED int
tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg) int need_unwind_info, void *arg)
{ {
if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX) if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)
&& di->format == UNW_INFO_FORMAT_ARM_EXIDX) && di->format == UNW_INFO_FORMAT_ARM_EXIDX)
{ {
/* The .ARM.exidx section contains a sorted list of key-value pairs - /* The .ARM.exidx section contains a sorted list of key-value pairs -
the unwind entries. The 'key' is a prel31 offset to the start of a the unwind entries. The 'key' is a prel31 offset to the start of a
function. We binary search this section in order to find the function. We binary search this section in order to find the
appropriate unwind entry. */ appropriate unwind entry. */
unw_word_t first = di->u.rti.table_data; unw_word_t first = di->u.rti.table_data;
unw_word_t last = di->u.rti.table_data + di->u.rti.table_len - 8; unw_word_t last = di->u.rti.table_data + di->u.rti.table_len - 8;
unw_word_t entry, val; unw_word_t entry, val;
if (prel31_to_addr (as, arg, first, &val) < 0 || ip < val) if (prel31_to_addr (as, arg, first, &val) < 0 || ip < val)
return -UNW_ENOINFO; return -UNW_ENOINFO;
if (prel31_to_addr (as, arg, last, &val) < 0) if (prel31_to_addr (as, arg, last, &val) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
if (ip >= val) if (ip >= val)
{ {
entry = last; entry = last;
if (prel31_to_addr (as, arg, last, &pi->start_ip) < 0) if (prel31_to_addr (as, arg, last, &pi->start_ip) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
pi->end_ip = di->end_ip -1; pi->end_ip = di->end_ip -1;
} }
else else
{ {
while (first < last - 8) while (first < last - 8)
{ {
entry = first + (((last - first) / 8 + 1) >> 1) * 8; entry = first + (((last - first) / 8 + 1) >> 1) * 8;
if (prel31_to_addr (as, arg, entry, &val) < 0) if (prel31_to_addr (as, arg, entry, &val) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
if (ip < val) if (ip < val)
last = entry; last = entry;
else else
first = entry; first = entry;
} }
entry = first; entry = first;
if (prel31_to_addr (as, arg, entry, &pi->start_ip) < 0) if (prel31_to_addr (as, arg, entry, &pi->start_ip) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
if (prel31_to_addr (as, arg, entry + 8, &pi->end_ip) < 0) if (prel31_to_addr (as, arg, entry + 8, &pi->end_ip) < 0)
return -UNW_EINVAL; return -UNW_EINVAL;
pi->end_ip--; pi->end_ip--;
} }
if (need_unwind_info) if (need_unwind_info)
{ {
pi->unwind_info_size = 8; pi->unwind_info_size = 8;
pi->unwind_info = (void *) entry; pi->unwind_info = (void *) entry;
pi->format = UNW_INFO_FORMAT_ARM_EXIDX; pi->format = UNW_INFO_FORMAT_ARM_EXIDX;
} }
return 0; return 0;
} }
else if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) else if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)
&& di->format != UNW_INFO_FORMAT_ARM_EXIDX) && di->format != UNW_INFO_FORMAT_ARM_EXIDX)
return dwarf_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); return dwarf_search_unwind_table (as, ip, di, pi, need_unwind_info, arg);
return -UNW_ENOINFO; return -UNW_ENOINFO;
@ -469,20 +469,20 @@ arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data)
for (n = info->dlpi_phnum; --n >= 0; phdr++) for (n = info->dlpi_phnum; --n >= 0; phdr++)
{ {
switch (phdr->p_type) switch (phdr->p_type)
{ {
case PT_LOAD: case PT_LOAD:
if (cb_data->ip >= phdr->p_vaddr + info->dlpi_addr && if (cb_data->ip >= phdr->p_vaddr + info->dlpi_addr &&
cb_data->ip < phdr->p_vaddr + info->dlpi_addr + phdr->p_memsz) cb_data->ip < phdr->p_vaddr + info->dlpi_addr + phdr->p_memsz)
p_text = phdr; p_text = phdr;
break; break;
case PT_ARM_EXIDX: case PT_ARM_EXIDX:
p_arm_exidx = phdr; p_arm_exidx = phdr;
break; break;
default: default:
break; break;
} }
} }
if (p_text && p_arm_exidx) if (p_text && p_arm_exidx)
@ -501,7 +501,7 @@ arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data)
HIDDEN int HIDDEN int
arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info, void *arg) unw_proc_info_t *pi, int need_unwind_info, void *arg)
{ {
int ret = -1; int ret = -1;
intrmask_t saved_mask; intrmask_t saved_mask;
@ -524,14 +524,14 @@ arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
if (cb_data.single_fde) if (cb_data.single_fde)
/* already got the result in *pi */ /* already got the result in *pi */
return 0; return 0;
if (cb_data.di_debug.format != -1) if (cb_data.di_debug.format != -1)
ret = tdep_search_unwind_table (as, ip, &cb_data.di_debug, pi, ret = tdep_search_unwind_table (as, ip, &cb_data.di_debug, pi,
need_unwind_info, arg); need_unwind_info, arg);
else else
ret = -UNW_ENOINFO; ret = -UNW_ENOINFO;
} }
if (ret < 0 && UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) if (ret < 0 && UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX))
@ -548,10 +548,10 @@ arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
if (cb_data.di.format != -1) if (cb_data.di.format != -1)
ret = tdep_search_unwind_table (as, ip, &cb_data.di, pi, ret = tdep_search_unwind_table (as, ip, &cb_data.di, pi,
need_unwind_info, arg); need_unwind_info, arg);
else else
ret = -UNW_ENOINFO; ret = -UNW_ENOINFO;
} }
if (ret < 0) if (ret < 0)

View file

@ -30,7 +30,7 @@ unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc)
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
dwarf_loc_t loc; dwarf_loc_t loc;
loc = DWARF_NULL_LOC; /* default to "not saved" */ loc = DWARF_NULL_LOC; /* default to "not saved" */
switch (reg) switch (reg)
{ {

View file

@ -58,7 +58,7 @@ tdep_init (void)
#ifndef UNW_REMOTE_ONLY #ifndef UNW_REMOTE_ONLY
arm_local_addr_space_init (); arm_local_addr_space_init ();
#endif #endif
tdep_init_done = 1; /* signal that we're initialized... */ tdep_init_done = 1; /* signal that we're initialized... */
} }
out: out:
lock_release (&arm_lock, saved_mask); lock_release (&arm_lock, saved_mask);

View file

@ -66,7 +66,7 @@ HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
static int static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg) void *arg)
{ {
*dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
return 0; return 0;
@ -74,7 +74,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
static int static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg) void *arg)
{ {
if (write) if (write)
{ {
@ -91,7 +91,7 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
static int static int
access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
void *arg) void *arg)
{ {
unw_word_t *addr; unw_word_t *addr;
unw_tdep_context_t *uc = arg; unw_tdep_context_t *uc = arg;
@ -122,7 +122,7 @@ Debug (16, "reg = %s\n", unw_regname (reg));
static int static int
access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg) int write, void *arg)
{ {
unw_tdep_context_t *uc = arg; unw_tdep_context_t *uc = arg;
unw_fpreg_t *addr; unw_fpreg_t *addr;
@ -136,14 +136,14 @@ access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
if (write) if (write)
{ {
Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg),
((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
*(unw_fpreg_t *) addr = *val; *(unw_fpreg_t *) addr = *val;
} }
else else
{ {
*val = *(unw_fpreg_t *) addr; *val = *(unw_fpreg_t *) addr;
Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg),
((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
} }
return 0; return 0;
@ -155,8 +155,8 @@ access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
static int static int
get_static_proc_name (unw_addr_space_t as, unw_word_t ip, get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp, char *buf, size_t buf_len, unw_word_t *offp,
void *arg) void *arg)
{ {
return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
} }

View file

@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
HIDDEN int HIDDEN int
tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
int write) int write)
{ {
dwarf_loc_t loc = DWARF_NULL_LOC; dwarf_loc_t loc = DWARF_NULL_LOC;
@ -74,7 +74,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
HIDDEN int HIDDEN int
tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
int write) int write)
{ {
Debug (1, "bad register number %u\n", reg); Debug (1, "bad register number %u\n", reg);
return -UNW_EBADREG; return -UNW_EBADREG;

View file

@ -39,7 +39,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
if (c->sigcontext_format == ARM_SCF_NONE) if (c->sigcontext_format == ARM_SCF_NONE)
{ {
/* Since there are no signals involved here we restore the non scratch /* Since there are no signals involved here we restore the non scratch
registers only. */ registers only. */
unsigned long regs[10]; unsigned long regs[10];
regs[0] = uc->regs[4]; regs[0] = uc->regs[4];
regs[1] = uc->regs[5]; regs[1] = uc->regs[5];
@ -53,21 +53,21 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
regs[9] = uc->regs[14]; /* LR */ regs[9] = uc->regs[14]; /* LR */
struct regs_overlay { struct regs_overlay {
char x[sizeof(regs)]; char x[sizeof(regs)];
}; };
asm __volatile__ ( asm __volatile__ (
"ldmia %0, {r4-r12, lr}\n" "ldmia %0, {r4-r12, lr}\n"
"mov sp, r12\n" "mov sp, r12\n"
"bx lr\n" "bx lr\n"
: : "r" (regs), : : "r" (regs),
"m" (*(struct regs_overlay *)regs) "m" (*(struct regs_overlay *)regs)
); );
} }
else else
{ {
/* In case a signal frame is involved, we're using its trampoline which /* In case a signal frame is involved, we're using its trampoline which
calls sigreturn. */ calls sigreturn. */
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
sc->arm_r0 = uc->regs[0]; sc->arm_r0 = uc->regs[0];
sc->arm_r1 = uc->regs[1]; sc->arm_r1 = uc->regs[1];
@ -89,11 +89,11 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
sc->arm_cpsr &= 0xf9ff03ffUL; sc->arm_cpsr &= 0xf9ff03ffUL;
/* Set the SP and the PC in order to continue execution at the modified /* Set the SP and the PC in order to continue execution at the modified
trampoline which restores the signal mask and the registers. */ trampoline which restores the signal mask and the registers. */
asm __volatile__ ( asm __volatile__ (
"mov sp, %0\n" "mov sp, %0\n"
"bx %1\n" "bx %1\n"
: : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc)
); );
} }
unreachable(); unreachable();
@ -120,15 +120,15 @@ establish_machine_state (struct cursor *c)
{ {
Debug (16, "copying %s %d\n", unw_regname (reg), reg); Debug (16, "copying %s %d\n", unw_regname (reg), reg);
if (unw_is_fpreg (reg)) if (unw_is_fpreg (reg))
{ {
if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
as->acc.access_fpreg (as, reg, &fpval, 1, arg); as->acc.access_fpreg (as, reg, &fpval, 1, arg);
} }
else else
{ {
if (tdep_access_reg (c, reg, &val, 0) >= 0) if (tdep_access_reg (c, reg, &val, 0) >= 0)
as->acc.access_reg (as, reg, &val, 1, arg); as->acc.access_reg (as, reg, &val, 1, arg);
} }
} }
} }
@ -142,7 +142,7 @@ unw_resume (unw_cursor_t *cursor)
if (!c->dwarf.ip) if (!c->dwarf.ip)
{ {
/* This can happen easily when the frame-chain gets truncated /* This can happen easily when the frame-chain gets truncated
due to bad or missing unwind-info. */ due to bad or missing unwind-info. */
Debug (1, "refusing to resume execution at address 0\n"); Debug (1, "refusing to resume execution at address 0\n");
return -UNW_EINVAL; return -UNW_EINVAL;
} }
@ -150,5 +150,5 @@ unw_resume (unw_cursor_t *cursor)
establish_machine_state (c); establish_machine_state (c);
return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c,
c->dwarf.as_arg); c->dwarf.as_arg);
} }

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY
Copyright (C) 2014 CERN and Aalto University Copyright (C) 2014 CERN and Aalto University
Contributed by Filip Nyback Contributed by Filip Nyback
This file is part of libunwind. This file is part of libunwind.
@ -33,16 +33,16 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
unw_tdep_frame_t *f = &c->frame_info; unw_tdep_frame_t *f = &c->frame_info;
Debug (4, "ip=0x%x cfa=0x%x type %d cfa [where=%d val=%d] cfaoff=%d" Debug (4, "ip=0x%x cfa=0x%x type %d cfa [where=%d val=%d] cfaoff=%d"
" ra=0x%x r7 [where=%d val=%d @0x%x] lr [where=%d val=%d @0x%x] " " ra=0x%x r7 [where=%d val=%d @0x%x] lr [where=%d val=%d @0x%x] "
"sp [where=%d val=%d @0x%x]\n", "sp [where=%d val=%d @0x%x]\n",
d->ip, d->cfa, f->frame_type, d->ip, d->cfa, f->frame_type,
rs->reg[DWARF_CFA_REG_COLUMN].where, rs->reg[DWARF_CFA_REG_COLUMN].where,
rs->reg[DWARF_CFA_REG_COLUMN].val, rs->reg[DWARF_CFA_REG_COLUMN].val,
rs->reg[DWARF_CFA_OFF_COLUMN].val, rs->reg[DWARF_CFA_OFF_COLUMN].val,
DWARF_GET_LOC(d->loc[d->ret_addr_column]), DWARF_GET_LOC(d->loc[d->ret_addr_column]),
rs->reg[R7].where, rs->reg[R7].val, DWARF_GET_LOC(d->loc[R7]), rs->reg[R7].where, rs->reg[R7].val, DWARF_GET_LOC(d->loc[R7]),
rs->reg[LR].where, rs->reg[LR].val, DWARF_GET_LOC(d->loc[LR]), rs->reg[LR].where, rs->reg[LR].val, DWARF_GET_LOC(d->loc[LR]),
rs->reg[SP].where, rs->reg[SP].val, DWARF_GET_LOC(d->loc[SP])); rs->reg[SP].where, rs->reg[SP].val, DWARF_GET_LOC(d->loc[SP]));
/* A standard frame is defined as: /* A standard frame is defined as:
- CFA is register-relative offset off R7 or SP; - CFA is register-relative offset off R7 or SP;
@ -53,24 +53,24 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
if (f->frame_type == UNW_ARM_FRAME_OTHER if (f->frame_type == UNW_ARM_FRAME_OTHER
&& (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) && (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG)
&& (rs->reg[DWARF_CFA_REG_COLUMN].val == R7 && (rs->reg[DWARF_CFA_REG_COLUMN].val == R7
|| rs->reg[DWARF_CFA_REG_COLUMN].val == SP) || rs->reg[DWARF_CFA_REG_COLUMN].val == SP)
&& labs(rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29) && labs(rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29)
&& d->ret_addr_column == LR && d->ret_addr_column == LR
&& (rs->reg[R7].where == DWARF_WHERE_UNDEF && (rs->reg[R7].where == DWARF_WHERE_UNDEF
|| rs->reg[R7].where == DWARF_WHERE_SAME || rs->reg[R7].where == DWARF_WHERE_SAME
|| (rs->reg[R7].where == DWARF_WHERE_CFAREL || (rs->reg[R7].where == DWARF_WHERE_CFAREL
&& labs(rs->reg[R7].val) < (1 << 29) && labs(rs->reg[R7].val) < (1 << 29)
&& rs->reg[R7].val+1 != 0)) && rs->reg[R7].val+1 != 0))
&& (rs->reg[LR].where == DWARF_WHERE_UNDEF && (rs->reg[LR].where == DWARF_WHERE_UNDEF
|| rs->reg[LR].where == DWARF_WHERE_SAME || rs->reg[LR].where == DWARF_WHERE_SAME
|| (rs->reg[LR].where == DWARF_WHERE_CFAREL || (rs->reg[LR].where == DWARF_WHERE_CFAREL
&& labs(rs->reg[LR].val) < (1 << 29) && labs(rs->reg[LR].val) < (1 << 29)
&& rs->reg[LR].val+1 != 0)) && rs->reg[LR].val+1 != 0))
&& (rs->reg[SP].where == DWARF_WHERE_UNDEF && (rs->reg[SP].where == DWARF_WHERE_UNDEF
|| rs->reg[SP].where == DWARF_WHERE_SAME || rs->reg[SP].where == DWARF_WHERE_SAME
|| (rs->reg[SP].where == DWARF_WHERE_CFAREL || (rs->reg[SP].where == DWARF_WHERE_CFAREL
&& labs(rs->reg[SP].val) < (1 << 29) && labs(rs->reg[SP].val) < (1 << 29)
&& rs->reg[SP].val+1 != 0))) && rs->reg[SP].val+1 != 0)))
{ {
/* Save information for a standard frame. */ /* Save information for a standard frame. */
f->frame_type = UNW_ARM_FRAME_STANDARD; f->frame_type = UNW_ARM_FRAME_STANDARD;

View file

@ -30,7 +30,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <signal.h> #include <signal.h>
#define arm_exidx_step UNW_OBJ(arm_exidx_step) #define arm_exidx_step UNW_OBJ(arm_exidx_step)
static inline int static inline int
arm_exidx_step (struct cursor *c) arm_exidx_step (struct cursor *c)
@ -64,7 +64,7 @@ arm_exidx_step (struct cursor *c)
if (c->dwarf.ip == old_ip && c->dwarf.cfa == old_cfa) if (c->dwarf.ip == old_ip && c->dwarf.cfa == old_cfa)
{ {
Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n",
__FUNCTION__, (long) c->dwarf.ip); __FUNCTION__, (long) c->dwarf.ip);
return -UNW_EBADFRAME; return -UNW_EBADFRAME;
} }
@ -103,32 +103,32 @@ unw_handle_signal_frame (unw_cursor_t *cursor)
if (ret == 1) if (ret == 1)
{ {
/* Handle non-RT signal frames. Check if the first word on the stack /* Handle non-RT signal frames. Check if the first word on the stack
is the magic number. */ is the magic number. */
if (sp == 0x5ac3c35a) if (sp == 0x5ac3c35a)
{ {
c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME; c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME;
sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF;
} }
else else
{ {
c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME; c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME;
sc_addr = sp_addr; sc_addr = sp_addr;
} }
} }
else if (ret == 2) else if (ret == 2)
{ {
/* Handle RT signal frames. Check if the first word on the stack is a /* Handle RT signal frames. Check if the first word on the stack is a
pointer to the siginfo structure. */ pointer to the siginfo structure. */
if (sp == sp_addr + 8) if (sp == sp_addr + 8)
{ {
c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME; c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME;
sc_addr = sp_addr + 8 + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; sc_addr = sp_addr + 8 + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF;
} }
else else
{ {
c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME; c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME;
sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF;
} }
} }
else else
return -UNW_EUNSPEC; return -UNW_EUNSPEC;
@ -186,9 +186,9 @@ unw_step (unw_cursor_t *cursor)
Debug(1, "dwarf_step()=%d\n", ret); Debug(1, "dwarf_step()=%d\n", ret);
if (likely (ret > 0)) if (likely (ret > 0))
return 1; return 1;
else if (unlikely (ret == -UNW_ESTOPUNWIND)) else if (unlikely (ret == -UNW_ESTOPUNWIND))
return ret; return ret;
if (ret < 0 && ret != -UNW_ENOINFO) if (ret < 0 && ret != -UNW_ENOINFO)
{ {
@ -203,9 +203,9 @@ unw_step (unw_cursor_t *cursor)
{ {
ret = arm_exidx_step (c); ret = arm_exidx_step (c);
if (ret > 0) if (ret > 0)
return 1; return 1;
if (ret == -UNW_ESTOPUNWIND || ret == 0) if (ret == -UNW_ESTOPUNWIND || ret == 0)
return ret; return ret;
} }
/* Fall back on APCS frame parsing. /* Fall back on APCS frame parsing.

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY
Copyright (C) 2014 CERN and Aalto University Copyright (C) 2014 CERN and Aalto University
Contributed by Filip Nyback Contributed by Filip Nyback
This file is part of libunwind. This file is part of libunwind.
@ -43,7 +43,7 @@ typedef struct
size_t log_size; size_t log_size;
size_t used; size_t used;
size_t dtor_count; /* Counts how many times our destructor has already size_t dtor_count; /* Counts how many times our destructor has already
been called. */ been called. */
} unw_trace_cache_t; } unw_trace_cache_t;
static const unw_tdep_frame_t empty_frame = { 0, UNW_ARM_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; static const unw_tdep_frame_t empty_frame = { 0, UNW_ARM_FRAME_OTHER, -1, -1, 0, -1, -1, -1 };
@ -65,7 +65,7 @@ trace_cache_free (void *arg)
/* Not yet our turn to get destroyed. Re-install ourselves into the key. */ /* Not yet our turn to get destroyed. Re-install ourselves into the key. */
pthread_setspecific(trace_cache_key, cache); pthread_setspecific(trace_cache_key, cache);
Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, Debug(5, "delayed freeing cache %p (%zx to go)\n", cache,
PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count);
return; return;
} }
tls_cache_destroyed = 1; tls_cache_destroyed = 1;
@ -111,7 +111,7 @@ trace_cache_create (void)
/* The current thread is in the process of exiting. Don't recreate /* The current thread is in the process of exiting. Don't recreate
cache, as we wouldn't have another chance to free it. */ cache, as we wouldn't have another chance to free it. */
Debug(5, "refusing to reallocate cache: " Debug(5, "refusing to reallocate cache: "
"thread-locals are being deallocated\n"); "thread-locals are being deallocated\n");
return NULL; return NULL;
} }
@ -215,11 +215,11 @@ trace_cache_get (void)
highly unusual unwind info which uses these creatively. */ highly unusual unwind info which uses these creatively. */
static unw_tdep_frame_t * static unw_tdep_frame_t *
trace_init_addr (unw_tdep_frame_t *f, trace_init_addr (unw_tdep_frame_t *f,
unw_cursor_t *cursor, unw_cursor_t *cursor,
unw_word_t cfa, unw_word_t cfa,
unw_word_t pc, unw_word_t pc,
unw_word_t r7, unw_word_t r7,
unw_word_t sp) unw_word_t sp)
{ {
struct cursor *c = (struct cursor *) cursor; struct cursor *c = (struct cursor *) cursor;
struct dwarf_cursor *d = &c->dwarf; struct dwarf_cursor *d = &c->dwarf;
@ -262,9 +262,9 @@ trace_init_addr (unw_tdep_frame_t *f,
f->last_frame = -1; f->last_frame = -1;
Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n",
f->virtual_address, f->frame_type, f->last_frame, f->virtual_address, f->frame_type, f->last_frame,
f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset, f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset,
f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset);
return f; return f;
} }
@ -275,11 +275,11 @@ trace_init_addr (unw_tdep_frame_t *f,
frame cache slot which describes RIP. */ frame cache slot which describes RIP. */
static unw_tdep_frame_t * static unw_tdep_frame_t *
trace_lookup (unw_cursor_t *cursor, trace_lookup (unw_cursor_t *cursor,
unw_trace_cache_t *cache, unw_trace_cache_t *cache,
unw_word_t cfa, unw_word_t cfa,
unw_word_t pc, unw_word_t pc,
unw_word_t r7, unw_word_t r7,
unw_word_t sp) unw_word_t sp)
{ {
/* First look up for previously cached information using cache as /* First look up for previously cached information using cache as
linear probing hash table with probe step of 1. Majority of linear probing hash table with probe step of 1. Majority of
@ -442,7 +442,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
{ {
pc -= d->use_prev_instr; pc -= d->use_prev_instr;
Debug (2, "depth %d cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", Debug (2, "depth %d cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n",
depth, cfa, pc, sp, r7); depth, cfa, pc, sp, r7);
/* See if we have this address cached. If not, evaluate enough of /* See if we have this address cached. If not, evaluate enough of
the dwarf unwind information to fill the cache line data, or to the dwarf unwind information to fill the cache line data, or to
@ -484,7 +484,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
/* Advance standard traceable frame. */ /* Advance standard traceable frame. */
cfa = (f->cfa_reg_sp ? sp : r7) + f->cfa_reg_offset; cfa = (f->cfa_reg_sp ? sp : r7) + f->cfa_reg_offset;
if (likely(f->lr_cfa_offset != -1)) if (likely(f->lr_cfa_offset != -1))
ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc);
else if (lr != 0) else if (lr != 0)
{ {
/* Use the saved link register as the new pc. */ /* Use the saved link register as the new pc. */
@ -492,7 +492,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
lr = 0; lr = 0;
} }
if (likely(ret >= 0) && likely(f->r7_cfa_offset != -1)) if (likely(ret >= 0) && likely(f->r7_cfa_offset != -1))
ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->r7_cfa_offset, r7); ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->r7_cfa_offset, r7);
/* Don't bother reading SP from DWARF, CFA becomes new SP. */ /* Don't bother reading SP from DWARF, CFA becomes new SP. */
sp = cfa; sp = cfa;
@ -524,14 +524,14 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
default: default:
/* We cannot trace through this frame, give up and tell the /* We cannot trace through this frame, give up and tell the
caller we had to stop. Data collected so far may still be caller we had to stop. Data collected so far may still be
useful to the caller, so let it know how far we got. */ useful to the caller, so let it know how far we got. */
ret = -UNW_ESTOPUNWIND; ret = -UNW_ESTOPUNWIND;
break; break;
} }
Debug (4, "new cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", Debug (4, "new cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n",
cfa, pc, sp, r7); cfa, pc, sp, r7);
/* If we failed or ended up somewhere bogus, stop. */ /* If we failed or ended up somewhere bogus, stop. */
if (unlikely(ret < 0 || pc < 0x4000)) if (unlikely(ret < 0 || pc < 0x4000))

View file

@ -54,7 +54,7 @@ common_init (struct cursor *c, unsigned use_prev_instr)
/* FIXME: correct for ARM? */ /* FIXME: correct for ARM? */
ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13), ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13),
&c->dwarf.cfa); &c->dwarf.cfa);
if (ret < 0) if (ret < 0)
return ret; return ret;

View file

@ -31,9 +31,9 @@ PROTECTED int
unw_is_fpreg (int regnum) unw_is_fpreg (int regnum)
{ {
return ((regnum >= UNW_ARM_S0 && regnum <= UNW_ARM_S31) return ((regnum >= UNW_ARM_S0 && regnum <= UNW_ARM_S31)
|| (regnum >= UNW_ARM_F0 && regnum <= UNW_ARM_F7) || (regnum >= UNW_ARM_F0 && regnum <= UNW_ARM_F7)
|| (regnum >= UNW_ARM_wCGR0 && regnum <= UNW_ARM_wCGR7) || (regnum >= UNW_ARM_wCGR0 && regnum <= UNW_ARM_wCGR7)
|| (regnum >= UNW_ARM_wR0 && regnum <= UNW_ARM_wR15) || (regnum >= UNW_ARM_wR0 && regnum <= UNW_ARM_wR15)
|| (regnum >= UNW_ARM_wC0 && regnum <= UNW_ARM_wC7) || (regnum >= UNW_ARM_wC0 && regnum <= UNW_ARM_wC7)
|| (regnum >= UNW_ARM_D0 && regnum <= UNW_ARM_D31)); || (regnum >= UNW_ARM_D0 && regnum <= UNW_ARM_D31));
} }

View file

@ -4,33 +4,33 @@
/* Offsets for ARM Linux "ucontext_t": */ /* Offsets for ARM Linux "ucontext_t": */
#define LINUX_UC_FLAGS_OFF 0x00 #define LINUX_UC_FLAGS_OFF 0x00
#define LINUX_UC_LINK_OFF 0x04 #define LINUX_UC_LINK_OFF 0x04
#define LINUX_UC_STACK_OFF 0x08 #define LINUX_UC_STACK_OFF 0x08
#define LINUX_UC_MCONTEXT_OFF 0x14 #define LINUX_UC_MCONTEXT_OFF 0x14
#define LINUX_UC_SIGMASK_OFF 0x68 #define LINUX_UC_SIGMASK_OFF 0x68
#define LINUX_UC_REGSPACE_OFF 0xE8 #define LINUX_UC_REGSPACE_OFF 0xE8
/* Offsets for ARM Linux "struct sigcontext": */ /* Offsets for ARM Linux "struct sigcontext": */
#define LINUX_SC_TRAPNO_OFF 0x00 #define LINUX_SC_TRAPNO_OFF 0x00
#define LINUX_SC_ERRORCODE_OFF 0x04 #define LINUX_SC_ERRORCODE_OFF 0x04
#define LINUX_SC_OLDMASK_OFF 0x08 #define LINUX_SC_OLDMASK_OFF 0x08
#define LINUX_SC_R0_OFF 0x0C #define LINUX_SC_R0_OFF 0x0C
#define LINUX_SC_R1_OFF 0x10 #define LINUX_SC_R1_OFF 0x10
#define LINUX_SC_R2_OFF 0x14 #define LINUX_SC_R2_OFF 0x14
#define LINUX_SC_R3_OFF 0x18 #define LINUX_SC_R3_OFF 0x18
#define LINUX_SC_R4_OFF 0x1C #define LINUX_SC_R4_OFF 0x1C
#define LINUX_SC_R5_OFF 0x20 #define LINUX_SC_R5_OFF 0x20
#define LINUX_SC_R6_OFF 0x24 #define LINUX_SC_R6_OFF 0x24
#define LINUX_SC_R7_OFF 0x28 #define LINUX_SC_R7_OFF 0x28
#define LINUX_SC_R8_OFF 0x2C #define LINUX_SC_R8_OFF 0x2C
#define LINUX_SC_R9_OFF 0x30 #define LINUX_SC_R9_OFF 0x30
#define LINUX_SC_R10_OFF 0x34 #define LINUX_SC_R10_OFF 0x34
#define LINUX_SC_FP_OFF 0x38 #define LINUX_SC_FP_OFF 0x38
#define LINUX_SC_IP_OFF 0x3C #define LINUX_SC_IP_OFF 0x3C
#define LINUX_SC_SP_OFF 0x40 #define LINUX_SC_SP_OFF 0x40
#define LINUX_SC_LR_OFF 0x44 #define LINUX_SC_LR_OFF 0x44
#define LINUX_SC_PC_OFF 0x48 #define LINUX_SC_PC_OFF 0x48
#define LINUX_SC_CPSR_OFF 0x4C #define LINUX_SC_CPSR_OFF 0x4C
#define LINUX_SC_FAULTADDR_OFF 0x50 #define LINUX_SC_FAULTADDR_OFF 0x50

View file

@ -32,18 +32,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "libunwind_i.h" #include "libunwind_i.h"
/* DWARF column numbers for ARM: */ /* DWARF column numbers for ARM: */
#define R7 7 #define R7 7
#define SP 13 #define SP 13
#define LR 14 #define LR 14
#define PC 15 #define PC 15
#define arm_lock UNW_OBJ(lock) #define arm_lock UNW_OBJ(lock)
#define arm_local_resume UNW_OBJ(local_resume) #define arm_local_resume UNW_OBJ(local_resume)
#define arm_local_addr_space_init UNW_OBJ(local_addr_space_init) #define arm_local_addr_space_init UNW_OBJ(local_addr_space_init)
extern void arm_local_addr_space_init (void); extern void arm_local_addr_space_init (void);
extern int arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, extern int arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
void *arg); void *arg);
/* By-pass calls to access_mem() when known to be safe. */ /* By-pass calls to access_mem() when known to be safe. */
#ifdef UNW_LOCAL_ONLY #ifdef UNW_LOCAL_ONLY
# undef ACCESS_MEM_FAST # undef ACCESS_MEM_FAST

View file

@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
int int
_UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val, _UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
int write, void *arg) int write, void *arg)
{ {
if (write) if (write)
{ {
@ -43,9 +43,9 @@ _UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
{ {
phdr = &ui->phdrs[i]; phdr = &ui->phdrs[i];
if (phdr->p_vaddr <= addr && addr_last < phdr->p_vaddr + phdr->p_memsz) if (phdr->p_vaddr <= addr && addr_last < phdr->p_vaddr + phdr->p_memsz)
{ {
goto found; goto found;
} }
} }
Debug(1, "addr 0x%llx is unmapped\n", (unsigned long long)addr); Debug(1, "addr 0x%llx is unmapped\n", (unsigned long long)addr);
return -UNW_EINVAL; return -UNW_EINVAL;
@ -62,8 +62,8 @@ _UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
if (phdr->backing_fd < 0) if (phdr->backing_fd < 0)
{ {
Debug(1, "access to not-present data in phdr[%d]: addr:0x%llx\n", Debug(1, "access to not-present data in phdr[%d]: addr:0x%llx\n",
i, (unsigned long long)addr i, (unsigned long long)addr
); );
return -UNW_EINVAL; return -UNW_EINVAL;
} }
filename = phdr->backing_filename; filename = phdr->backing_filename;
@ -82,17 +82,17 @@ _UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
goto read_error; goto read_error;
Debug(1, "0x%llx <- [addr:0x%llx fileofs:0x%llx]\n", Debug(1, "0x%llx <- [addr:0x%llx fileofs:0x%llx]\n",
(unsigned long long)(*val), (unsigned long long)(*val),
(unsigned long long)addr, (unsigned long long)addr,
(unsigned long long)fileofs (unsigned long long)fileofs
); );
return 0; return 0;
read_error: read_error:
Debug(1, "access out of file: addr:0x%llx fileofs:%llx file:'%s'\n", Debug(1, "access out of file: addr:0x%llx fileofs:%llx file:'%s'\n",
(unsigned long long)addr, (unsigned long long)addr,
(unsigned long long)fileofs, (unsigned long long)fileofs,
filename filename
); );
return -UNW_EINVAL; return -UNW_EINVAL;
} }

View file

@ -130,8 +130,8 @@ _UCD_access_reg (unw_addr_space_t as,
* image. * image.
*/ */
Debug(1, "pr_reg[%d]:%ld (0x%lx)\n", regnum, Debug(1, "pr_reg[%d]:%ld (0x%lx)\n", regnum,
(long)ui->prstatus->pr_reg[regnum], (long)ui->prstatus->pr_reg[regnum],
(long)ui->prstatus->pr_reg[regnum] (long)ui->prstatus->pr_reg[regnum]
); );
*valp = ui->prstatus->pr_reg[regnum]; *valp = ui->prstatus->pr_reg[regnum];

View file

@ -25,12 +25,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
PROTECTED unw_accessors_t _UCD_accessors = PROTECTED unw_accessors_t _UCD_accessors =
{ {
.find_proc_info = _UCD_find_proc_info, .find_proc_info = _UCD_find_proc_info,
.put_unwind_info = _UCD_put_unwind_info, .put_unwind_info = _UCD_put_unwind_info,
.get_dyn_info_list_addr = _UCD_get_dyn_info_list_addr, .get_dyn_info_list_addr = _UCD_get_dyn_info_list_addr,
.access_mem = _UCD_access_mem, .access_mem = _UCD_access_mem,
.access_reg = _UCD_access_reg, .access_reg = _UCD_access_reg,
.access_fpreg = _UCD_access_fpreg, .access_fpreg = _UCD_access_fpreg,
.resume = _UCD_resume, .resume = _UCD_resume,
.get_proc_name = _UCD_get_proc_name .get_proc_name = _UCD_get_proc_name
}; };

View file

@ -40,17 +40,17 @@ CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr)
/* addr, length, prot, flags, fd, fd_offset */ /* addr, length, prot, flags, fd, fd_offset */
ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset); ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset);
if (ei->image == MAP_FAILED) if (ei->image == MAP_FAILED)
{ {
ei->image = NULL; ei->image = NULL;
return NULL; return NULL;
} }
ei->size = phdr->p_filesz; ei->size = phdr->p_filesz;
size_t remainder_len = phdr->p_memsz - phdr->p_filesz; size_t remainder_len = phdr->p_memsz - phdr->p_filesz;
if (remainder_len > 0) if (remainder_len > 0)
{ {
void *remainder_base = (char*) ei->image + phdr->p_filesz; void *remainder_base = (char*) ei->image + phdr->p_filesz;
munmap(remainder_base, remainder_len); munmap(remainder_base, remainder_len);
} }
} else { } else {
/* We have a backing file for this segment. /* We have a backing file for this segment.
* This file is always longer than phdr->p_memsz, * This file is always longer than phdr->p_memsz,
@ -62,10 +62,10 @@ CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr)
/* addr, length, prot, flags, fd, fd_offset */ /* addr, length, prot, flags, fd, fd_offset */
ei->image = mmap(NULL, phdr->backing_filesize, PROT_READ, MAP_PRIVATE, phdr->backing_fd, 0); ei->image = mmap(NULL, phdr->backing_filesize, PROT_READ, MAP_PRIVATE, phdr->backing_fd, 0);
if (ei->image == MAP_FAILED) if (ei->image == MAP_FAILED)
{ {
ei->image = NULL; ei->image = NULL;
return NULL; return NULL;
} }
ei->size = phdr->backing_filesize; ei->size = phdr->backing_filesize;
} }
@ -89,10 +89,10 @@ _UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip)
{ {
coredump_phdr_t *phdr = &ui->phdrs[i]; coredump_phdr_t *phdr = &ui->phdrs[i];
if (phdr->p_vaddr <= ip && ip < phdr->p_vaddr + phdr->p_memsz) if (phdr->p_vaddr <= ip && ip < phdr->p_vaddr + phdr->p_memsz)
{ {
phdr = CD_elf_map_image(ui, phdr); phdr = CD_elf_map_image(ui, phdr);
return phdr; return phdr;
} }
} }
return NULL; return NULL;
} }

View file

@ -102,7 +102,7 @@ get_unwind_info(struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip)
int int
_UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, _UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
int need_unwind_info, void *arg) int need_unwind_info, void *arg)
{ {
struct UCD_info *ui = arg; struct UCD_info *ui = arg;
@ -119,33 +119,33 @@ _UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
if (ui->edi.ktab.format != -1) if (ui->edi.ktab.format != -1)
{ {
/* The kernel unwind table resides in local memory, so we have /* The kernel unwind table resides in local memory, so we have
to use the local address space to search it. Since to use the local address space to search it. Since
_UCD_put_unwind_info() has no easy way of detecting this _UCD_put_unwind_info() has no easy way of detecting this
case, we simply make a copy of the unwind-info, so case, we simply make a copy of the unwind-info, so
_UCD_put_unwind_info() can always free() the unwind-info _UCD_put_unwind_info() can always free() the unwind-info
without ill effects. */ without ill effects. */
ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi,
need_unwind_info, arg); need_unwind_info, arg);
if (ret >= 0) if (ret >= 0)
{ {
if (!need_unwind_info) if (!need_unwind_info)
pi->unwind_info = NULL; pi->unwind_info = NULL;
else else
{ {
void *mem = malloc (pi->unwind_info_size); void *mem = malloc (pi->unwind_info_size);
if (!mem) if (!mem)
return -UNW_ENOMEM; return -UNW_ENOMEM;
memcpy (mem, pi->unwind_info, pi->unwind_info_size); memcpy (mem, pi->unwind_info, pi->unwind_info_size);
pi->unwind_info = mem; pi->unwind_info = mem;
} }
} }
} }
#endif #endif
if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1)
ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache,
pi, need_unwind_info, arg); pi, need_unwind_info, arg);
#if UNW_TARGET_ARM #if UNW_TARGET_ARM
if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1)
@ -155,7 +155,7 @@ _UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1)
ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi,
need_unwind_info, arg); need_unwind_info, arg);
Debug(1, "returns %d\n", ret); Debug(1, "returns %d\n", ret);

View file

@ -31,7 +31,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
sensitive to the performance of this routine, why bother... */ sensitive to the performance of this routine, why bother... */
static int static int
elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip, elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp) char *buf, size_t buf_len, unw_word_t *offp)
{ {
unsigned long segbase, mapoff; unsigned long segbase, mapoff;
int ret; int ret;
@ -56,7 +56,7 @@ elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t i
int int
_UCD_get_proc_name (unw_addr_space_t as, unw_word_t ip, _UCD_get_proc_name (unw_addr_space_t as, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp, void *arg) char *buf, size_t buf_len, unw_word_t *offp, void *arg)
{ {
struct UCD_info *ui = arg; struct UCD_info *ui = arg;

View file

@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
int int
_UCD_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, _UCD_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg) int write, void *arg)
{ {
print_error (__func__); print_error (__func__);
print_error (" not implemented\n"); print_error (" not implemented\n");

View file

@ -1,5 +1,5 @@
/* We need to get a separate copy of the ELF-code into /* We need to get a separate copy of the ELF-code into
libunwind-coredump since it cannot (and must not) have any ELF libunwind-coredump since it cannot (and must not) have any ELF
dependencies on libunwind. */ dependencies on libunwind. */
#include "libunwind_i.h" /* get ELFCLASS defined */ #include "libunwind_i.h" /* get ELFCLASS defined */
#include "../elfxx.c" #include "../elfxx.c"

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003-2005 Hewlett-Packard Co Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -32,7 +32,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
static inline int static inline int
get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
int *countp) int *countp)
{ {
unsigned long lo, hi, off; unsigned long lo, hi, off;
struct UPT_info *ui = arg; struct UPT_info *ui = arg;
@ -46,26 +46,26 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
while (maps_next (&mi, &lo, &hi, &off)) while (maps_next (&mi, &lo, &hi, &off))
{ {
if (off) if (off)
continue; continue;
invalidate_edi (&ui->edi); invalidate_edi (&ui->edi);
if (elf_map_image (&ui->ei, path) < 0) if (elf_map_image (&ui->ei, path) < 0)
/* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */
continue; continue;
Debug (16, "checking object %s\n", path); Debug (16, "checking object %s\n", path);
di = tdep_find_unwind_table (&ui->edi, as, path, lo, off); di = tdep_find_unwind_table (&ui->edi, as, path, lo, off);
if (di) if (di)
{ {
res = _Uia64_find_dyn_list (as, di, arg); res = _Uia64_find_dyn_list (as, di, arg);
if (res && count++ == 0) if (res && count++ == 0)
{ {
Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res);
*dil_addr = res; *dil_addr = res;
} }
} }
} }
maps_close (&mi); maps_close (&mi);
*countp = count; *countp = count;
@ -76,7 +76,7 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
static inline int static inline int
get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
int *countp) int *countp)
{ {
# warning Implement get_list_addr(), please. # warning Implement get_list_addr(), please.
*countp = 0; *countp = 0;
@ -87,7 +87,7 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
int int
_UCD_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, _UCD_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr,
void *arg) void *arg)
{ {
int count, ret; int count, ret;

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co Copyright (C) 2003 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003 Hewlett-Packard Co Copyright (C) 2003 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -44,8 +44,8 @@ is_cie_id (unw_word_t val, int is_debug_frame)
repeated. */ repeated. */
static inline int static inline int
parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
const unw_proc_info_t *pi, struct dwarf_cie_info *dci, const unw_proc_info_t *pi, struct dwarf_cie_info *dci,
unw_word_t base, void *arg) unw_word_t base, void *arg)
{ {
uint8_t version, ch, augstr[5], fde_encoding, handler_encoding; uint8_t version, ch, augstr[5], fde_encoding, handler_encoding;
unw_word_t len, cie_end_addr, aug_size; unw_word_t len, cie_end_addr, aug_size;
@ -53,8 +53,8 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
uint64_t u64val; uint64_t u64val;
size_t i; size_t i;
int ret; int ret;
# define STR2(x) #x # define STR2(x) #x
# define STR(x) STR2(x) # define STR(x) STR2(x)
/* Pick appropriate default for FDE-encoding. DWARF spec says /* Pick appropriate default for FDE-encoding. DWARF spec says
start-IP (initial_location) and the code-size (address_range) are start-IP (initial_location) and the code-size (address_range) are
@ -63,9 +63,9 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
for fde_encoding. */ for fde_encoding. */
switch (dwarf_addr_size (as)) switch (dwarf_addr_size (as))
{ {
case 4: fde_encoding = DW_EH_PE_udata4; break; case 4: fde_encoding = DW_EH_PE_udata4; break;
case 8: fde_encoding = DW_EH_PE_udata8; break; case 8: fde_encoding = DW_EH_PE_udata8; break;
default: fde_encoding = DW_EH_PE_omit; break; default: fde_encoding = DW_EH_PE_omit; break;
} }
dci->lsda_encoding = DW_EH_PE_omit; dci->lsda_encoding = DW_EH_PE_omit;
@ -84,32 +84,32 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
len = u32val; len = u32val;
cie_end_addr = addr + len; cie_end_addr = addr + len;
if ((ret = dwarf_readu32 (as, a, &addr, &cie_id, arg)) < 0) if ((ret = dwarf_readu32 (as, a, &addr, &cie_id, arg)) < 0)
return ret; return ret;
if (cie_id != expected_id) if (cie_id != expected_id)
{ {
Debug (1, "Unexpected CIE id %x\n", cie_id); Debug (1, "Unexpected CIE id %x\n", cie_id);
return -UNW_EINVAL; return -UNW_EINVAL;
} }
} }
else else
{ {
/* the CIE is in the 64-bit DWARF format */ /* the CIE is in the 64-bit DWARF format */
uint64_t cie_id; uint64_t cie_id;
/* DWARF says CIE id should be 0xffffffffffffffff, but in /* DWARF says CIE id should be 0xffffffffffffffff, but in
.eh_frame, it's 0 */ .eh_frame, it's 0 */
const uint64_t expected_id = (base) ? 0xffffffffffffffffull : 0; const uint64_t expected_id = (base) ? 0xffffffffffffffffull : 0;
if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0)
return ret; return ret;
len = u64val; len = u64val;
cie_end_addr = addr + len; cie_end_addr = addr + len;
if ((ret = dwarf_readu64 (as, a, &addr, &cie_id, arg)) < 0) if ((ret = dwarf_readu64 (as, a, &addr, &cie_id, arg)) < 0)
return ret; return ret;
if (cie_id != expected_id) if (cie_id != expected_id)
{ {
Debug (1, "Unexpected CIE id %llx\n", (long long) cie_id); Debug (1, "Unexpected CIE id %llx\n", (long long) cie_id);
return -UNW_EINVAL; return -UNW_EINVAL;
} }
} }
dci->cie_instr_end = cie_end_addr; dci->cie_instr_end = cie_end_addr;
@ -119,7 +119,7 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
if (version != 1 && version != DWARF_CIE_VERSION) if (version != 1 && version != DWARF_CIE_VERSION)
{ {
Debug (1, "Got CIE version %u, expected version 1 or " Debug (1, "Got CIE version %u, expected version 1 or "
STR (DWARF_CIE_VERSION) "\n", version); STR (DWARF_CIE_VERSION) "\n", version);
return -UNW_EBADVERSION; return -UNW_EBADVERSION;
} }
@ -128,13 +128,13 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
for (i = 0;;) for (i = 0;;)
{ {
if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0)
return ret; return ret;
if (!ch) if (!ch)
break; /* end of augmentation string */ break; /* end of augmentation string */
if (i < sizeof (augstr) - 1) if (i < sizeof (augstr) - 1)
augstr[i++] = ch; augstr[i++] = ch;
} }
if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->code_align, arg)) < 0 if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->code_align, arg)) < 0
@ -145,11 +145,11 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
if (version == 1) if (version == 1)
{ {
if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0)
return ret; return ret;
dci->ret_addr_column = ch; dci->ret_addr_column = ch;
} }
else if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->ret_addr_column, else if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->ret_addr_column,
arg)) < 0) arg)) < 0)
return ret; return ret;
i = 0; i = 0;
@ -157,7 +157,7 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
{ {
dci->sized_augmentation = 1; dci->sized_augmentation = 1;
if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0)
return ret; return ret;
i++; i++;
} }
@ -165,50 +165,50 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
switch (augstr[i]) switch (augstr[i])
{ {
case 'L': case 'L':
/* read the LSDA pointer-encoding format. */ /* read the LSDA pointer-encoding format. */
if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0)
return ret; return ret;
dci->lsda_encoding = ch; dci->lsda_encoding = ch;
break; break;
case 'R': case 'R':
/* read the FDE pointer-encoding format. */ /* read the FDE pointer-encoding format. */
if ((ret = dwarf_readu8 (as, a, &addr, &fde_encoding, arg)) < 0) if ((ret = dwarf_readu8 (as, a, &addr, &fde_encoding, arg)) < 0)
return ret; return ret;
break; break;
case 'P': case 'P':
/* read the personality-routine pointer-encoding format. */ /* read the personality-routine pointer-encoding format. */
if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0) if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0)
return ret; return ret;
if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding, if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding,
pi, &dci->handler, arg)) < 0) pi, &dci->handler, arg)) < 0)
return ret; return ret;
break; break;
case 'S': case 'S':
/* This is a signal frame. */ /* This is a signal frame. */
dci->signal_frame = 1; dci->signal_frame = 1;
/* Temporarily set it to one so dwarf_parse_fde() knows that /* Temporarily set it to one so dwarf_parse_fde() knows that
it should fetch the actual ABI/TAG pair from the FDE. */ it should fetch the actual ABI/TAG pair from the FDE. */
dci->have_abi_marker = 1; dci->have_abi_marker = 1;
break; break;
default: default:
Debug (1, "Unexpected augmentation string `%s'\n", augstr); Debug (1, "Unexpected augmentation string `%s'\n", augstr);
if (dci->sized_augmentation) if (dci->sized_augmentation)
/* If we have the size of the augmentation body, we can skip /* If we have the size of the augmentation body, we can skip
over the parts that we don't understand, so we're OK. */ over the parts that we don't understand, so we're OK. */
goto done; goto done;
else else
return -UNW_EINVAL; return -UNW_EINVAL;
} }
done: done:
dci->fde_encoding = fde_encoding; dci->fde_encoding = fde_encoding;
dci->cie_instr_start = addr; dci->cie_instr_start = addr;
Debug (15, "CIE parsed OK, augmentation = \"%s\", handler=0x%lx\n", Debug (15, "CIE parsed OK, augmentation = \"%s\", handler=0x%lx\n",
augstr, (long) dci->handler); augstr, (long) dci->handler);
return 0; return 0;
} }
@ -219,9 +219,9 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
HIDDEN int HIDDEN int
dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a, dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addrp, unw_proc_info_t *pi, unw_word_t *addrp, unw_proc_info_t *pi,
int need_unwind_info, unw_word_t base, int need_unwind_info, unw_word_t base,
void *arg) void *arg)
{ {
unw_word_t fde_end_addr, cie_addr, cie_offset_addr, aug_end_addr = 0; unw_word_t fde_end_addr, cie_addr, cie_offset_addr, aug_end_addr = 0;
unw_word_t start_ip, ip_range, aug_size, addr = *addrp; unw_word_t start_ip, ip_range, aug_size, addr = *addrp;
@ -242,9 +242,9 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
int32_t cie_offset; int32_t cie_offset;
/* In some configurations, an FDE with a 0 length indicates the /* In some configurations, an FDE with a 0 length indicates the
end of the FDE-table. */ end of the FDE-table. */
if (u32val == 0) if (u32val == 0)
return -UNW_ENOINFO; return -UNW_ENOINFO;
/* the FDE is in the 32-bit DWARF format */ /* the FDE is in the 32-bit DWARF format */
@ -252,20 +252,20 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
cie_offset_addr = addr; cie_offset_addr = addr;
if ((ret = dwarf_reads32 (as, a, &addr, &cie_offset, arg)) < 0) if ((ret = dwarf_reads32 (as, a, &addr, &cie_offset, arg)) < 0)
return ret; return ret;
if (is_cie_id (cie_offset, base != 0)) if (is_cie_id (cie_offset, base != 0))
/* ignore CIEs (happens during linear searches) */ /* ignore CIEs (happens during linear searches) */
return 0; return 0;
if (base != 0) if (base != 0)
cie_addr = base + cie_offset; cie_addr = base + cie_offset;
else else
/* DWARF says that the CIE_pointer in the FDE is a /* DWARF says that the CIE_pointer in the FDE is a
.debug_frame-relative offset, but the GCC-generated .eh_frame .debug_frame-relative offset, but the GCC-generated .eh_frame
sections instead store a "pcrelative" offset, which is just sections instead store a "pcrelative" offset, which is just
as fine as it's self-contained. */ as fine as it's self-contained. */
cie_addr = cie_offset_addr - cie_offset; cie_addr = cie_offset_addr - cie_offset;
} }
else else
{ {
@ -274,26 +274,26 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
/* the FDE is in the 64-bit DWARF format */ /* the FDE is in the 64-bit DWARF format */
if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0)
return ret; return ret;
*addrp = fde_end_addr = addr + u64val; *addrp = fde_end_addr = addr + u64val;
cie_offset_addr = addr; cie_offset_addr = addr;
if ((ret = dwarf_reads64 (as, a, &addr, &cie_offset, arg)) < 0) if ((ret = dwarf_reads64 (as, a, &addr, &cie_offset, arg)) < 0)
return ret; return ret;
if (is_cie_id (cie_offset, base != 0)) if (is_cie_id (cie_offset, base != 0))
/* ignore CIEs (happens during linear searches) */ /* ignore CIEs (happens during linear searches) */
return 0; return 0;
if (base != 0) if (base != 0)
cie_addr = base + cie_offset; cie_addr = base + cie_offset;
else else
/* DWARF says that the CIE_pointer in the FDE is a /* DWARF says that the CIE_pointer in the FDE is a
.debug_frame-relative offset, but the GCC-generated .eh_frame .debug_frame-relative offset, but the GCC-generated .eh_frame
sections instead store a "pcrelative" offset, which is just sections instead store a "pcrelative" offset, which is just
as fine as it's self-contained. */ as fine as it's self-contained. */
cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset); cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset);
} }
Debug (15, "looking for CIE at address %lx\n", (long) cie_addr); Debug (15, "looking for CIE at address %lx\n", (long) cie_addr);
@ -306,9 +306,9 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
ip_range_encoding = dci.fde_encoding & DW_EH_PE_FORMAT_MASK; ip_range_encoding = dci.fde_encoding & DW_EH_PE_FORMAT_MASK;
if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.fde_encoding, if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.fde_encoding,
pi, &start_ip, arg)) < 0 pi, &start_ip, arg)) < 0
|| (ret = dwarf_read_encoded_pointer (as, a, &addr, ip_range_encoding, || (ret = dwarf_read_encoded_pointer (as, a, &addr, ip_range_encoding,
pi, &ip_range, arg)) < 0) pi, &ip_range, arg)) < 0)
return ret; return ret;
pi->start_ip = start_ip; pi->start_ip = start_ip;
pi->end_ip = start_ip + ip_range; pi->end_ip = start_ip + ip_range;
@ -317,16 +317,16 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
if (dci.sized_augmentation) if (dci.sized_augmentation)
{ {
if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0)
return ret; return ret;
aug_end_addr = addr + aug_size; aug_end_addr = addr + aug_size;
} }
if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.lsda_encoding, if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.lsda_encoding,
pi, &pi->lsda, arg)) < 0) pi, &pi->lsda, arg)) < 0)
return ret; return ret;
Debug (15, "FDE covers IP 0x%lx-0x%lx, LSDA=0x%lx\n", Debug (15, "FDE covers IP 0x%lx-0x%lx, LSDA=0x%lx\n",
(long) pi->start_ip, (long) pi->end_ip, (long) pi->lsda); (long) pi->start_ip, (long) pi->end_ip, (long) pi->lsda);
if (need_unwind_info) if (need_unwind_info)
{ {
@ -334,21 +334,21 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
pi->unwind_info_size = sizeof (dci); pi->unwind_info_size = sizeof (dci);
pi->unwind_info = mempool_alloc (&dwarf_cie_info_pool); pi->unwind_info = mempool_alloc (&dwarf_cie_info_pool);
if (!pi->unwind_info) if (!pi->unwind_info)
return -UNW_ENOMEM; return -UNW_ENOMEM;
if (dci.have_abi_marker) if (dci.have_abi_marker)
{ {
if ((ret = dwarf_readu16 (as, a, &addr, &dci.abi, arg)) < 0 if ((ret = dwarf_readu16 (as, a, &addr, &dci.abi, arg)) < 0
|| (ret = dwarf_readu16 (as, a, &addr, &dci.tag, arg)) < 0) || (ret = dwarf_readu16 (as, a, &addr, &dci.tag, arg)) < 0)
return ret; return ret;
Debug (13, "Found ABI marker = (abi=%u, tag=%u)\n", Debug (13, "Found ABI marker = (abi=%u, tag=%u)\n",
dci.abi, dci.tag); dci.abi, dci.tag);
} }
if (dci.sized_augmentation) if (dci.sized_augmentation)
dci.fde_instr_start = aug_end_addr; dci.fde_instr_start = aug_end_addr;
else else
dci.fde_instr_start = addr; dci.fde_instr_start = addr;
dci.fde_instr_end = fde_end_addr; dci.fde_instr_end = fde_end_addr;
memcpy (pi->unwind_info, &dci, sizeof (dci)); memcpy (pi->unwind_info, &dci, sizeof (dci));

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -48,9 +48,9 @@ struct table_entry
static int static int
linear_search (unw_addr_space_t as, unw_word_t ip, linear_search (unw_addr_space_t as, unw_word_t ip,
unw_word_t eh_frame_start, unw_word_t eh_frame_end, unw_word_t eh_frame_start, unw_word_t eh_frame_end,
unw_word_t fde_count, unw_word_t fde_count,
unw_proc_info_t *pi, int need_unwind_info, void *arg) unw_proc_info_t *pi, int need_unwind_info, void *arg)
{ {
unw_accessors_t *a = unw_get_accessors (unw_local_addr_space); unw_accessors_t *a = unw_get_accessors (unw_local_addr_space);
unw_word_t i = 0, fde_addr, addr = eh_frame_start; unw_word_t i = 0, fde_addr, addr = eh_frame_start;
@ -60,21 +60,21 @@ linear_search (unw_addr_space_t as, unw_word_t ip,
{ {
fde_addr = addr; fde_addr = addr;
if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, 0, 0, arg)) if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, 0, 0, arg))
< 0) < 0)
return ret; return ret;
if (ip >= pi->start_ip && ip < pi->end_ip) if (ip >= pi->start_ip && ip < pi->end_ip)
{ {
if (!need_unwind_info) if (!need_unwind_info)
return 1; return 1;
addr = fde_addr; addr = fde_addr;
if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi,
need_unwind_info, 0, need_unwind_info, 0,
arg)) arg))
< 0) < 0)
return ret; return ret;
return 1; return 1;
} }
} }
return -UNW_ENOINFO; return -UNW_ENOINFO;
} }
@ -124,7 +124,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
goto file_error; goto file_error;
Debug (4, "loading string table of size %zd\n", Debug (4, "loading string table of size %zd\n",
sec_hdrs[shstrndx].sh_size); sec_hdrs[shstrndx].sh_size);
stringtab = malloc (sec_hdrs[shstrndx].sh_size); stringtab = malloc (sec_hdrs[shstrndx].sh_size);
fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET); fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET);
if (fread (stringtab, 1, sec_hdrs[shstrndx].sh_size, f) != sec_hdrs[shstrndx].sh_size) if (fread (stringtab, 1, sec_hdrs[shstrndx].sh_size, f) != sec_hdrs[shstrndx].sh_size)
@ -136,28 +136,28 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
if (strcmp (secname, ".debug_frame") == 0) if (strcmp (secname, ".debug_frame") == 0)
{ {
*bufsize = sec_hdrs[i].sh_size; *bufsize = sec_hdrs[i].sh_size;
*buf = malloc (*bufsize); *buf = malloc (*bufsize);
fseek (f, sec_hdrs[i].sh_offset, SEEK_SET); fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
if (fread (*buf, 1, *bufsize, f) != *bufsize) if (fread (*buf, 1, *bufsize, f) != *bufsize)
goto file_error; goto file_error;
Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", Debug (4, "read %zd bytes of .debug_frame from offset %zd\n",
*bufsize, sec_hdrs[i].sh_offset); *bufsize, sec_hdrs[i].sh_offset);
} }
else if (strcmp (secname, ".gnu_debuglink") == 0) else if (strcmp (secname, ".gnu_debuglink") == 0)
{ {
linksize = sec_hdrs[i].sh_size; linksize = sec_hdrs[i].sh_size;
linkbuf = malloc (linksize); linkbuf = malloc (linksize);
fseek (f, sec_hdrs[i].sh_offset, SEEK_SET); fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
if (fread (linkbuf, 1, linksize, f) != linksize) if (fread (linkbuf, 1, linksize, f) != linksize)
goto file_error; goto file_error;
Debug (4, "read %zd bytes of .gnu_debuglink from offset %zd\n", Debug (4, "read %zd bytes of .gnu_debuglink from offset %zd\n",
linksize, sec_hdrs[i].sh_offset); linksize, sec_hdrs[i].sh_offset);
} }
} }
free (stringtab); free (stringtab);
@ -181,16 +181,16 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
/* XXX: Don't bother with the checksum; just search for the file. */ /* XXX: Don't bother with the checksum; just search for the file. */
basedir = malloc (strlen (file) + 1); basedir = malloc (strlen (file) + 1);
newname = malloc (strlen (linkbuf) + strlen (debugdir) newname = malloc (strlen (linkbuf) + strlen (debugdir)
+ strlen (file) + 9); + strlen (file) + 9);
p = strrchr (file, '/'); p = strrchr (file, '/');
if (p != NULL) if (p != NULL)
{ {
memcpy (basedir, file, p - file); memcpy (basedir, file, p - file);
basedir[p - file] = '\0'; basedir[p - file] = '\0';
} }
else else
basedir[0] = 0; basedir[0] = 0;
strcpy (newname, basedir); strcpy (newname, basedir);
strcat (newname, "/"); strcat (newname, "/");
@ -198,21 +198,21 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
ret = load_debug_frame (newname, buf, bufsize, -1); ret = load_debug_frame (newname, buf, bufsize, -1);
if (ret == 1) if (ret == 1)
{ {
strcpy (newname, basedir); strcpy (newname, basedir);
strcat (newname, "/.debug/"); strcat (newname, "/.debug/");
strcat (newname, linkbuf); strcat (newname, linkbuf);
ret = load_debug_frame (newname, buf, bufsize, -1); ret = load_debug_frame (newname, buf, bufsize, -1);
} }
if (ret == 1 && is_local == 1) if (ret == 1 && is_local == 1)
{ {
strcpy (newname, debugdir); strcpy (newname, debugdir);
strcat (newname, basedir); strcat (newname, basedir);
strcat (newname, "/"); strcat (newname, "/");
strcat (newname, linkbuf); strcat (newname, linkbuf);
ret = load_debug_frame (newname, buf, bufsize, -1); ret = load_debug_frame (newname, buf, bufsize, -1);
} }
free (basedir); free (basedir);
free (newname); free (newname);
@ -248,14 +248,14 @@ find_binary_for_address (unw_word_t ip, char *name, size_t name_size)
while (maps_next (&mi, &segbase, &hi, &mapoff)) while (maps_next (&mi, &segbase, &hi, &mapoff))
if (ip >= segbase && ip < hi) if (ip >= segbase && ip < hi)
{ {
size_t len = strlen (mi.path); size_t len = strlen (mi.path);
if (len + 1 <= name_size) if (len + 1 <= name_size)
{ {
memcpy (name, mi.path, len + 1); memcpy (name, mi.path, len + 1);
found = 1; found = 1;
} }
break; break;
} }
maps_close (&mi); maps_close (&mi);
return !found; return !found;
@ -269,7 +269,7 @@ find_binary_for_address (unw_word_t ip, char *name, size_t name_size)
static struct unw_debug_frame_list * static struct unw_debug_frame_list *
locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
unw_word_t start, unw_word_t end) unw_word_t start, unw_word_t end)
{ {
struct unw_debug_frame_list *w, *fdesc = 0; struct unw_debug_frame_list *w, *fdesc = 0;
char path[PATH_MAX]; char path[PATH_MAX];
@ -284,7 +284,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
{ {
Debug (4, "checking %p: %lx-%lx\n", w, (long)w->start, (long)w->end); Debug (4, "checking %p: %lx-%lx\n", w, (long)w->start, (long)w->end);
if (addr >= w->start && addr < w->end) if (addr >= w->start && addr < w->end)
return w; return w;
} }
/* If the object name we receive is blank, there's still a chance of locating /* If the object name we receive is blank, there's still a chance of locating
@ -295,10 +295,10 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
err = find_binary_for_address (addr, name, sizeof(path)); err = find_binary_for_address (addr, name, sizeof(path));
if (err) if (err)
{ {
Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n", Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n",
(uint64_t) addr); (uint64_t) addr);
return 0; return 0;
} }
} }
else else
name = (char*) dlname; name = (char*) dlname;
@ -331,7 +331,7 @@ struct debug_frame_tab
static void static void
debug_frame_tab_append (struct debug_frame_tab *tab, debug_frame_tab_append (struct debug_frame_tab *tab,
unw_word_t fde_offset, unw_word_t start_ip) unw_word_t fde_offset, unw_word_t start_ip)
{ {
unsigned int length = tab->length; unsigned int length = tab->length;
@ -372,8 +372,8 @@ debug_frame_tab_compare (const void *a, const void *b)
PROTECTED int PROTECTED int
dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip,
unw_word_t segbase, const char* obj_name, unw_word_t segbase, const char* obj_name,
unw_word_t start, unw_word_t end) unw_word_t start, unw_word_t end)
{ {
unw_dyn_info_t *di; unw_dyn_info_t *di;
struct unw_debug_frame_list *fdesc = 0; struct unw_debug_frame_list *fdesc = 0;
@ -546,11 +546,11 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
/* Make sure struct dl_phdr_info is at least as big as we need. */ /* Make sure struct dl_phdr_info is at least as big as we need. */
if (size < offsetof (struct dl_phdr_info, dlpi_phnum) if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
+ sizeof (info->dlpi_phnum)) + sizeof (info->dlpi_phnum))
return -1; return -1;
Debug (15, "checking %s, base=0x%lx)\n", Debug (15, "checking %s, base=0x%lx)\n",
info->dlpi_name, (long) info->dlpi_addr); info->dlpi_name, (long) info->dlpi_addr);
phdr = info->dlpi_phdr; phdr = info->dlpi_phdr;
load_base = info->dlpi_addr; load_base = info->dlpi_addr;
@ -563,19 +563,19 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
for (n = info->dlpi_phnum; --n >= 0; phdr++) for (n = info->dlpi_phnum; --n >= 0; phdr++)
{ {
if (phdr->p_type == PT_LOAD) if (phdr->p_type == PT_LOAD)
{ {
Elf_W(Addr) vaddr = phdr->p_vaddr + load_base; Elf_W(Addr) vaddr = phdr->p_vaddr + load_base;
if (ip >= vaddr && ip < vaddr + phdr->p_memsz) if (ip >= vaddr && ip < vaddr + phdr->p_memsz)
p_text = phdr; p_text = phdr;
if (vaddr + phdr->p_filesz > max_load_addr) if (vaddr + phdr->p_filesz > max_load_addr)
max_load_addr = vaddr + phdr->p_filesz; max_load_addr = vaddr + phdr->p_filesz;
} }
else if (phdr->p_type == PT_GNU_EH_FRAME) else if (phdr->p_type == PT_GNU_EH_FRAME)
p_eh_hdr = phdr; p_eh_hdr = phdr;
else if (phdr->p_type == PT_DYNAMIC) else if (phdr->p_type == PT_DYNAMIC)
p_dynamic = phdr; p_dynamic = phdr;
} }
if (!p_text) if (!p_text)
@ -584,97 +584,97 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
if (p_eh_hdr) if (p_eh_hdr)
{ {
if (p_dynamic) if (p_dynamic)
{ {
/* For dynamicly linked executables and shared libraries, /* For dynamicly linked executables and shared libraries,
DT_PLTGOT is the value that data-relative addresses are DT_PLTGOT is the value that data-relative addresses are
relative to for that object. We call this the "gp". */ relative to for that object. We call this the "gp". */
Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(p_dynamic->p_vaddr + load_base); Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(p_dynamic->p_vaddr + load_base);
for (; dyn->d_tag != DT_NULL; ++dyn) for (; dyn->d_tag != DT_NULL; ++dyn)
if (dyn->d_tag == DT_PLTGOT) if (dyn->d_tag == DT_PLTGOT)
{ {
/* Assume that _DYNAMIC is writable and GLIBC has /* Assume that _DYNAMIC is writable and GLIBC has
relocated it (true for x86 at least). */ relocated it (true for x86 at least). */
di->gp = dyn->d_un.d_ptr; di->gp = dyn->d_un.d_ptr;
break; break;
} }
} }
else else
/* Otherwise this is a static executable with no _DYNAMIC. Assume /* Otherwise this is a static executable with no _DYNAMIC. Assume
that data-relative addresses are relative to 0, i.e., that data-relative addresses are relative to 0, i.e.,
absolute. */ absolute. */
di->gp = 0; di->gp = 0;
pi->gp = di->gp; pi->gp = di->gp;
hdr = (struct dwarf_eh_frame_hdr *) (p_eh_hdr->p_vaddr + load_base); hdr = (struct dwarf_eh_frame_hdr *) (p_eh_hdr->p_vaddr + load_base);
if (hdr->version != DW_EH_VERSION) if (hdr->version != DW_EH_VERSION)
{ {
Debug (1, "table `%s' has unexpected version %d\n", Debug (1, "table `%s' has unexpected version %d\n",
info->dlpi_name, hdr->version); info->dlpi_name, hdr->version);
return 0; return 0;
} }
a = unw_get_accessors (unw_local_addr_space); a = unw_get_accessors (unw_local_addr_space);
addr = (unw_word_t) (uintptr_t) (hdr + 1); addr = (unw_word_t) (uintptr_t) (hdr + 1);
/* (Optionally) read eh_frame_ptr: */ /* (Optionally) read eh_frame_ptr: */
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
&addr, hdr->eh_frame_ptr_enc, pi, &addr, hdr->eh_frame_ptr_enc, pi,
&eh_frame_start, NULL)) < 0) &eh_frame_start, NULL)) < 0)
return ret; return ret;
/* (Optionally) read fde_count: */ /* (Optionally) read fde_count: */
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
&addr, hdr->fde_count_enc, pi, &addr, hdr->fde_count_enc, pi,
&fde_count, NULL)) < 0) &fde_count, NULL)) < 0)
return ret; return ret;
if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
{ {
/* If there is no search table or it has an unsupported /* If there is no search table or it has an unsupported
encoding, fall back on linear search. */ encoding, fall back on linear search. */
if (hdr->table_enc == DW_EH_PE_omit) if (hdr->table_enc == DW_EH_PE_omit)
Debug (4, "table `%s' lacks search table; doing linear search\n", Debug (4, "table `%s' lacks search table; doing linear search\n",
info->dlpi_name); info->dlpi_name);
else else
Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", Debug (4, "table `%s' has encoding 0x%x; doing linear search\n",
info->dlpi_name, hdr->table_enc); info->dlpi_name, hdr->table_enc);
eh_frame_end = max_load_addr; /* XXX can we do better? */ eh_frame_end = max_load_addr; /* XXX can we do better? */
if (hdr->fde_count_enc == DW_EH_PE_omit) if (hdr->fde_count_enc == DW_EH_PE_omit)
fde_count = ~0UL; fde_count = ~0UL;
if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit)
abort (); abort ();
/* XXX we know how to build a local binary search table for /* XXX we know how to build a local binary search table for
.debug_frame, so we could do that here too. */ .debug_frame, so we could do that here too. */
cb_data->single_fde = 1; cb_data->single_fde = 1;
found = linear_search (unw_local_addr_space, ip, found = linear_search (unw_local_addr_space, ip,
eh_frame_start, eh_frame_end, fde_count, eh_frame_start, eh_frame_end, fde_count,
pi, need_unwind_info, NULL); pi, need_unwind_info, NULL);
if (found != 1) if (found != 1)
found = 0; found = 0;
} }
else else
{ {
di->format = UNW_INFO_FORMAT_REMOTE_TABLE; di->format = UNW_INFO_FORMAT_REMOTE_TABLE;
di->start_ip = p_text->p_vaddr + load_base; di->start_ip = p_text->p_vaddr + load_base;
di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz; di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz;
di->u.rti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name; di->u.rti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name;
di->u.rti.table_data = addr; di->u.rti.table_data = addr;
assert (sizeof (struct table_entry) % sizeof (unw_word_t) == 0); assert (sizeof (struct table_entry) % sizeof (unw_word_t) == 0);
di->u.rti.table_len = (fde_count * sizeof (struct table_entry) di->u.rti.table_len = (fde_count * sizeof (struct table_entry)
/ sizeof (unw_word_t)); / sizeof (unw_word_t));
/* For the binary-search table in the eh_frame_hdr, data-relative /* For the binary-search table in the eh_frame_hdr, data-relative
means relative to the start of that section... */ means relative to the start of that section... */
di->u.rti.segbase = (unw_word_t) (uintptr_t) hdr; di->u.rti.segbase = (unw_word_t) (uintptr_t) hdr;
found = 1; found = 1;
Debug (15, "found table `%s': segbase=0x%lx, len=%lu, gp=0x%lx, " Debug (15, "found table `%s': segbase=0x%lx, len=%lu, gp=0x%lx, "
"table_data=0x%lx\n", (char *) (uintptr_t) di->u.rti.name_ptr, "table_data=0x%lx\n", (char *) (uintptr_t) di->u.rti.name_ptr,
(long) di->u.rti.segbase, (long) di->u.rti.table_len, (long) di->u.rti.segbase, (long) di->u.rti.table_len,
(long) di->gp, (long) di->u.rti.table_data); (long) di->gp, (long) di->u.rti.table_data);
} }
} }
#ifdef CONFIG_DEBUG_FRAME #ifdef CONFIG_DEBUG_FRAME
@ -687,20 +687,20 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
{ {
if (info->dlpi_phdr[n].p_type == PT_LOAD) if (info->dlpi_phdr[n].p_type == PT_LOAD)
{ {
unw_word_t seg_start = info->dlpi_addr + info->dlpi_phdr[n].p_vaddr; unw_word_t seg_start = info->dlpi_addr + info->dlpi_phdr[n].p_vaddr;
unw_word_t seg_end = seg_start + info->dlpi_phdr[n].p_memsz; unw_word_t seg_end = seg_start + info->dlpi_phdr[n].p_memsz;
if (seg_start < start) if (seg_start < start)
start = seg_start; start = seg_start;
if (seg_end > end) if (seg_end > end)
end = seg_end; end = seg_end;
} }
} }
found = dwarf_find_debug_frame (found, &cb_data->di_debug, ip, found = dwarf_find_debug_frame (found, &cb_data->di_debug, ip,
info->dlpi_addr, info->dlpi_name, start, info->dlpi_addr, info->dlpi_name, start,
end); end);
#endif /* CONFIG_DEBUG_FRAME */ #endif /* CONFIG_DEBUG_FRAME */
return found; return found;
@ -708,7 +708,7 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
HIDDEN int HIDDEN int
dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info, void *arg) unw_proc_info_t *pi, int need_unwind_info, void *arg)
{ {
struct dwarf_callback_data cb_data; struct dwarf_callback_data cb_data;
intrmask_t saved_mask; intrmask_t saved_mask;
@ -740,13 +740,13 @@ dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
/* search the table: */ /* search the table: */
if (cb_data.di.format != -1) if (cb_data.di.format != -1)
ret = dwarf_search_unwind_table (as, ip, &cb_data.di, ret = dwarf_search_unwind_table (as, ip, &cb_data.di,
pi, need_unwind_info, arg); pi, need_unwind_info, arg);
else else
ret = -UNW_ENOINFO; ret = -UNW_ENOINFO;
if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1) if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1)
ret = dwarf_search_unwind_table (as, ip, &cb_data.di_debug, pi, ret = dwarf_search_unwind_table (as, ip, &cb_data.di_debug, pi,
need_unwind_info, arg); need_unwind_info, arg);
return ret; return ret;
} }
@ -764,12 +764,12 @@ lookup (const struct table_entry *table, size_t table_size, int32_t rel_ip)
e = table + mid; e = table + mid;
Debug (15, "e->start_ip_offset = %lx\n", (long) e->start_ip_offset); Debug (15, "e->start_ip_offset = %lx\n", (long) e->start_ip_offset);
if (rel_ip < e->start_ip_offset) if (rel_ip < e->start_ip_offset)
hi = mid; hi = mid;
else else
lo = mid + 1; lo = mid + 1;
} }
if (hi <= 0) if (hi <= 0)
return NULL; return NULL;
e = table + hi - 1; e = table + hi - 1;
return e; return e;
} }
@ -783,8 +783,8 @@ lookup (const struct table_entry *table, size_t table_size, int32_t rel_ip)
occurred reading remote memory. */ occurred reading remote memory. */
static int static int
remote_lookup (unw_addr_space_t as, remote_lookup (unw_addr_space_t as,
unw_word_t table, size_t table_size, int32_t rel_ip, unw_word_t table, size_t table_size, int32_t rel_ip,
struct table_entry *e, void *arg) struct table_entry *e, void *arg)
{ {
unsigned long table_len = table_size / sizeof (struct table_entry); unsigned long table_len = table_size / sizeof (struct table_entry);
unw_accessors_t *a = unw_get_accessors (as); unw_accessors_t *a = unw_get_accessors (as);
@ -799,12 +799,12 @@ remote_lookup (unw_addr_space_t as,
mid = (lo + hi) / 2; mid = (lo + hi) / 2;
e_addr = table + mid * sizeof (struct table_entry); e_addr = table + mid * sizeof (struct table_entry);
if ((ret = dwarf_reads32 (as, a, &e_addr, &start, arg)) < 0) if ((ret = dwarf_reads32 (as, a, &e_addr, &start, arg)) < 0)
return ret; return ret;
if (rel_ip < start) if (rel_ip < start)
hi = mid; hi = mid;
else else
lo = mid + 1; lo = mid + 1;
} }
if (hi <= 0) if (hi <= 0)
return 0; return 0;
@ -819,8 +819,8 @@ remote_lookup (unw_addr_space_t as,
PROTECTED int PROTECTED int
dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi, unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg) int need_unwind_info, void *arg)
{ {
const struct table_entry *e = NULL, *table; const struct table_entry *e = NULL, *table;
unw_word_t segbase = 0, fde_addr; unw_word_t segbase = 0, fde_addr;
@ -836,7 +836,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE); assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE);
#else #else
assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE
|| di->format == UNW_INFO_FORMAT_TABLE); || di->format == UNW_INFO_FORMAT_TABLE);
#endif #endif
assert (ip >= di->start_ip && ip < di->end_ip); assert (ip >= di->start_ip && ip < di->end_ip);
@ -876,34 +876,34 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
#ifndef UNW_LOCAL_ONLY #ifndef UNW_LOCAL_ONLY
segbase = di->u.rti.segbase; segbase = di->u.rti.segbase;
if ((ret = remote_lookup (as, (uintptr_t) table, table_len, if ((ret = remote_lookup (as, (uintptr_t) table, table_len,
ip - segbase, &ent, arg)) < 0) ip - segbase, &ent, arg)) < 0)
return ret; return ret;
if (ret) if (ret)
e = &ent; e = &ent;
else else
e = NULL; /* no info found */ e = NULL; /* no info found */
#endif #endif
} }
if (!e) if (!e)
{ {
Debug (1, "IP %lx inside range %lx-%lx, but no explicit unwind info found\n", Debug (1, "IP %lx inside range %lx-%lx, but no explicit unwind info found\n",
(long) ip, (long) di->start_ip, (long) di->end_ip); (long) ip, (long) di->start_ip, (long) di->end_ip);
/* IP is inside this table's range, but there is no explicit /* IP is inside this table's range, but there is no explicit
unwind info. */ unwind info. */
return -UNW_ENOINFO; return -UNW_ENOINFO;
} }
Debug (15, "ip=0x%lx, start_ip=0x%lx\n", Debug (15, "ip=0x%lx, start_ip=0x%lx\n",
(long) ip, (long) (e->start_ip_offset)); (long) ip, (long) (e->start_ip_offset));
if (debug_frame_base) if (debug_frame_base)
fde_addr = e->fde_offset + debug_frame_base; fde_addr = e->fde_offset + debug_frame_base;
else else
fde_addr = e->fde_offset + segbase; fde_addr = e->fde_offset + segbase;
Debug (1, "e->fde_offset = %lx, segbase = %lx, debug_frame_base = %lx, " Debug (1, "e->fde_offset = %lx, segbase = %lx, debug_frame_base = %lx, "
"fde_addr = %lx\n", (long) e->fde_offset, (long) segbase, "fde_addr = %lx\n", (long) e->fde_offset, (long) segbase,
(long) debug_frame_base, (long) fde_addr); (long) debug_frame_base, (long) fde_addr);
if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi, if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi,
need_unwind_info, need_unwind_info,
debug_frame_base, arg)) < 0) debug_frame_base, arg)) < 0)
return ret; return ret;
/* .debug_frame uses an absolute encoding that does not know about any /* .debug_frame uses an absolute encoding that does not know about any
@ -924,5 +924,5 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
HIDDEN void HIDDEN void
dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg)
{ {
return; /* always a nop */ return; /* always a nop */
} }

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003-2004 Hewlett-Packard Co Copyright (C) 2003-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -35,8 +35,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
int int
dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
char *path, unw_word_t segbase, unw_word_t mapoff, char *path, unw_word_t segbase, unw_word_t mapoff,
unw_word_t ip) unw_word_t ip)
{ {
Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL;
unw_word_t addr, eh_frame_start, fde_count, load_base; unw_word_t addr, eh_frame_start, fde_count, load_base;
@ -63,37 +63,37 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
for (i = 0; i < ehdr->e_phnum; ++i) for (i = 0; i < ehdr->e_phnum; ++i)
{ {
switch (phdr[i].p_type) switch (phdr[i].p_type)
{ {
case PT_LOAD: case PT_LOAD:
if (phdr[i].p_vaddr < start_ip) if (phdr[i].p_vaddr < start_ip)
start_ip = phdr[i].p_vaddr; start_ip = phdr[i].p_vaddr;
if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip)
end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; end_ip = phdr[i].p_vaddr + phdr[i].p_memsz;
if (phdr[i].p_offset == mapoff) if (phdr[i].p_offset == mapoff)
ptxt = phdr + i; ptxt = phdr + i;
if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr)
max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz;
break; break;
case PT_GNU_EH_FRAME: case PT_GNU_EH_FRAME:
peh_hdr = phdr + i; peh_hdr = phdr + i;
break; break;
case PT_DYNAMIC: case PT_DYNAMIC:
pdyn = phdr + i; pdyn = phdr + i;
break; break;
#if UNW_TARGET_ARM #if UNW_TARGET_ARM
case PT_ARM_EXIDX: case PT_ARM_EXIDX:
parm_exidx = phdr + i; parm_exidx = phdr + i;
break; break;
#endif #endif
default: default:
break; break;
} }
} }
if (!ptxt) if (!ptxt)
@ -106,85 +106,85 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
if (peh_hdr) if (peh_hdr)
{ {
if (pdyn) if (pdyn)
{ {
/* For dynamicly linked executables and shared libraries, /* For dynamicly linked executables and shared libraries,
DT_PLTGOT is the value that data-relative addresses are DT_PLTGOT is the value that data-relative addresses are
relative to for that object. We call this the "gp". */ relative to for that object. We call this the "gp". */
Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset
+ (char *) edi->ei.image); + (char *) edi->ei.image);
for (; dyn->d_tag != DT_NULL; ++dyn) for (; dyn->d_tag != DT_NULL; ++dyn)
if (dyn->d_tag == DT_PLTGOT) if (dyn->d_tag == DT_PLTGOT)
{ {
/* Assume that _DYNAMIC is writable and GLIBC has /* Assume that _DYNAMIC is writable and GLIBC has
relocated it (true for x86 at least). */ relocated it (true for x86 at least). */
edi->di_cache.gp = dyn->d_un.d_ptr; edi->di_cache.gp = dyn->d_un.d_ptr;
break; break;
} }
} }
else else
/* Otherwise this is a static executable with no _DYNAMIC. Assume /* Otherwise this is a static executable with no _DYNAMIC. Assume
that data-relative addresses are relative to 0, i.e., that data-relative addresses are relative to 0, i.e.,
absolute. */ absolute. */
edi->di_cache.gp = 0; edi->di_cache.gp = 0;
hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset
+ (char *) edi->ei.image); + (char *) edi->ei.image);
if (hdr->version != DW_EH_VERSION) if (hdr->version != DW_EH_VERSION)
{ {
Debug (1, "table `%s' has unexpected version %d\n", Debug (1, "table `%s' has unexpected version %d\n",
path, hdr->version); path, hdr->version);
return -UNW_ENOINFO; return -UNW_ENOINFO;
} }
a = unw_get_accessors (unw_local_addr_space); a = unw_get_accessors (unw_local_addr_space);
addr = (unw_word_t) (hdr + 1); addr = (unw_word_t) (hdr + 1);
/* Fill in a dummy proc_info structure. We just need to fill in /* Fill in a dummy proc_info structure. We just need to fill in
enough to ensure that dwarf_read_encoded_pointer() can do it's enough to ensure that dwarf_read_encoded_pointer() can do it's
job. Since we don't have a procedure-context at this point, all job. Since we don't have a procedure-context at this point, all
we have to do is fill in the global-pointer. */ we have to do is fill in the global-pointer. */
memset (&pi, 0, sizeof (pi)); memset (&pi, 0, sizeof (pi));
pi.gp = edi->di_cache.gp; pi.gp = edi->di_cache.gp;
/* (Optionally) read eh_frame_ptr: */ /* (Optionally) read eh_frame_ptr: */
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
&addr, hdr->eh_frame_ptr_enc, &pi, &addr, hdr->eh_frame_ptr_enc, &pi,
&eh_frame_start, NULL)) < 0) &eh_frame_start, NULL)) < 0)
return -UNW_ENOINFO; return -UNW_ENOINFO;
/* (Optionally) read fde_count: */ /* (Optionally) read fde_count: */
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
&addr, hdr->fde_count_enc, &pi, &addr, hdr->fde_count_enc, &pi,
&fde_count, NULL)) < 0) &fde_count, NULL)) < 0)
return -UNW_ENOINFO; return -UNW_ENOINFO;
if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
{ {
#if 1 #if 1
abort (); abort ();
#else #else
unw_word_t eh_frame_end; unw_word_t eh_frame_end;
/* If there is no search table or it has an unsupported /* If there is no search table or it has an unsupported
encoding, fall back on linear search. */ encoding, fall back on linear search. */
if (hdr->table_enc == DW_EH_PE_omit) if (hdr->table_enc == DW_EH_PE_omit)
Debug (4, "EH lacks search table; doing linear search\n"); Debug (4, "EH lacks search table; doing linear search\n");
else else
Debug (4, "EH table has encoding 0x%x; doing linear search\n", Debug (4, "EH table has encoding 0x%x; doing linear search\n",
hdr->table_enc); hdr->table_enc);
eh_frame_end = max_load_addr; /* XXX can we do better? */ eh_frame_end = max_load_addr; /* XXX can we do better? */
if (hdr->fde_count_enc == DW_EH_PE_omit) if (hdr->fde_count_enc == DW_EH_PE_omit)
fde_count = ~0UL; fde_count = ~0UL;
if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit)
abort (); abort ();
return linear_search (unw_local_addr_space, ip, return linear_search (unw_local_addr_space, ip,
eh_frame_start, eh_frame_end, fde_count, eh_frame_start, eh_frame_end, fde_count,
pi, need_unwind_info, NULL); pi, need_unwind_info, NULL);
#endif #endif
} }
edi->di_cache.start_ip = start_ip; edi->di_cache.start_ip = start_ip;
edi->di_cache.end_ip = end_ip; edi->di_cache.end_ip = end_ip;
@ -193,14 +193,14 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
/* two 32-bit values (ip_offset/fde_offset) per table-entry: */ /* two 32-bit values (ip_offset/fde_offset) per table-entry: */
edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t);
edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr)
+ (addr - (unw_word_t) edi->ei.image + (addr - (unw_word_t) edi->ei.image
- peh_hdr->p_offset)); - peh_hdr->p_offset));
/* For the binary-search table in the eh_frame_hdr, data-relative /* For the binary-search table in the eh_frame_hdr, data-relative
means relative to the start of that section... */ means relative to the start of that section... */
edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr)
+ ((unw_word_t) hdr - (unw_word_t) edi->ei.image + ((unw_word_t) hdr - (unw_word_t) edi->ei.image
- peh_hdr->p_offset)); - peh_hdr->p_offset));
found = 1; found = 1;
} }
@ -220,7 +220,7 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
#ifdef CONFIG_DEBUG_FRAME #ifdef CONFIG_DEBUG_FRAME
/* Try .debug_frame. */ /* Try .debug_frame. */
found = dwarf_find_debug_frame (found, &edi->di_debug, ip, load_base, path, found = dwarf_find_debug_frame (found, &edi->di_debug, ip, load_base, path,
start_ip, end_ip); start_ip, end_ip);
#endif #endif
return found; return found;

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -27,12 +27,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "dwarf_i.h" #include "dwarf_i.h"
#include "libunwind_i.h" #include "libunwind_i.h"
#define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool)) #define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool))
#define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs)) #define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs))
static inline int static inline int
read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *valp, void *arg) unw_word_t *valp, void *arg)
{ {
int ret; int ret;
@ -49,7 +49,7 @@ read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
static inline void static inline void
set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where, set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where,
unw_word_t val) unw_word_t val)
{ {
sr->rs_current.reg[regnum].where = where; sr->rs_current.reg[regnum].where = where;
sr->rs_current.reg[regnum].val = val; sr->rs_current.reg[regnum].val = val;
@ -58,8 +58,8 @@ set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where,
/* Run a CFI program to update the register state. */ /* Run a CFI program to update the register state. */
static int static int
run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
unw_word_t ip, unw_word_t *addr, unw_word_t end_addr, unw_word_t ip, unw_word_t *addr, unw_word_t end_addr,
struct dwarf_cie_info *dci) struct dwarf_cie_info *dci)
{ {
unw_word_t curr_ip, operand = 0, regnum, val, len, fde_encoding; unw_word_t curr_ip, operand = 0, regnum, val, len, fde_encoding;
dwarf_reg_state_t *rs_stack = NULL, *new_rs, *old_rs; dwarf_reg_state_t *rs_stack = NULL, *new_rs, *old_rs;
@ -88,251 +88,251 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
while (curr_ip <= ip && *addr < end_addr) while (curr_ip <= ip && *addr < end_addr)
{ {
if ((ret = dwarf_readu8 (as, a, addr, &op, arg)) < 0) if ((ret = dwarf_readu8 (as, a, addr, &op, arg)) < 0)
return ret; return ret;
if (op & DWARF_CFA_OPCODE_MASK) if (op & DWARF_CFA_OPCODE_MASK)
{ {
operand = op & DWARF_CFA_OPERAND_MASK; operand = op & DWARF_CFA_OPERAND_MASK;
op &= ~DWARF_CFA_OPERAND_MASK; op &= ~DWARF_CFA_OPERAND_MASK;
} }
switch ((dwarf_cfa_t) op) switch ((dwarf_cfa_t) op)
{ {
case DW_CFA_advance_loc: case DW_CFA_advance_loc:
curr_ip += operand * dci->code_align; curr_ip += operand * dci->code_align;
Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip);
break; break;
case DW_CFA_advance_loc1: case DW_CFA_advance_loc1:
if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0) if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0)
goto fail; goto fail;
curr_ip += u8 * dci->code_align; curr_ip += u8 * dci->code_align;
Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip);
break; break;
case DW_CFA_advance_loc2: case DW_CFA_advance_loc2:
if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0) if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0)
goto fail; goto fail;
curr_ip += u16 * dci->code_align; curr_ip += u16 * dci->code_align;
Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip);
break; break;
case DW_CFA_advance_loc4: case DW_CFA_advance_loc4:
if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0) if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0)
goto fail; goto fail;
curr_ip += u32 * dci->code_align; curr_ip += u32 * dci->code_align;
Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip);
break; break;
case DW_CFA_MIPS_advance_loc8: case DW_CFA_MIPS_advance_loc8:
#ifdef UNW_TARGET_MIPS #ifdef UNW_TARGET_MIPS
{ {
uint64_t u64; uint64_t u64;
if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0) if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0)
goto fail; goto fail;
curr_ip += u64 * dci->code_align; curr_ip += u64 * dci->code_align;
Debug (15, "CFA_MIPS_advance_loc8\n"); Debug (15, "CFA_MIPS_advance_loc8\n");
break; break;
} }
#else #else
Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n"); Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n");
ret = -UNW_EINVAL; ret = -UNW_EINVAL;
goto fail; goto fail;
#endif #endif
case DW_CFA_offset: case DW_CFA_offset:
regnum = operand; regnum = operand;
if (regnum >= DWARF_NUM_PRESERVED_REGS) if (regnum >= DWARF_NUM_PRESERVED_REGS)
{ {
Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n", Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n",
(unsigned int) regnum); (unsigned int) regnum);
ret = -UNW_EBADREG; ret = -UNW_EBADREG;
goto fail; goto fail;
} }
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
goto fail; goto fail;
set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset r%lu at cfa+0x%lx\n", Debug (15, "CFA_offset r%lu at cfa+0x%lx\n",
(long) regnum, (long) (val * dci->data_align)); (long) regnum, (long) (val * dci->data_align));
break; break;
case DW_CFA_offset_extended: case DW_CFA_offset_extended:
if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail; goto fail;
set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n", Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n",
(long) regnum, (long) (val * dci->data_align)); (long) regnum, (long) (val * dci->data_align));
break; break;
case DW_CFA_offset_extended_sf: case DW_CFA_offset_extended_sf:
if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
|| ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0))
goto fail; goto fail;
set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align);
Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n", Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n",
(long) regnum, (long) (val * dci->data_align)); (long) regnum, (long) (val * dci->data_align));
break; break;
case DW_CFA_restore: case DW_CFA_restore:
regnum = operand; regnum = operand;
if (regnum >= DWARF_NUM_PRESERVED_REGS) if (regnum >= DWARF_NUM_PRESERVED_REGS)
{ {
Debug (1, "Invalid register number %u in DW_CFA_restore\n", Debug (1, "Invalid register number %u in DW_CFA_restore\n",
(unsigned int) regnum); (unsigned int) regnum);
ret = -UNW_EINVAL; ret = -UNW_EINVAL;
goto fail; goto fail;
} }
sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum]; sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum];
Debug (15, "CFA_restore r%lu\n", (long) regnum); Debug (15, "CFA_restore r%lu\n", (long) regnum);
break; break;
case DW_CFA_restore_extended: case DW_CFA_restore_extended:
if ((ret = dwarf_read_uleb128 (as, a, addr, &regnum, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &regnum, arg)) < 0)
goto fail; goto fail;
if (regnum >= DWARF_NUM_PRESERVED_REGS) if (regnum >= DWARF_NUM_PRESERVED_REGS)
{ {
Debug (1, "Invalid register number %u in " Debug (1, "Invalid register number %u in "
"DW_CFA_restore_extended\n", (unsigned int) regnum); "DW_CFA_restore_extended\n", (unsigned int) regnum);
ret = -UNW_EINVAL; ret = -UNW_EINVAL;
goto fail; goto fail;
} }
sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum]; sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum];
Debug (15, "CFA_restore_extended r%lu\n", (long) regnum); Debug (15, "CFA_restore_extended r%lu\n", (long) regnum);
break; break;
case DW_CFA_nop: case DW_CFA_nop:
break; break;
case DW_CFA_set_loc: case DW_CFA_set_loc:
fde_encoding = dci->fde_encoding; fde_encoding = dci->fde_encoding;
if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding, if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding,
&c->pi, &curr_ip, &c->pi, &curr_ip,
arg)) < 0) arg)) < 0)
goto fail; goto fail;
Debug (15, "CFA_set_loc to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_set_loc to 0x%lx\n", (long) curr_ip);
break; break;
case DW_CFA_undefined: case DW_CFA_undefined:
if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
goto fail; goto fail;
set_reg (sr, regnum, DWARF_WHERE_UNDEF, 0); set_reg (sr, regnum, DWARF_WHERE_UNDEF, 0);
Debug (15, "CFA_undefined r%lu\n", (long) regnum); Debug (15, "CFA_undefined r%lu\n", (long) regnum);
break; break;
case DW_CFA_same_value: case DW_CFA_same_value:
if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
goto fail; goto fail;
set_reg (sr, regnum, DWARF_WHERE_SAME, 0); set_reg (sr, regnum, DWARF_WHERE_SAME, 0);
Debug (15, "CFA_same_value r%lu\n", (long) regnum); Debug (15, "CFA_same_value r%lu\n", (long) regnum);
break; break;
case DW_CFA_register: case DW_CFA_register:
if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail; goto fail;
set_reg (sr, regnum, DWARF_WHERE_REG, val); set_reg (sr, regnum, DWARF_WHERE_REG, val);
Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum, (long) val); Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum, (long) val);
break; break;
case DW_CFA_remember_state: case DW_CFA_remember_state:
new_rs = alloc_reg_state (); new_rs = alloc_reg_state ();
if (!new_rs) if (!new_rs)
{ {
Debug (1, "Out of memory in DW_CFA_remember_state\n"); Debug (1, "Out of memory in DW_CFA_remember_state\n");
ret = -UNW_ENOMEM; ret = -UNW_ENOMEM;
goto fail; goto fail;
} }
memcpy (new_rs->reg, sr->rs_current.reg, sizeof (new_rs->reg)); memcpy (new_rs->reg, sr->rs_current.reg, sizeof (new_rs->reg));
new_rs->next = rs_stack; new_rs->next = rs_stack;
rs_stack = new_rs; rs_stack = new_rs;
Debug (15, "CFA_remember_state\n"); Debug (15, "CFA_remember_state\n");
break; break;
case DW_CFA_restore_state: case DW_CFA_restore_state:
if (!rs_stack) if (!rs_stack)
{ {
Debug (1, "register-state stack underflow\n"); Debug (1, "register-state stack underflow\n");
ret = -UNW_EINVAL; ret = -UNW_EINVAL;
goto fail; goto fail;
} }
memcpy (&sr->rs_current.reg, &rs_stack->reg, sizeof (rs_stack->reg)); memcpy (&sr->rs_current.reg, &rs_stack->reg, sizeof (rs_stack->reg));
old_rs = rs_stack; old_rs = rs_stack;
rs_stack = rs_stack->next; rs_stack = rs_stack->next;
free_reg_state (old_rs); free_reg_state (old_rs);
Debug (15, "CFA_restore_state\n"); Debug (15, "CFA_restore_state\n");
break; break;
case DW_CFA_def_cfa: case DW_CFA_def_cfa:
if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail; goto fail;
set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum);
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */
Debug (15, "CFA_def_cfa r%lu+0x%lx\n", (long) regnum, (long) val); Debug (15, "CFA_def_cfa r%lu+0x%lx\n", (long) regnum, (long) val);
break; break;
case DW_CFA_def_cfa_sf: case DW_CFA_def_cfa_sf:
if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
|| ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0))
goto fail; goto fail;
set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum);
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, set_reg (sr, DWARF_CFA_OFF_COLUMN, 0,
val * dci->data_align); /* factored! */ val * dci->data_align); /* factored! */
Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n", Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n",
(long) regnum, (long) (val * dci->data_align)); (long) regnum, (long) (val * dci->data_align));
break; break;
case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_register:
if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
goto fail; goto fail;
set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum);
Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum); Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum);
break; break;
case DW_CFA_def_cfa_offset: case DW_CFA_def_cfa_offset:
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
goto fail; goto fail;
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */
Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val); Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val);
break; break;
case DW_CFA_def_cfa_offset_sf: case DW_CFA_def_cfa_offset_sf:
if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)
goto fail; goto fail;
set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, set_reg (sr, DWARF_CFA_OFF_COLUMN, 0,
val * dci->data_align); /* factored! */ val * dci->data_align); /* factored! */
Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n", Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n",
(long) (val * dci->data_align)); (long) (val * dci->data_align));
break; break;
case DW_CFA_def_cfa_expression: case DW_CFA_def_cfa_expression:
/* Save the address of the DW_FORM_block for later evaluation. */ /* Save the address of the DW_FORM_block for later evaluation. */
set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_EXPR, *addr); set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_EXPR, *addr);
if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0)
goto fail; goto fail;
Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n", Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n",
(long) *addr, (long) len); (long) *addr, (long) len);
*addr += len; *addr += len;
break; break;
case DW_CFA_expression: case DW_CFA_expression:
if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
goto fail; goto fail;
/* Save the address of the DW_FORM_block for later evaluation. */ /* Save the address of the DW_FORM_block for later evaluation. */
set_reg (sr, regnum, DWARF_WHERE_EXPR, *addr); set_reg (sr, regnum, DWARF_WHERE_EXPR, *addr);
if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0)
goto fail; goto fail;
Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n", Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n",
(long) regnum, (long) addr, (long) len); (long) regnum, (long) addr, (long) len);
*addr += len; *addr += len;
break; break;
case DW_CFA_val_expression: case DW_CFA_val_expression:
if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if ((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
@ -350,42 +350,42 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
break; break;
case DW_CFA_GNU_args_size: case DW_CFA_GNU_args_size:
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
goto fail; goto fail;
sr->args_size = val; sr->args_size = val;
Debug (15, "CFA_GNU_args_size %lu\n", (long) val); Debug (15, "CFA_GNU_args_size %lu\n", (long) val);
break; break;
case DW_CFA_GNU_negative_offset_extended: case DW_CFA_GNU_negative_offset_extended:
/* A comment in GCC says that this is obsoleted by /* A comment in GCC says that this is obsoleted by
DW_CFA_offset_extended_sf, but that it's used by older DW_CFA_offset_extended_sf, but that it's used by older
PowerPC code. */ PowerPC code. */
if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0) if (((ret = read_regnum (as, a, addr, &regnum, arg)) < 0)
|| ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0))
goto fail; goto fail;
set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align)); set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align));
Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n", Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n",
(long) -(val * dci->data_align)); (long) -(val * dci->data_align));
break; break;
case DW_CFA_GNU_window_save: case DW_CFA_GNU_window_save:
#ifdef UNW_TARGET_SPARC #ifdef UNW_TARGET_SPARC
/* This is a special CFA to handle all 16 windowed registers /* This is a special CFA to handle all 16 windowed registers
on SPARC. */ on SPARC. */
for (regnum = 16; regnum < 32; ++regnum) for (regnum = 16; regnum < 32; ++regnum)
set_reg (sr, regnum, DWARF_WHERE_CFAREL, set_reg (sr, regnum, DWARF_WHERE_CFAREL,
(regnum - 16) * sizeof (unw_word_t)); (regnum - 16) * sizeof (unw_word_t));
Debug (15, "CFA_GNU_window_save\n"); Debug (15, "CFA_GNU_window_save\n");
break; break;
#else #else
/* FALL THROUGH */ /* FALL THROUGH */
#endif #endif
case DW_CFA_lo_user: case DW_CFA_lo_user:
case DW_CFA_hi_user: case DW_CFA_hi_user:
Debug (1, "Unexpected CFA opcode 0x%x\n", op); Debug (1, "Unexpected CFA opcode 0x%x\n", op);
ret = -UNW_EINVAL; ret = -UNW_EINVAL;
goto fail; goto fail;
} }
} }
ret = 0; ret = 0;
@ -430,12 +430,12 @@ fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip, int need_unwind_info)
/* check dynamic info first --- it overrides everything else */ /* check dynamic info first --- it overrides everything else */
ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info, ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info,
c->as_arg); c->as_arg);
if (ret == -UNW_ENOINFO) if (ret == -UNW_ENOINFO)
{ {
dynamic = 0; dynamic = 0;
if ((ret = tdep_find_proc_info (c, ip, need_unwind_info)) < 0) if ((ret = tdep_find_proc_info (c, ip, need_unwind_info)) < 0)
return ret; return ret;
} }
if (c->pi.format != UNW_INFO_FORMAT_DYNAMIC if (c->pi.format != UNW_INFO_FORMAT_DYNAMIC
@ -496,7 +496,7 @@ parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr)
addr = dci->cie_instr_start; addr = dci->cie_instr_start;
if ((ret = run_cfi_program (c, sr, ~(unw_word_t) 0, &addr, if ((ret = run_cfi_program (c, sr, ~(unw_word_t) 0, &addr,
dci->cie_instr_end, dci)) < 0) dci->cie_instr_end, dci)) < 0)
return ret; return ret;
memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial)); memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial));
@ -519,7 +519,7 @@ flush_rs_cache (struct dwarf_rs_cache *cache)
for (i = 0; i < DWARF_UNW_CACHE_SIZE; ++i) for (i = 0; i < DWARF_UNW_CACHE_SIZE; ++i)
{ {
if (i > 0) if (i > 0)
cache->buckets[i].lru_chain = (i - 1); cache->buckets[i].lru_chain = (i - 1);
cache->buckets[i].coll_chain = -1; cache->buckets[i].coll_chain = -1;
cache->buckets[i].ip = 0; cache->buckets[i].ip = 0;
cache->buckets[i].valid = 0; cache->buckets[i].valid = 0;
@ -554,7 +554,7 @@ get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
static inline void static inline void
put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache, put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache,
intrmask_t *saved_maskp) intrmask_t *saved_maskp)
{ {
assert (as->caching_policy != UNW_CACHE_NONE); assert (as->caching_policy != UNW_CACHE_NONE);
@ -567,7 +567,7 @@ static inline unw_hash_index_t CONST_ATTR
hash (unw_word_t ip) hash (unw_word_t ip)
{ {
/* based on (sqrt(5)/2-1)*2^64 */ /* based on (sqrt(5)/2-1)*2^64 */
# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) # define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL)
return ip * magic >> ((sizeof(unw_word_t) * 8) - DWARF_LOG_UNW_HASH_SIZE); return ip * magic >> ((sizeof(unw_word_t) * 8) - DWARF_LOG_UNW_HASH_SIZE);
} }
@ -634,22 +634,22 @@ rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c)
tmp = cache->buckets + cache->hash[index]; tmp = cache->buckets + cache->hash[index];
prev = NULL; prev = NULL;
while (1) while (1)
{ {
if (tmp == rs) if (tmp == rs)
{ {
if (prev) if (prev)
prev->coll_chain = tmp->coll_chain; prev->coll_chain = tmp->coll_chain;
else else
cache->hash[index] = tmp->coll_chain; cache->hash[index] = tmp->coll_chain;
break; break;
} }
else else
prev = tmp; prev = tmp;
if (tmp->coll_chain >= DWARF_UNW_CACHE_SIZE) if (tmp->coll_chain >= DWARF_UNW_CACHE_SIZE)
/* old rs wasn't in the hash-table */ /* old rs wasn't in the hash-table */
break; break;
tmp = cache->buckets + tmp->coll_chain; tmp = cache->buckets + tmp->coll_chain;
} }
} }
/* enter new rs in the hash table */ /* enter new rs in the hash table */
@ -669,7 +669,7 @@ rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c)
static int static int
create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr,
unw_word_t ip) unw_word_t ip)
{ {
int i, ret; int i, ret;
@ -699,8 +699,8 @@ create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr,
static inline int static inline int
eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as,
unw_accessors_t *a, unw_word_t addr, unw_accessors_t *a, unw_word_t addr,
dwarf_loc_t *locp, void *arg) dwarf_loc_t *locp, void *arg)
{ {
int ret, is_register; int ret, is_register;
unw_word_t len, val; unw_word_t len, val;
@ -747,18 +747,18 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
/* CFA is equal to [reg] + offset: */ /* CFA is equal to [reg] + offset: */
/* As a special-case, if the stack-pointer is the CFA and the /* As a special-case, if the stack-pointer is the CFA and the
stack-pointer wasn't saved, popping the CFA implicitly pops stack-pointer wasn't saved, popping the CFA implicitly pops
the stack-pointer as well. */ the stack-pointer as well. */
if ((rs->reg[DWARF_CFA_REG_COLUMN].val == UNW_TDEP_SP) if ((rs->reg[DWARF_CFA_REG_COLUMN].val == UNW_TDEP_SP)
&& (UNW_TDEP_SP < ARRAY_SIZE(rs->reg)) && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg))
&& (rs->reg[UNW_TDEP_SP].where == DWARF_WHERE_SAME)) && (rs->reg[UNW_TDEP_SP].where == DWARF_WHERE_SAME))
cfa = c->cfa; cfa = c->cfa;
else else
{ {
regnum = dwarf_to_unw_regnum (rs->reg[DWARF_CFA_REG_COLUMN].val); regnum = dwarf_to_unw_regnum (rs->reg[DWARF_CFA_REG_COLUMN].val);
if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0) if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0)
return ret; return ret;
} }
cfa += rs->reg[DWARF_CFA_OFF_COLUMN].val; cfa += rs->reg[DWARF_CFA_OFF_COLUMN].val;
} }
else else
@ -769,37 +769,37 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
addr = rs->reg[DWARF_CFA_REG_COLUMN].val; addr = rs->reg[DWARF_CFA_REG_COLUMN].val;
if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0)
return ret; return ret;
/* the returned location better be a memory location... */ /* the returned location better be a memory location... */
if (DWARF_IS_REG_LOC (cfa_loc)) if (DWARF_IS_REG_LOC (cfa_loc))
return -UNW_EBADFRAME; return -UNW_EBADFRAME;
cfa = DWARF_GET_LOC (cfa_loc); cfa = DWARF_GET_LOC (cfa_loc);
} }
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
{ {
switch ((dwarf_where_t) rs->reg[i].where) switch ((dwarf_where_t) rs->reg[i].where)
{ {
case DWARF_WHERE_UNDEF: case DWARF_WHERE_UNDEF:
c->loc[i] = DWARF_NULL_LOC; c->loc[i] = DWARF_NULL_LOC;
break; break;
case DWARF_WHERE_SAME: case DWARF_WHERE_SAME:
break; break;
case DWARF_WHERE_CFAREL: case DWARF_WHERE_CFAREL:
c->loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg[i].val); c->loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg[i].val);
break; break;
case DWARF_WHERE_REG: case DWARF_WHERE_REG:
c->loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg[i].val)); c->loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg[i].val));
break; break;
case DWARF_WHERE_EXPR: case DWARF_WHERE_EXPR:
addr = rs->reg[i].val; addr = rs->reg[i].val;
if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0) if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0)
return ret; return ret;
break; break;
case DWARF_WHERE_VAL_EXPR: case DWARF_WHERE_VAL_EXPR:
addr = rs->reg[i].val; addr = rs->reg[i].val;
@ -807,7 +807,7 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
return ret; return ret;
c->loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (c->loc[i])); c->loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (c->loc[i]));
break; break;
} }
} }
c->cfa = cfa; c->cfa = cfa;
@ -826,7 +826,7 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
if (c->ip == prev_ip && c->cfa == prev_cfa) if (c->ip == prev_ip && c->cfa == prev_cfa)
{ {
Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n",
__FUNCTION__, (long) c->ip); __FUNCTION__, (long) c->ip);
return -UNW_EBADFRAME; return -UNW_EBADFRAME;
} }
@ -883,12 +883,12 @@ dwarf_find_save_locs (struct dwarf_cursor *c)
else else
{ {
if ((ret = fetch_proc_info (c, c->ip, 1)) < 0 || if ((ret = fetch_proc_info (c, c->ip, 1)) < 0 ||
(ret = create_state_record_for (c, &sr, c->ip)) < 0) (ret = create_state_record_for (c, &sr, c->ip)) < 0)
{ {
put_rs_cache (c->as, cache, &saved_mask); put_rs_cache (c->as, cache, &saved_mask);
put_unwind_info (c, &c->pi); put_unwind_info (c, &c->pi);
return ret; return ret;
} }
rs = rs_new (cache, c); rs = rs_new (cache, c);
memcpy(rs, &sr.rs_current, offsetof(struct dwarf_reg_state, ip)); memcpy(rs, &sr.rs_current, offsetof(struct dwarf_reg_state, ip));

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.
@ -30,10 +30,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
HIDDEN int HIDDEN int
dwarf_read_encoded_pointer (unw_addr_space_t as, unw_accessors_t *a, dwarf_read_encoded_pointer (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, unsigned char encoding, unw_word_t *addr, unsigned char encoding,
const unw_proc_info_t *pi, const unw_proc_info_t *pi,
unw_word_t *valp, void *arg) unw_word_t *valp, void *arg)
{ {
return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding, return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding,
pi, valp, arg); pi, valp, arg);
} }

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.

View file

@ -1,6 +1,6 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P. Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind. This file is part of libunwind.

View file

@ -2,7 +2,7 @@
#define elf32_h #define elf32_h
#ifndef ELF_CLASS #ifndef ELF_CLASS
#define ELF_CLASS ELFCLASS32 #define ELF_CLASS ELFCLASS32
#endif #endif
#include "elfxx.h" #include "elfxx.h"

View file

@ -2,7 +2,7 @@
#define elf64_h #define elf64_h
#ifndef ELF_CLASS #ifndef ELF_CLASS
#define ELF_CLASS ELFCLASS64 #define ELF_CLASS ELFCLASS64
#endif #endif
#include "elfxx.h" #include "elfxx.h"

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003-2005 Hewlett-Packard Co Copyright (C) 2003-2005 Hewlett-Packard Co
Copyright (C) 2007 David Mosberger-Tang Copyright (C) 2007 David Mosberger-Tang
Contributed by David Mosberger-Tang <dmosberger@gmail.com> Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind. This file is part of libunwind.
@ -43,8 +43,8 @@ elf_w (section_table) (struct elf_image *ei)
if (soff + ehdr->e_shnum * ehdr->e_shentsize > ei->size) if (soff + ehdr->e_shnum * ehdr->e_shentsize > ei->size)
{ {
Debug (1, "section table outside of image? (%lu > %lu)\n", Debug (1, "section table outside of image? (%lu > %lu)\n",
(unsigned long) (soff + ehdr->e_shnum * ehdr->e_shentsize), (unsigned long) (soff + ehdr->e_shnum * ehdr->e_shentsize),
(unsigned long) ei->size); (unsigned long) ei->size);
return NULL; return NULL;
} }
@ -65,8 +65,8 @@ elf_w (string_table) (struct elf_image *ei, int section)
if (str_soff + ehdr->e_shentsize > ei->size) if (str_soff + ehdr->e_shentsize > ei->size)
{ {
Debug (1, "string shdr table outside of image? (%lu > %lu)\n", Debug (1, "string shdr table outside of image? (%lu > %lu)\n",
(unsigned long) (str_soff + ehdr->e_shentsize), (unsigned long) (str_soff + ehdr->e_shentsize),
(unsigned long) ei->size); (unsigned long) ei->size);
return NULL; return NULL;
} }
str_shdr = (Elf_W (Shdr) *) ((char *) ei->image + str_soff); str_shdr = (Elf_W (Shdr) *) ((char *) ei->image + str_soff);
@ -74,8 +74,8 @@ elf_w (string_table) (struct elf_image *ei, int section)
if (str_shdr->sh_offset + str_shdr->sh_size > ei->size) if (str_shdr->sh_offset + str_shdr->sh_size > ei->size)
{ {
Debug (1, "string table outside of image? (%lu > %lu)\n", Debug (1, "string table outside of image? (%lu > %lu)\n",
(unsigned long) (str_shdr->sh_offset + str_shdr->sh_size), (unsigned long) (str_shdr->sh_offset + str_shdr->sh_size),
(unsigned long) ei->size); (unsigned long) ei->size);
return NULL; return NULL;
} }
@ -85,9 +85,9 @@ elf_w (string_table) (struct elf_image *ei, int section)
static int static int
elf_w (lookup_symbol) (unw_addr_space_t as, elf_w (lookup_symbol) (unw_addr_space_t as,
unw_word_t ip, struct elf_image *ei, unw_word_t ip, struct elf_image *ei,
Elf_W (Addr) load_offset, Elf_W (Addr) load_offset,
char *buf, size_t buf_len, Elf_W (Addr) *min_dist) char *buf, size_t buf_len, Elf_W (Addr) *min_dist)
{ {
size_t syment_size; size_t syment_size;
Elf_W (Ehdr) *ehdr = ei->image; Elf_W (Ehdr) *ehdr = ei->image;
@ -107,50 +107,50 @@ elf_w (lookup_symbol) (unw_addr_space_t as,
for (i = 0; i < ehdr->e_shnum; ++i) for (i = 0; i < ehdr->e_shnum; ++i)
{ {
switch (shdr->sh_type) switch (shdr->sh_type)
{ {
case SHT_SYMTAB: case SHT_SYMTAB:
case SHT_DYNSYM: case SHT_DYNSYM:
symtab = (Elf_W (Sym) *) ((char *) ei->image + shdr->sh_offset); symtab = (Elf_W (Sym) *) ((char *) ei->image + shdr->sh_offset);
symtab_end = (Elf_W (Sym) *) ((char *) symtab + shdr->sh_size); symtab_end = (Elf_W (Sym) *) ((char *) symtab + shdr->sh_size);
syment_size = shdr->sh_entsize; syment_size = shdr->sh_entsize;
strtab = elf_w (string_table) (ei, shdr->sh_link); strtab = elf_w (string_table) (ei, shdr->sh_link);
if (!strtab) if (!strtab)
break; break;
Debug (16, "symtab=0x%lx[%d]\n", Debug (16, "symtab=0x%lx[%d]\n",
(long) shdr->sh_offset, shdr->sh_type); (long) shdr->sh_offset, shdr->sh_type);
for (sym = symtab; for (sym = symtab;
sym < symtab_end; sym < symtab_end;
sym = (Elf_W (Sym) *) ((char *) sym + syment_size)) sym = (Elf_W (Sym) *) ((char *) sym + syment_size))
{ {
if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC
&& sym->st_shndx != SHN_UNDEF) && sym->st_shndx != SHN_UNDEF)
{ {
val = sym->st_value; val = sym->st_value;
if (sym->st_shndx != SHN_ABS) if (sym->st_shndx != SHN_ABS)
val += load_offset; val += load_offset;
if (tdep_get_func_addr (as, val, &val) < 0) if (tdep_get_func_addr (as, val, &val) < 0)
continue; continue;
Debug (16, "0x%016lx info=0x%02x %s\n", Debug (16, "0x%016lx info=0x%02x %s\n",
(long) val, sym->st_info, strtab + sym->st_name); (long) val, sym->st_info, strtab + sym->st_name);
if ((Elf_W (Addr)) (ip - val) < *min_dist) if ((Elf_W (Addr)) (ip - val) < *min_dist)
{ {
*min_dist = (Elf_W (Addr)) (ip - val); *min_dist = (Elf_W (Addr)) (ip - val);
strncpy (buf, strtab + sym->st_name, buf_len); strncpy (buf, strtab + sym->st_name, buf_len);
buf[buf_len - 1] = '\0'; buf[buf_len - 1] = '\0';
ret = (strlen (strtab + sym->st_name) >= buf_len ret = (strlen (strtab + sym->st_name) >= buf_len
? -UNW_ENOMEM : 0); ? -UNW_ENOMEM : 0);
} }
} }
} }
break; break;
default: default:
break; break;
} }
shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize);
} }
return ret; return ret;
@ -158,7 +158,7 @@ elf_w (lookup_symbol) (unw_addr_space_t as,
static Elf_W (Addr) static Elf_W (Addr)
elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase, elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase,
unsigned long mapoff) unsigned long mapoff)
{ {
Elf_W (Addr) offset = 0; Elf_W (Addr) offset = 0;
Elf_W (Ehdr) *ehdr; Elf_W (Ehdr) *ehdr;
@ -171,8 +171,8 @@ elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase,
for (i = 0; i < ehdr->e_phnum; ++i) for (i = 0; i < ehdr->e_phnum; ++i)
if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff) if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff)
{ {
offset = segbase - phdr[i].p_vaddr; offset = segbase - phdr[i].p_vaddr;
break; break;
} }
return offset; return offset;
@ -199,7 +199,7 @@ xz_uncompressed_size (uint8_t *compressed, size_t length)
uint8_t *indexdata = footer - options.backward_size; uint8_t *indexdata = footer - options.backward_size;
if (lzma_index_buffer_decode (&index, &memlimit, NULL, indexdata, if (lzma_index_buffer_decode (&index, &memlimit, NULL, indexdata,
&pos, options.backward_size) != LZMA_OK) &pos, options.backward_size) != LZMA_OK)
return 0; return 0;
if (lzma_index_size (index) == options.backward_size) if (lzma_index_size (index) == options.backward_size)
@ -236,21 +236,21 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi)
for (i = 0; i < ehdr->e_shnum; ++i) for (i = 0; i < ehdr->e_shnum; ++i)
{ {
if (strcmp (strtab + shdr->sh_name, ".gnu_debugdata") == 0) if (strcmp (strtab + shdr->sh_name, ".gnu_debugdata") == 0)
{ {
if (shdr->sh_offset + shdr->sh_size > ei->size) if (shdr->sh_offset + shdr->sh_size > ei->size)
{ {
Debug (1, ".gnu_debugdata outside image? (0x%lu > 0x%lu)\n", Debug (1, ".gnu_debugdata outside image? (0x%lu > 0x%lu)\n",
(unsigned long) shdr->sh_offset + shdr->sh_size, (unsigned long) shdr->sh_offset + shdr->sh_size,
(unsigned long) ei->size); (unsigned long) ei->size);
return 0; return 0;
} }
Debug (16, "found .gnu_debugdata at 0x%lx\n", Debug (16, "found .gnu_debugdata at 0x%lx\n",
(unsigned long) shdr->sh_offset); (unsigned long) shdr->sh_offset);
compressed = ((uint8_t *) ei->image) + shdr->sh_offset; compressed = ((uint8_t *) ei->image) + shdr->sh_offset;
compressed_len = shdr->sh_size; compressed_len = shdr->sh_size;
break; break;
} }
shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize);
} }
@ -268,7 +268,7 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi)
mdi->size = uncompressed_len; mdi->size = uncompressed_len;
mdi->image = mmap (NULL, uncompressed_len, PROT_READ|PROT_WRITE, mdi->image = mmap (NULL, uncompressed_len, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (mdi->image == MAP_FAILED) if (mdi->image == MAP_FAILED)
return 0; return 0;
@ -276,8 +276,8 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi)
size_t in_pos = 0, out_pos = 0; size_t in_pos = 0, out_pos = 0;
lzma_ret lret; lzma_ret lret;
lret = lzma_stream_buffer_decode (&memlimit, 0, NULL, lret = lzma_stream_buffer_decode (&memlimit, 0, NULL,
compressed, &in_pos, compressed_len, compressed, &in_pos, compressed_len,
mdi->image, &out_pos, mdi->size); mdi->image, &out_pos, mdi->size);
if (lret != LZMA_OK) if (lret != LZMA_OK)
{ {
Debug (1, "LZMA decompression failed: %d\n", lret); Debug (1, "LZMA decompression failed: %d\n", lret);
@ -302,10 +302,10 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi)
HIDDEN int HIDDEN int
elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei, elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei,
unsigned long segbase, unsigned long segbase,
unsigned long mapoff, unsigned long mapoff,
unw_word_t ip, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp) char *buf, size_t buf_len, unw_word_t *offp)
{ {
Elf_W (Addr) load_offset; Elf_W (Addr) load_offset;
Elf_W (Addr) min_dist = ~(Elf_W (Addr))0; Elf_W (Addr) min_dist = ~(Elf_W (Addr))0;
@ -320,19 +320,19 @@ elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei,
if (elf_w (extract_minidebuginfo) (ei, &mdi)) if (elf_w (extract_minidebuginfo) (ei, &mdi))
{ {
int ret_mdi = elf_w (lookup_symbol) (as, ip, &mdi, load_offset, buf, int ret_mdi = elf_w (lookup_symbol) (as, ip, &mdi, load_offset, buf,
buf_len, &min_dist); buf_len, &min_dist);
/* Closer symbol was found (possibly truncated). */ /* Closer symbol was found (possibly truncated). */
if (ret_mdi == 0 || ret_mdi == -UNW_ENOMEM) if (ret_mdi == 0 || ret_mdi == -UNW_ENOMEM)
{ {
ret = ret_mdi; ret = ret_mdi;
} }
munmap (mdi.image, mdi.size); munmap (mdi.image, mdi.size);
} }
if (min_dist >= ei->size) if (min_dist >= ei->size)
return -UNW_ENOINFO; /* not found */ return -UNW_ENOINFO; /* not found */
if (offp) if (offp)
*offp = min_dist; *offp = min_dist;
return ret; return ret;
@ -340,7 +340,7 @@ elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei,
HIDDEN int HIDDEN int
elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp) char *buf, size_t buf_len, unw_word_t *offp)
{ {
unsigned long segbase, mapoff; unsigned long segbase, mapoff;
struct elf_image ei; struct elf_image ei;

View file

@ -1,7 +1,7 @@
/* libunwind - a platform-independent unwind library /* libunwind - a platform-independent unwind library
Copyright (C) 2003, 2005 Hewlett-Packard Co Copyright (C) 2003, 2005 Hewlett-Packard Co
Copyright (C) 2007 David Mosberger-Tang Copyright (C) 2007 David Mosberger-Tang
Contributed by David Mosberger-Tang <dmosberger@gmail.com> Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind. This file is part of libunwind.
@ -33,26 +33,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "libunwind_i.h" #include "libunwind_i.h"
#if ELF_CLASS == ELFCLASS32 #if ELF_CLASS == ELFCLASS32
# define ELF_W(x) ELF32_##x # define ELF_W(x) ELF32_##x
# define Elf_W(x) Elf32_##x # define Elf_W(x) Elf32_##x
# define elf_w(x) _Uelf32_##x # define elf_w(x) _Uelf32_##x
#else #else
# define ELF_W(x) ELF64_##x # define ELF_W(x) ELF64_##x
# define Elf_W(x) Elf64_##x # define Elf_W(x) Elf64_##x
# define elf_w(x) _Uelf64_##x # define elf_w(x) _Uelf64_##x
#endif #endif
extern int elf_w (get_proc_name) (unw_addr_space_t as, extern int elf_w (get_proc_name) (unw_addr_space_t as,
pid_t pid, unw_word_t ip, pid_t pid, unw_word_t ip,
char *buf, size_t len, char *buf, size_t len,
unw_word_t *offp); unw_word_t *offp);
extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as, extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as,
struct elf_image *ei, struct elf_image *ei,
unsigned long segbase, unsigned long segbase,
unsigned long mapoff, unsigned long mapoff,
unw_word_t ip, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp); char *buf, size_t buf_len, unw_word_t *offp);
static inline int static inline int
elf_w (valid_object) (struct elf_image *ei) elf_w (valid_object) (struct elf_image *ei)
@ -61,9 +61,9 @@ elf_w (valid_object) (struct elf_image *ei)
return 0; return 0;
return (memcmp (ei->image, ELFMAG, SELFMAG) == 0 return (memcmp (ei->image, ELFMAG, SELFMAG) == 0
&& ((uint8_t *) ei->image)[EI_CLASS] == ELF_CLASS && ((uint8_t *) ei->image)[EI_CLASS] == ELF_CLASS
&& ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE && ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE
&& ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT); && ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT);
} }
static inline int static inline int

Some files were not shown because too many files have changed in this diff Show more