diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-03-25 11:46:14 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-03-25 11:46:14 -0400 |
commit | 949e84da2d80837b192209efb4122f2ff59ab54d (patch) | |
tree | 3b09669cc429da4218f8ca3157bc78133ea1b0ab /runtime/unwind/unwind.h | |
parent | 6043234f6d6efba366f67666b2197a47f5bdafce (diff) | |
download | systemtap-steved-949e84da2d80837b192209efb4122f2ff59ab54d.tar.gz systemtap-steved-949e84da2d80837b192209efb4122f2ff59ab54d.tar.xz systemtap-steved-949e84da2d80837b192209efb4122f2ff59ab54d.zip |
add (back) runtime/unwind files
Diffstat (limited to 'runtime/unwind/unwind.h')
-rw-r--r-- | runtime/unwind/unwind.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/runtime/unwind/unwind.h b/runtime/unwind/unwind.h new file mode 100644 index 00000000..8651cb9e --- /dev/null +++ b/runtime/unwind/unwind.h @@ -0,0 +1,142 @@ +/* -*- linux-c -*- + * + * dwarf unwinder header file + * Copyright (C) 2008 Red Hat Inc. + * Copyright (C) 2002-2006 Novell, Inc. + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +#ifndef _STP_UNWIND_H_ +#define _STP_UNWIND_H_ + +#if defined (__x86_64__) +#include "x86_64.h" +#elif defined (__i386__) +#include "i386.h" +#else +#error "Unsupported dwarf unwind architecture" +#endif + +#define MAX_STACK_DEPTH 8 + +#define EXTRA_INFO(f) { \ + BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \ + % FIELD_SIZEOF(struct unwind_frame_info, f)) \ + + offsetof(struct unwind_frame_info, f) \ + / FIELD_SIZEOF(struct unwind_frame_info, f), \ + FIELD_SIZEOF(struct unwind_frame_info, f) \ + } +#define PTREGS_INFO(f) EXTRA_INFO(regs.f) + +static const struct { + unsigned offs:BITS_PER_LONG / 2; + unsigned width:BITS_PER_LONG / 2; +} reg_info[] = { + UNW_REGISTER_INFO +}; + +#undef PTREGS_INFO +#undef EXTRA_INFO + +#ifndef REG_INVALID +#define REG_INVALID(r) (reg_info[r].width == 0) +#endif + +#define DW_CFA_nop 0x00 +#define DW_CFA_set_loc 0x01 +#define DW_CFA_advance_loc1 0x02 +#define DW_CFA_advance_loc2 0x03 +#define DW_CFA_advance_loc4 0x04 +#define DW_CFA_offset_extended 0x05 +#define DW_CFA_restore_extended 0x06 +#define DW_CFA_undefined 0x07 +#define DW_CFA_same_value 0x08 +#define DW_CFA_register 0x09 +#define DW_CFA_remember_state 0x0a +#define DW_CFA_restore_state 0x0b +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_register 0x0d +#define DW_CFA_def_cfa_offset 0x0e +#define DW_CFA_def_cfa_expression 0x0f +#define DW_CFA_expression 0x10 +#define DW_CFA_offset_extended_sf 0x11 +#define DW_CFA_def_cfa_sf 0x12 +#define DW_CFA_def_cfa_offset_sf 0x13 +#define DW_CFA_val_offset 0x14 +#define DW_CFA_val_offset_sf 0x15 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_lo_user 0x1c +#define DW_CFA_GNU_window_save 0x2d +#define DW_CFA_GNU_args_size 0x2e +#define DW_CFA_GNU_negative_offset_extended 0x2f +#define DW_CFA_hi_user 0x3f + +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_leb128 0x01 +#define DW_EH_PE_data2 0x02 +#define DW_EH_PE_data4 0x03 +#define DW_EH_PE_data8 0x04 +#define DW_EH_PE_FORM 0x07 /* mask */ +#define DW_EH_PE_signed 0x08 /* signed versions of above have this bit set */ + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 +#define DW_EH_PE_aligned 0x50 +#define DW_EH_PE_ADJUST 0x70 /* mask */ +#define DW_EH_PE_indirect 0x80 +#define DW_EH_PE_omit 0xff + +typedef unsigned long uleb128_t; +typedef signed long sleb128_t; + +static struct unwind_table { + unsigned long pc; /* text */ + unsigned long range; /* text_size */ + const void *address; /* unwind_data */ + unsigned long size; /* unwind_data_len */ + const unsigned char *header; /* unwind_header */ + unsigned long hdrsz; + struct unwind_table *link; + const char *name; /* module name */ +} root_table; + +struct unwind_item { + enum item_location { + Nowhere, + Memory, + Register, + Value + } where; + uleb128_t value; +}; + +struct unwind_state { + uleb128_t loc, org; + const u8 *cieStart, *cieEnd; + uleb128_t codeAlign; + sleb128_t dataAlign; + struct cfa { + uleb128_t reg, offs; + } cfa; + struct unwind_item regs[ARRAY_SIZE(reg_info)]; + unsigned stackDepth:8; + unsigned version:8; + const u8 *label; + const u8 *stack[MAX_STACK_DEPTH]; +}; + +static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 }; +static unsigned long read_pointer(const u8 **pLoc, + const void *end, + signed ptrType); +static const u32 bad_cie, not_fde; +static const u32 *cie_for_fde(const u32 *fde, const struct _stp_module *); +static signed fde_pointer_type(const u32 *cie); + +#endif /*_STP_UNWIND_H_*/ |