• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
3   *
4   * This file is subject to the terms and conditions of the GNU General Public
5   * License.  See the file "COPYING" in the main directory of this archive
6   * for more details.
7   *
8   */
9  #ifndef __ASM_SH_DWARF_H
10  #define __ASM_SH_DWARF_H
11  
12  #ifdef CONFIG_DWARF_UNWINDER
13  
14  /*
15   * DWARF expression operations
16   */
17  #define DW_OP_addr	0x03
18  #define DW_OP_deref	0x06
19  #define DW_OP_const1u	0x08
20  #define DW_OP_const1s	0x09
21  #define DW_OP_const2u	0x0a
22  #define DW_OP_const2s	0x0b
23  #define DW_OP_const4u	0x0c
24  #define DW_OP_const4s	0x0d
25  #define DW_OP_const8u	0x0e
26  #define DW_OP_const8s	0x0f
27  #define DW_OP_constu	0x10
28  #define DW_OP_consts	0x11
29  #define DW_OP_dup	0x12
30  #define DW_OP_drop	0x13
31  #define DW_OP_over	0x14
32  #define DW_OP_pick	0x15
33  #define DW_OP_swap	0x16
34  #define DW_OP_rot	0x17
35  #define DW_OP_xderef	0x18
36  #define DW_OP_abs	0x19
37  #define DW_OP_and	0x1a
38  #define DW_OP_div	0x1b
39  #define DW_OP_minus	0x1c
40  #define DW_OP_mod	0x1d
41  #define DW_OP_mul	0x1e
42  #define DW_OP_neg	0x1f
43  #define DW_OP_not	0x20
44  #define DW_OP_or	0x21
45  #define DW_OP_plus	0x22
46  #define DW_OP_plus_uconst	0x23
47  #define DW_OP_shl	0x24
48  #define DW_OP_shr	0x25
49  #define DW_OP_shra	0x26
50  #define DW_OP_xor	0x27
51  #define DW_OP_skip	0x2f
52  #define DW_OP_bra	0x28
53  #define DW_OP_eq	0x29
54  #define DW_OP_ge	0x2a
55  #define DW_OP_gt	0x2b
56  #define DW_OP_le	0x2c
57  #define DW_OP_lt	0x2d
58  #define DW_OP_ne	0x2e
59  #define DW_OP_lit0	0x30
60  #define DW_OP_lit1	0x31
61  #define DW_OP_lit2	0x32
62  #define DW_OP_lit3	0x33
63  #define DW_OP_lit4	0x34
64  #define DW_OP_lit5	0x35
65  #define DW_OP_lit6	0x36
66  #define DW_OP_lit7	0x37
67  #define DW_OP_lit8	0x38
68  #define DW_OP_lit9	0x39
69  #define DW_OP_lit10	0x3a
70  #define DW_OP_lit11	0x3b
71  #define DW_OP_lit12	0x3c
72  #define DW_OP_lit13	0x3d
73  #define DW_OP_lit14	0x3e
74  #define DW_OP_lit15	0x3f
75  #define DW_OP_lit16	0x40
76  #define DW_OP_lit17	0x41
77  #define DW_OP_lit18	0x42
78  #define DW_OP_lit19	0x43
79  #define DW_OP_lit20	0x44
80  #define DW_OP_lit21	0x45
81  #define DW_OP_lit22	0x46
82  #define DW_OP_lit23	0x47
83  #define DW_OP_lit24	0x48
84  #define DW_OP_lit25	0x49
85  #define DW_OP_lit26	0x4a
86  #define DW_OP_lit27	0x4b
87  #define DW_OP_lit28	0x4c
88  #define DW_OP_lit29	0x4d
89  #define DW_OP_lit30	0x4e
90  #define DW_OP_lit31	0x4f
91  #define DW_OP_reg0	0x50
92  #define DW_OP_reg1	0x51
93  #define DW_OP_reg2	0x52
94  #define DW_OP_reg3	0x53
95  #define DW_OP_reg4	0x54
96  #define DW_OP_reg5	0x55
97  #define DW_OP_reg6	0x56
98  #define DW_OP_reg7	0x57
99  #define DW_OP_reg8	0x58
100  #define DW_OP_reg9	0x59
101  #define DW_OP_reg10	0x5a
102  #define DW_OP_reg11	0x5b
103  #define DW_OP_reg12	0x5c
104  #define DW_OP_reg13	0x5d
105  #define DW_OP_reg14	0x5e
106  #define DW_OP_reg15	0x5f
107  #define DW_OP_reg16	0x60
108  #define DW_OP_reg17	0x61
109  #define DW_OP_reg18	0x62
110  #define DW_OP_reg19	0x63
111  #define DW_OP_reg20	0x64
112  #define DW_OP_reg21	0x65
113  #define DW_OP_reg22	0x66
114  #define DW_OP_reg23	0x67
115  #define DW_OP_reg24	0x68
116  #define DW_OP_reg25	0x69
117  #define DW_OP_reg26	0x6a
118  #define DW_OP_reg27	0x6b
119  #define DW_OP_reg28	0x6c
120  #define DW_OP_reg29	0x6d
121  #define DW_OP_reg30	0x6e
122  #define DW_OP_reg31	0x6f
123  #define DW_OP_breg0	0x70
124  #define DW_OP_breg1	0x71
125  #define DW_OP_breg2	0x72
126  #define DW_OP_breg3	0x73
127  #define DW_OP_breg4	0x74
128  #define DW_OP_breg5	0x75
129  #define DW_OP_breg6	0x76
130  #define DW_OP_breg7	0x77
131  #define DW_OP_breg8	0x78
132  #define DW_OP_breg9	0x79
133  #define DW_OP_breg10	0x7a
134  #define DW_OP_breg11	0x7b
135  #define DW_OP_breg12	0x7c
136  #define DW_OP_breg13	0x7d
137  #define DW_OP_breg14	0x7e
138  #define DW_OP_breg15	0x7f
139  #define DW_OP_breg16	0x80
140  #define DW_OP_breg17	0x81
141  #define DW_OP_breg18	0x82
142  #define DW_OP_breg19	0x83
143  #define DW_OP_breg20	0x84
144  #define DW_OP_breg21	0x85
145  #define DW_OP_breg22	0x86
146  #define DW_OP_breg23	0x87
147  #define DW_OP_breg24	0x88
148  #define DW_OP_breg25	0x89
149  #define DW_OP_breg26	0x8a
150  #define DW_OP_breg27	0x8b
151  #define DW_OP_breg28	0x8c
152  #define DW_OP_breg29	0x8d
153  #define DW_OP_breg30	0x8e
154  #define DW_OP_breg31	0x8f
155  #define DW_OP_regx	0x90
156  #define DW_OP_fbreg	0x91
157  #define DW_OP_bregx	0x92
158  #define DW_OP_piece	0x93
159  #define DW_OP_deref_size	0x94
160  #define DW_OP_xderef_size	0x95
161  #define DW_OP_nop	0x96
162  #define DW_OP_push_object_address	0x97
163  #define DW_OP_call2	0x98
164  #define DW_OP_call4	0x99
165  #define DW_OP_call_ref	0x9a
166  #define DW_OP_form_tls_address	0x9b
167  #define DW_OP_call_frame_cfa	0x9c
168  #define DW_OP_bit_piece	0x9d
169  #define DW_OP_lo_user	0xe0
170  #define DW_OP_hi_user	0xff
171  
172  /*
173   * Addresses used in FDE entries in the .eh_frame section may be encoded
174   * using one of the following encodings.
175   */
176  #define DW_EH_PE_absptr	0x00
177  #define DW_EH_PE_omit	0xff
178  #define DW_EH_PE_uleb128	0x01
179  #define DW_EH_PE_udata2	0x02
180  #define DW_EH_PE_udata4	0x03
181  #define DW_EH_PE_udata8	0x04
182  #define DW_EH_PE_sleb128	0x09
183  #define DW_EH_PE_sdata2	0x0a
184  #define DW_EH_PE_sdata4	0x0b
185  #define DW_EH_PE_sdata8	0x0c
186  #define DW_EH_PE_signed	0x09
187  
188  #define DW_EH_PE_pcrel	0x10
189  
190  /*
191   * The architecture-specific register number that contains the return
192   * address in the .debug_frame table.
193   */
194  #define DWARF_ARCH_RA_REG	17
195  
196  #ifndef __ASSEMBLY__
197  
198  #include <linux/compiler.h>
199  #include <linux/bug.h>
200  #include <linux/list.h>
201  #include <linux/module.h>
202  
203  /*
204   * Read either the frame pointer (r14) or the stack pointer (r15).
205   * NOTE: this MUST be inlined.
206   */
dwarf_read_arch_reg(unsigned int reg)207  static __always_inline unsigned long dwarf_read_arch_reg(unsigned int reg)
208  {
209  	unsigned long value = 0;
210  
211  	switch (reg) {
212  	case 14:
213  		__asm__ __volatile__("mov r14, %0\n" : "=r" (value));
214  		break;
215  	case 15:
216  		__asm__ __volatile__("mov r15, %0\n" : "=r" (value));
217  		break;
218  	default:
219  		BUG();
220  	}
221  
222  	return value;
223  }
224  
225  /**
226   *	dwarf_cie - Common Information Entry
227   */
228  struct dwarf_cie {
229  	unsigned long length;
230  	unsigned long cie_id;
231  	unsigned char version;
232  	const char *augmentation;
233  	unsigned int code_alignment_factor;
234  	int data_alignment_factor;
235  
236  	/* Which column in the rule table represents return addr of func. */
237  	unsigned int return_address_reg;
238  
239  	unsigned char *initial_instructions;
240  	unsigned char *instructions_end;
241  
242  	unsigned char encoding;
243  
244  	unsigned long cie_pointer;
245  
246  	unsigned long flags;
247  #define DWARF_CIE_Z_AUGMENTATION	(1 << 0)
248  
249  	/* linked-list entry if this CIE is from a module */
250  	struct list_head link;
251  
252  	struct rb_node node;
253  };
254  
255  /**
256   *	dwarf_fde - Frame Description Entry
257   */
258  struct dwarf_fde {
259  	unsigned long length;
260  	unsigned long cie_pointer;
261  	struct dwarf_cie *cie;
262  	unsigned long initial_location;
263  	unsigned long address_range;
264  	unsigned char *instructions;
265  	unsigned char *end;
266  
267  	/* linked-list entry if this FDE is from a module */
268  	struct list_head link;
269  
270  	struct rb_node node;
271  };
272  
273  /**
274   *	dwarf_frame - DWARF information for a frame in the call stack
275   */
276  struct dwarf_frame {
277  	struct dwarf_frame *prev, *next;
278  
279  	unsigned long pc;
280  
281  	struct list_head reg_list;
282  
283  	unsigned long cfa;
284  
285  	/* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */
286  	unsigned int cfa_register;
287  	unsigned int cfa_offset;
288  
289  	/* Valid when DW_FRAME_CFA_REG_EXP is set in flags */
290  	unsigned char *cfa_expr;
291  	unsigned int cfa_expr_len;
292  
293  	unsigned long flags;
294  #define DWARF_FRAME_CFA_REG_OFFSET	(1 << 0)
295  #define DWARF_FRAME_CFA_REG_EXP		(1 << 1)
296  
297  	unsigned long return_addr;
298  };
299  
300  /**
301   *	dwarf_reg - DWARF register
302   *	@flags: Describes how to calculate the value of this register
303   */
304  struct dwarf_reg {
305  	struct list_head link;
306  
307  	unsigned int number;
308  
309  	unsigned long addr;
310  	unsigned long flags;
311  #define DWARF_REG_OFFSET	(1 << 0)
312  #define DWARF_VAL_OFFSET	(1 << 1)
313  #define DWARF_UNDEFINED		(1 << 2)
314  };
315  
316  /*
317   * Call Frame instruction opcodes.
318   */
319  #define DW_CFA_advance_loc	0x40
320  #define DW_CFA_offset		0x80
321  #define DW_CFA_restore		0xc0
322  #define DW_CFA_nop		0x00
323  #define DW_CFA_set_loc		0x01
324  #define DW_CFA_advance_loc1	0x02
325  #define DW_CFA_advance_loc2	0x03
326  #define DW_CFA_advance_loc4	0x04
327  #define DW_CFA_offset_extended	0x05
328  #define DW_CFA_restore_extended	0x06
329  #define DW_CFA_undefined	0x07
330  #define DW_CFA_same_value	0x08
331  #define DW_CFA_register		0x09
332  #define DW_CFA_remember_state	0x0a
333  #define DW_CFA_restore_state	0x0b
334  #define DW_CFA_def_cfa		0x0c
335  #define DW_CFA_def_cfa_register	0x0d
336  #define DW_CFA_def_cfa_offset	0x0e
337  #define DW_CFA_def_cfa_expression	0x0f
338  #define DW_CFA_expression	0x10
339  #define DW_CFA_offset_extended_sf	0x11
340  #define DW_CFA_def_cfa_sf	0x12
341  #define DW_CFA_def_cfa_offset_sf	0x13
342  #define DW_CFA_val_offset	0x14
343  #define DW_CFA_val_offset_sf	0x15
344  #define DW_CFA_val_expression	0x16
345  #define DW_CFA_lo_user		0x1c
346  #define DW_CFA_hi_user		0x3f
347  
348  /* GNU extension opcodes  */
349  #define DW_CFA_GNU_args_size	0x2e
350  #define DW_CFA_GNU_negative_offset_extended 0x2f
351  
352  /*
353   * Some call frame instructions encode their operands in the opcode. We
354   * need some helper functions to extract both the opcode and operands
355   * from an instruction.
356   */
DW_CFA_opcode(unsigned long insn)357  static inline unsigned int DW_CFA_opcode(unsigned long insn)
358  {
359  	return (insn & 0xc0);
360  }
361  
DW_CFA_operand(unsigned long insn)362  static inline unsigned int DW_CFA_operand(unsigned long insn)
363  {
364  	return (insn & 0x3f);
365  }
366  
367  #define DW_EH_FRAME_CIE	0		/* .eh_frame CIE IDs are 0 */
368  #define DW_CIE_ID	0xffffffff
369  #define DW64_CIE_ID	0xffffffffffffffffULL
370  
371  /*
372   * DWARF FDE/CIE length field values.
373   */
374  #define DW_EXT_LO	0xfffffff0
375  #define DW_EXT_HI	0xffffffff
376  #define DW_EXT_DWARF64	DW_EXT_HI
377  
378  extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
379  					      struct dwarf_frame *);
380  extern void dwarf_free_frame(struct dwarf_frame *);
381  
382  extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
383  				 struct module *);
384  extern void module_dwarf_cleanup(struct module *);
385  
386  #endif /* !__ASSEMBLY__ */
387  
388  #define CFI_STARTPROC	.cfi_startproc
389  #define CFI_ENDPROC	.cfi_endproc
390  #define CFI_DEF_CFA	.cfi_def_cfa
391  #define CFI_REGISTER	.cfi_register
392  #define CFI_REL_OFFSET	.cfi_rel_offset
393  #define CFI_UNDEFINED	.cfi_undefined
394  
395  #else
396  
397  /*
398   * Use the asm comment character to ignore the rest of the line.
399   */
400  #define CFI_IGNORE	!
401  
402  #define CFI_STARTPROC	CFI_IGNORE
403  #define CFI_ENDPROC	CFI_IGNORE
404  #define CFI_DEF_CFA	CFI_IGNORE
405  #define CFI_REGISTER	CFI_IGNORE
406  #define CFI_REL_OFFSET	CFI_IGNORE
407  #define CFI_UNDEFINED	CFI_IGNORE
408  
409  #ifndef __ASSEMBLY__
dwarf_unwinder_init(void)410  static inline void dwarf_unwinder_init(void)
411  {
412  }
413  
414  #define module_dwarf_finalize(hdr, sechdrs, me)	(0)
415  #define module_dwarf_cleanup(mod)		do { } while (0)
416  
417  #endif
418  
419  #endif /* CONFIG_DWARF_UNWINDER */
420  
421  #endif /* __ASM_SH_DWARF_H */
422