📄 cfi_annotations.patch
字号:
+#define _QUOTE_THIS(a) #a+/* Don't let CPP see the " and , \042=" \054=, */+#define DWARF_preamble .section .debug_frame \054\042\042\054%progbits+#endif++#ifdef CONFIG_64BIT+#define DATA_ALIGN_FACTOR 8+#define ADDR_LOC .quad+#else+#define DATA_ALIGN_FACTOR 4+#define ADDR_LOC .long+#endif++#include <linux/dwarf2-defs.h>+/*+ * This macro starts a debug frame section. The debug_frame describes+ * where to find the registers that the enclosing function saved on+ * entry.+ *+ * ORD is use by the label generator and should be the same as what is+ * passed to CFI_postamble.+ *+ * pc, pc register gdb ordinal.+ *+ * code_align this is the factor used to define locations or regions+ * where the given definitions apply. If you use labels to define these+ * this should be 1.+ *+ * data_align this is the factor used to define register offsets. If+ * you use struct offset, this should be the size of the register in+ * bytes or the negative of that. This is how it is used: you will+ * define a register as the reference register, say the stack pointer,+ * then you will say where a register is located relative to this+ * reference registers value, say 40 for register 3 (the gdb register+ * number). The <40> will be multiplied by <data_align> to define the+ * byte offset of the given register (3, in this example). So if your+ * <40> is the byte offset and the reference register points at the+ * begining, you would want 1 for the data_offset. If <40> was the 40th+ * 4-byte element in that structure you would want 4. And if your+ * reference register points at the end of the structure you would want+ * a negative data_align value(and you would have to do other math as+ * well).+ */++#define CFI_preamble(ORD, pc, code_align, data_align) \+ DWARF_preamble NL \+ .align DATA_ALIGN_FACTOR NL \+ .globl CAT3(frame,_,ORD) NL \+CAT3(frame,_,ORD): NL \+ .long 7f-6f NL \+6: \+ .long DW_CIE_ID NL \+ .byte DW_CIE_VERSION NL \+ .byte 0 NL \+ .uleb128 code_align NL \+ .sleb128 data_align NL \+ .byte pc NL++/*+ * After the above macro and prior to the CFI_postamble, you need to+ * define the initial state. This starts with defining the reference+ * register and, usually the pc. Here are some helper macros:+ */++#define CFA_define_reference(reg, offset) \+ .byte DW_CFA_def_cfa NL \+ .uleb128 reg NL \+ .uleb128 (offset) NL++#define CFA_define_offset(reg, offset) \+ .byte (DW_CFA_offset + reg) NL \+ .uleb128 (offset) NL++#define CFA_restore(reg) \+ .byte (DW_CFA_restore + reg) NL++#define CFI_postamble() \+ .align DATA_ALIGN_FACTOR NL \+7: NL \+.previous NL++/*+ * So now your code pushs stuff on the stack, you need a new location+ * and the rules for what to do. This starts a running description of+ * the call frame. You need to describe what changes with respect to+ * the call registers as the location of the pc moves through the code.+ * The following builds an FDE (fram descriptor entry?). Like the+ * above, it has a preamble and a postamble. It also is tied to the CFI+ * above.+ * The preamble macro is tied to the CFI thru the first parameter. The+ * second is the code start address and then the code end address+1.+ */+#define FDE_preamble(ORD, initial_address, end_address) \+ DWARF_preamble NL \+ .align DATA_ALIGN_FACTOR NL \+ .long 9f-8f NL \+8: \+ .long CAT3(frame,_,ORD) NL \+ ADDR_LOC initial_address NL \+ ADDR_LOC (end_address - initial_address) NL++#define FDE_postamble() \+ .align DATA_ALIGN_FACTOR NL \+9: NL \+.previous NL++/*+ * That done, you can now add registers, subtract registers, move the+ * reference and even change the reference. You can also define a new+ * area of code the info applies to. For discontinuous bits you should+ * start a new FDE. You may have as many as you like.+ */++/*+ * To advance the stack address by <bytes> (0x3f max)+ */++#define CFA_advance_loc(bytes) \+ .byte DW_CFA_advance_loc+bytes NL++/*+ * This one is good for 0xff or 255+ */+#define CFA_advance_loc1(bytes) \+ .byte DW_CFA_advance_loc1 NL \+ .byte bytes NL++#define CFA_undefine_reg(reg) \+ .byte DW_CFA_undefined NL \+ .uleb128 reg NL+/*+ * With the above you can define all the register locations. But+ * suppose the reference register moves... Takes the new offset NOT an+ * increment. This is how esp is tracked if it is not saved.+ */++#define CFA_define_cfa_offset(offset) \+ .byte DW_CFA_def_cfa_offset NL \+ .uleb128 (offset) NL+/*+ * Or suppose you want to use a different reference register...+ */+#define CFA_define_cfa_register(reg) \+ .byte DW_CFA_def_cfa_register NL \+ .uleb128 reg NL++/*+ * If you want to mess with the stack pointer, here is the expression.+ * The stack starts empty.+ */+#define CFA_def_cfa_expression \+ .byte DW_CFA_def_cfa_expression NL \+ .uleb128 20f-10f NL \+10: NL+/*+ * This expression is to be used for other regs. The stack starts with the+ * stack address.+ */++#define CFA_expression(reg) \+ .byte DW_CFA_expression NL \+ .uleb128 reg NL \+ .uleb128 20f-10f NL \+10: NL+/*+ * Here we do the expression stuff. You should code the above followed+ * by expression OPs followed by CFA_expression_end.+ */+++#define CFA_expression_end \+20: NL++#define CFA_exp_OP_const4s(a) \+ .byte DW_OP_const4s NL \+ .long a NL++#define CFA_exp_OP_swap .byte DW_OP_swap NL+#define CFA_exp_OP_dup .byte DW_OP_dup NL+#define CFA_exp_OP_drop .byte DW_OP_drop NL+/*+ * All these work on the top two elements on the stack, replacing them+ * with the result. Top comes first where it matters. True is 1, false 0.+ */+#define CFA_exp_OP_deref .byte DW_OP_deref NL+#define CFA_exp_OP_and .byte DW_OP_and NL+#define CFA_exp_OP_div .byte DW_OP_div NL+#define CFA_exp_OP_minus .byte DW_OP_minus NL+#define CFA_exp_OP_mod .byte DW_OP_mod NL+#define CFA_exp_OP_neg .byte DW_OP_neg NL+#define CFA_exp_OP_plus .byte DW_OP_plus NL+#define CFA_exp_OP_not .byte DW_OP_not NL+#define CFA_exp_OP_or .byte DW_OP_or NL+#define CFA_exp_OP_xor .byte DW_OP_xor NL+#define CFA_exp_OP_le .byte DW_OP_le NL+#define CFA_exp_OP_ge .byte DW_OP_ge NL+#define CFA_exp_OP_eq .byte DW_OP_eq NL+#define CFA_exp_OP_lt .byte DW_OP_lt NL+#define CFA_exp_OP_gt .byte DW_OP_gt NL+#define CFA_exp_OP_ne .byte DW_OP_ne NL+/*+ * These take a parameter as noted+ */+/*+ * Unconditional skip to loc. loc is a label (loc:)+ */+#define CFA_exp_OP_skip(loc) \+ .byte DW_OP_skip NL \+ .hword loc-.-2 NL+/*+ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)+ */+#define CFA_exp_OP_bra(loc) \+ .byte DW_OP_bra NL \+ .hword loc-.-2 NL++/*+ * TOS += no (an unsigned number)+ */+#define CFA_exp_OP_plus_uconst(no) \+ .byte DW_OP_plus_uconst NL \+ .uleb128 no NL++/*+ * ++TOS = no (a unsigned number)+ */+#define CFA_exp_OP_constu(no) \+ .byte DW_OP_constu NL \+ .uleb128 no NL+/*+ * ++TOS = no (a signed number)+ */+#define CFA_exp_OP_consts(no) \+ .byte DW_OP_consts NL \+ .sleb128 no NL+/*+ * ++TOS = no (an unsigned byte)+ */+#define CFA_exp_OP_const1u(no) \+ .byte DW_OP_const1u NL \+ .byte no NL+++/*+ * ++TOS = no (a address)+ */+#define CFA_exp_OP_addr(no) \+ .byte DW_OP_addr NL \+ .long no NL++/*+ * Push current frames value for "reg" + offset+ * We take advantage of the opcode assignments to make this a litteral reg+ * rather than use the DW_OP_bregx opcode.+ */++#define CFA_exp_OP_breg(reg,offset) \+ .byte DW_OP_breg0+reg NL \+ .sleb128 offset NL+#endifIndex: linux-2.6.16/include/asm-arm/kgdb.h===================================================================--- linux-2.6.16.orig/include/asm-arm/kgdb.h 2006-04-25 11:40:09.000000000 +0530+++ linux-2.6.16/include/asm-arm/kgdb.h 2006-04-25 11:42:37.000000000 +0530@@ -14,6 +14,7 @@ #include <linux/config.h> #include <asm/ptrace.h>+#include <asm-generic/kgdb.h> /*@@ -48,6 +49,7 @@ extern void kgdb_handle_bus_error(void); extern int kgdb_fault_expected;+#endif /* !__ASSEMBLY__ */ /* * From Amit S. Kale:@@ -83,5 +85,8 @@ #define _PC 15 #define _CPSR (GDB_MAX_REGS - 1) -#endif /* !__ASSEMBLY__ */+/* So that we can denote the end of a frame for tracing, in the simple+ * case. */+#define CFI_END_FRAME(func) __CFI_END_FRAME(_PC,_SP,func)+ #endif /* __ASM_KGDB_H__ */Index: linux-2.6.16/include/asm-i386/kgdb.h===================================================================--- linux-2.6.16.orig/include/asm-i386/kgdb.h 2006-04-25 11:30:47.000000000 +0530+++ linux-2.6.16/include/asm-i386/kgdb.h 2006-04-25 11:42:37.000000000 +0530@@ -6,6 +6,39 @@ * Copyright (C) 2001-2004 Amit S. Kale */ +#include <asm-generic/kgdb.h>++/*+ * Note that this register image is in a different order than+ * the register image that Linux produces at interrupt time.+ *+ * Linux's register image is defined by struct pt_regs in ptrace.h.+ * Just why GDB uses a different order is a historical mystery.+ */+#define _EAX 0+#define _ECX 1+#define _EDX 2+#define _EBX 3+#define _ESP 4+#define _EBP 5+#define _ESI 6+#define _EDI 7+#define _PC 8+#define _EIP 8+#define _PS 9+#define _EFLAGS 9+#define _CS 10+#define _SS 11+#define _DS 12+#define _ES 13+#define _FS 14+#define _GS 15++/* So that we can denote the end of a frame for tracing, in the simple+ * case. */+#define CFI_END_FRAME(func) __CFI_END_FRAME(_EIP,_ESP,func)++#ifndef __ASSEMBLY__ /************************************************************************/ /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ /* at least NUMREGBYTES*2 are needed for register packets */@@ -17,33 +50,9 @@ /* Number of bytes of registers we need to save for a setjmp/longjmp. */ #define NUMCRITREGBYTES 24 -/*- * Note that this register image is in a different order than- * the register image that Linux produces at interrupt time.- *- * Linux's register image is defined by struct pt_regs in ptrace.h.- * Just why GDB uses a different order is a historical mystery.- */-enum regnames { _EAX, /* 0 */- _ECX, /* 1 */- _EDX, /* 2 */- _EBX, /* 3 */- _ESP, /* 4 */- _EBP, /* 5 */- _ESI, /* 6 */- _EDI, /* 7 */- _PC, /* 8 also known as eip */- _PS, /* 9 also known as eflags */- _CS, /* 10 */- _SS, /* 11 */- _DS, /* 12 */- _ES, /* 13 */- _FS, /* 14 */- _GS /* 15 */-};- #define BREAKPOINT() asm(" int $3"); #define BREAK_INSTR_SIZE 1 #define CACHE_FLUSH_IS_SAFE 1+#endif /* !__ASSEMBLY__ */ #endif /* _ASM_KGDB_H_ */ #endif /* __KERNEL__ */Index: linux-2.6.16/include/asm-sh/kgdb.h===================================================================--- linux-2.6.16.orig/include/asm-sh/kgdb.h 2006-04-25 11:34:01.000000000 +0530+++ linux-2.6.16/include/asm-sh/kgdb.h 2006-04-25 11:42:37.000000000 +0530@@ -14,6 +14,7 @@ #ifndef __KGDB_H #define __KGDB_H +#include <asm-generic/kgdb.h> /* Based on sh-gdb.c from gdb-6.1, Glenn Engel at HP Ben Lee and Steve Chamberlain */ #define NUMREGBYTES 112 /* 92 */Index: linux-2.6.16/scripts/dwarfh.awk===================================================================--- linux-2.6.16.orig/scripts/dwarfh.awk 2006-04-25 10:59:23.506518750 +0530+++ linux-2.6.16/scripts/dwarfh.awk 2006-04-25 11:42:37.000000000 +0530@@ -0,0 +1,19 @@+BEGIN {+ print "#ifndef _ELF_DWARF_H"+ print "/* Machine generated from dwarf2.h by scripts/dwarfh.awk */"+}+$2 == "=" {+ gsub(/,/, "", $3)+ print "#define " $1 "\t " $3+}+$1 == "#define" {+ print $0+ while( index($0,"\\") == length($0)){+ getline+ print $0+ }+}+/.*/ {}+END {+ print "#endif"+}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -