]> sourceware.org Git - systemtap.git/blame - runtime/unwind/unwind.h
Be paranoid about table size resolving cie_for_fde and fde_pointer_type.
[systemtap.git] / runtime / unwind / unwind.h
CommitLineData
949e84da
FCE
1/* -*- linux-c -*-
2 *
3 * dwarf unwinder header file
4285dc9a 4 * Copyright (C) 2008, 2009 Red Hat Inc.
949e84da
FCE
5 * Copyright (C) 2002-2006 Novell, Inc.
6 *
7 * This file is part of systemtap, and is free software. You can
8 * redistribute it and/or modify it under the terms of the GNU General
9 * Public License (GPL); either version 2, or (at your option) any
10 * later version.
11 */
12
13#ifndef _STP_UNWIND_H_
14#define _STP_UNWIND_H_
15
ca1655b0
FCE
16#ifdef STP_USE_DWARF_UNWINDER
17
949e84da
FCE
18#if defined (__x86_64__)
19#include "x86_64.h"
20#elif defined (__i386__)
21#include "i386.h"
22#else
23#error "Unsupported dwarf unwind architecture"
24#endif
25
9afe68ed 26#define STP_MAX_STACK_DEPTH 8
949e84da 27
f1743f00
FCE
28#ifndef BUILD_BUG_ON_ZERO
29#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
30#endif
31
32
949e84da
FCE
33#define EXTRA_INFO(f) { \
34 BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
35 % FIELD_SIZEOF(struct unwind_frame_info, f)) \
36 + offsetof(struct unwind_frame_info, f) \
37 / FIELD_SIZEOF(struct unwind_frame_info, f), \
38 FIELD_SIZEOF(struct unwind_frame_info, f) \
39 }
40#define PTREGS_INFO(f) EXTRA_INFO(regs.f)
41
42static const struct {
43 unsigned offs:BITS_PER_LONG / 2;
44 unsigned width:BITS_PER_LONG / 2;
45} reg_info[] = {
46 UNW_REGISTER_INFO
47};
48
49#undef PTREGS_INFO
50#undef EXTRA_INFO
51
52#ifndef REG_INVALID
53#define REG_INVALID(r) (reg_info[r].width == 0)
54#endif
55
56#define DW_CFA_nop 0x00
57#define DW_CFA_set_loc 0x01
58#define DW_CFA_advance_loc1 0x02
59#define DW_CFA_advance_loc2 0x03
60#define DW_CFA_advance_loc4 0x04
61#define DW_CFA_offset_extended 0x05
62#define DW_CFA_restore_extended 0x06
63#define DW_CFA_undefined 0x07
64#define DW_CFA_same_value 0x08
65#define DW_CFA_register 0x09
66#define DW_CFA_remember_state 0x0a
67#define DW_CFA_restore_state 0x0b
68#define DW_CFA_def_cfa 0x0c
69#define DW_CFA_def_cfa_register 0x0d
70#define DW_CFA_def_cfa_offset 0x0e
71#define DW_CFA_def_cfa_expression 0x0f
72#define DW_CFA_expression 0x10
73#define DW_CFA_offset_extended_sf 0x11
74#define DW_CFA_def_cfa_sf 0x12
75#define DW_CFA_def_cfa_offset_sf 0x13
76#define DW_CFA_val_offset 0x14
77#define DW_CFA_val_offset_sf 0x15
78#define DW_CFA_val_expression 0x16
79#define DW_CFA_lo_user 0x1c
80#define DW_CFA_GNU_window_save 0x2d
81#define DW_CFA_GNU_args_size 0x2e
82#define DW_CFA_GNU_negative_offset_extended 0x2f
83#define DW_CFA_hi_user 0x3f
84
85#define DW_EH_PE_absptr 0x00
86#define DW_EH_PE_leb128 0x01
87#define DW_EH_PE_data2 0x02
88#define DW_EH_PE_data4 0x03
89#define DW_EH_PE_data8 0x04
90#define DW_EH_PE_FORM 0x07 /* mask */
91#define DW_EH_PE_signed 0x08 /* signed versions of above have this bit set */
92
93#define DW_EH_PE_pcrel 0x10
94#define DW_EH_PE_textrel 0x20
95#define DW_EH_PE_datarel 0x30
96#define DW_EH_PE_funcrel 0x40
97#define DW_EH_PE_aligned 0x50
98#define DW_EH_PE_ADJUST 0x70 /* mask */
99#define DW_EH_PE_indirect 0x80
100#define DW_EH_PE_omit 0xff
101
102typedef unsigned long uleb128_t;
103typedef signed long sleb128_t;
104
105static struct unwind_table {
106 unsigned long pc; /* text */
107 unsigned long range; /* text_size */
108 const void *address; /* unwind_data */
109 unsigned long size; /* unwind_data_len */
110 const unsigned char *header; /* unwind_header */
111 unsigned long hdrsz;
112 struct unwind_table *link;
113 const char *name; /* module name */
114} root_table;
115
116struct unwind_item {
117 enum item_location {
118 Nowhere,
119 Memory,
120 Register,
121 Value
122 } where;
123 uleb128_t value;
124};
125
126struct unwind_state {
127 uleb128_t loc, org;
128 const u8 *cieStart, *cieEnd;
129 uleb128_t codeAlign;
130 sleb128_t dataAlign;
131 struct cfa {
132 uleb128_t reg, offs;
133 } cfa;
134 struct unwind_item regs[ARRAY_SIZE(reg_info)];
135 unsigned stackDepth:8;
136 unsigned version:8;
137 const u8 *label;
9afe68ed 138 const u8 *stack[STP_MAX_STACK_DEPTH];
949e84da
FCE
139};
140
141static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
142static unsigned long read_pointer(const u8 **pLoc,
143 const void *end,
144 signed ptrType);
145static const u32 bad_cie, not_fde;
bf043a5f
MW
146static const u32 *cie_for_fde(const u32 *fde, void *table,
147 uint32_t table_len, int is_ehframe);
148static signed fde_pointer_type(const u32 *cie,
149 void *table, uint32_t table_len);
949e84da 150
ca1655b0
FCE
151
152#endif /* STP_USE_DWARF_UNWINDER */
949e84da 153#endif /*_STP_UNWIND_H_*/
This page took 0.058716 seconds and 5 git commands to generate.