sewardj | 669281e | 2007-02-28 13:27:37 +0000 | [diff] [blame] | 1 | |
| 2 | /* This is really horrible. It checks that the |
| 3 | stack unwinder understands DW_CFA_def_cfa_expression. It is |
| 4 | the result of compiling this: |
| 5 | |
| 6 | void bbb ( long x ) |
| 7 | { |
| 8 | __asm__ __volatile__( |
| 9 | "cmp %0,%0\n\t" |
| 10 | "jz .Lxyzzy\n" |
| 11 | ".Lxyzzy:\n\t" |
| 12 | : : "r"(x) : "cc" |
| 13 | ); |
| 14 | } |
| 15 | |
| 16 | void aaa ( long x ) { |
| 17 | bbb(x); |
| 18 | } |
| 19 | |
| 20 | int main ( void ) |
| 21 | { |
| 22 | long *p = malloc(8); |
| 23 | aaa( *p ); |
| 24 | return 0; |
| 25 | } |
| 26 | |
| 27 | and bracketing the cmp/jz insns with a move down/up by 256 of %rsp. |
| 28 | The .jz causes memcheck to complain, hence unwind the stack, but |
| 29 | that cannot be successfully done unless the return address can |
| 30 | be found. Hence the handwritten CFI below uses |
| 31 | DW_CFA_def_cfa_expression to make that possible. |
| 32 | |
| 33 | The CFI below isn't really right in that aaa appears twice |
| 34 | in the backtrace |
| 35 | |
| 36 | ==12868== Conditional jump or move depends on uninitialised value(s) |
| 37 | ==12868== at 0x400512: bbb (in /home/sewardj/VgTRUNK/trunk/mad0) |
| 38 | ==12868== by 0x400520: aaa (in /home/sewardj/VgTRUNK/trunk/mad0) |
| 39 | ==12868== by 0x400520: aaa (in /home/sewardj/VgTRUNK/trunk/mad0) |
| 40 | ==12868== by 0x400538: main (in /home/sewardj/VgTRUNK/trunk/mad0) |
| 41 | |
| 42 | but GDB behaves the same, so I'm not too concerned - indicates |
| 43 | the problem is with the handwritten CFI and not with |
| 44 | V's interpretation of it. |
| 45 | */ |
| 46 | |
| 47 | |
| 48 | .file "bad0.c" |
| 49 | .text |
| 50 | |
| 51 | |
| 52 | .globl bbb |
| 53 | .type bbb, @function |
| 54 | bbb: |
| 55 | .LFB2: |
| 56 | .Lbbb1: |
| 57 | subq $256,%rsp |
| 58 | .Lbbb2: |
| 59 | cmp %rdi,%rdi |
| 60 | jz .Lxyzzy |
| 61 | .Lxyzzy: |
| 62 | addq $256,%rsp |
| 63 | .Lbbb3: |
| 64 | ret |
| 65 | .Lbbb4: |
| 66 | .LFE2: |
| 67 | .size bbb, .-bbb |
| 68 | |
| 69 | |
| 70 | |
| 71 | .globl aaa |
| 72 | .type aaa, @function |
| 73 | aaa: |
| 74 | .LFB3: |
| 75 | call bbb |
| 76 | rep ; ret |
| 77 | .LFE3: |
| 78 | .size aaa, .-aaa |
| 79 | .globl main |
| 80 | .type main, @function |
| 81 | main: |
| 82 | .LFB4: |
| 83 | subq $8, %rsp |
| 84 | .LCFI0: |
| 85 | movl $8, %edi |
| 86 | call malloc |
| 87 | movq (%rax), %rdi |
| 88 | call aaa |
| 89 | movl $0, %eax |
| 90 | addq $8, %rsp |
| 91 | ret |
| 92 | .LFE4: |
| 93 | .size main, .-main |
| 94 | .section .eh_frame,"a",@progbits |
| 95 | .Lframe1: |
| 96 | .long .LECIE1-.LSCIE1 |
| 97 | .LSCIE1: |
| 98 | .long 0x0 |
| 99 | .byte 0x1 |
| 100 | .string "zR" |
| 101 | .uleb128 0x1 |
| 102 | .sleb128 -8 |
| 103 | .byte 0x10 |
| 104 | .uleb128 0x1 |
| 105 | .byte 0x3 |
| 106 | .byte 0xc |
| 107 | .uleb128 0x7 |
| 108 | .uleb128 0x8 |
| 109 | .byte 0x90 |
| 110 | .uleb128 0x1 |
| 111 | .align 8 |
| 112 | .LECIE1: |
| 113 | |
| 114 | /* start of the FDE for bbb */ |
| 115 | .LSFDE1: |
| 116 | .long .LEFDE1-.LASFDE1 /* length of FDE */ |
| 117 | .LASFDE1: |
| 118 | .long .LASFDE1-.Lframe1 /* CIE pointer */ |
| 119 | .long .LFB2 /* & bbb */ |
| 120 | .long .LFE2-.LFB2 /* sizeof(bbb) */ |
| 121 | .uleb128 0 /* augmentation length */ |
| 122 | .byte 0x40 + .Lbbb2 - .Lbbb1 /* _advance_loc to .Lbbb2 */ |
| 123 | |
| 124 | /* For the section in between .Lbbb2 and .Lbbb3, set the |
| 125 | CFA to be %rsp+256, and set the return address (dwarf r16) |
| 126 | to be *(CFA+0). */ |
| 127 | .byte 0x0f /* _def_cfa_expression */ |
| 128 | .uleb128 .Lexpr1e-.Lexpr1s /* length of expression */ |
| 129 | .Lexpr1s: |
| 130 | .byte 0x77 /* DW_OP_breg7 == %rsp + sleb128(0) */ |
| 131 | .sleb128 0 |
| 132 | .byte 0x40 /* DW_OP_lit16 */ |
| 133 | .byte 0x40 /* DW_OP_lit16 */ |
| 134 | .byte 0x1e /* DW_OP_mul */ |
| 135 | .byte 0x22 /* DW_OP_plus */ |
| 136 | .Lexpr1e: |
| 137 | .byte 0x90 /* _cfa_offset: r16 = *(cfa+0) */ |
| 138 | .uleb128 0 |
| 139 | |
| 140 | .byte 0x40 + .Lbbb3 - .Lbbb2 /* _advance_loc to .Lbbb3 */ |
| 141 | |
| 142 | /* For the section .Lbbb3 to .Lbbb4, should set CFA back to |
| 143 | something sensible. This tries to do it but still causes |
| 144 | GDB to show an extraneous aaa frame on the stack. Oh well. */ |
| 145 | /* Now set CFA back to %rsp+0 */ |
| 146 | .byte 0x0f /* _def_cfa_expression */ |
| 147 | .uleb128 .Lexpr2e-.Lexpr2s /* length of expression */ |
| 148 | .Lexpr2s: |
| 149 | .byte 0x77 /* DW_OP_breg7 == %rsp + sleb128(0) */ |
| 150 | .sleb128 0 |
| 151 | .byte 0x30 /* DW_OP_lit0 */ |
| 152 | .byte 0x1c /* DW_OP_minus */ |
| 153 | .Lexpr2e: |
| 154 | .byte 0x90 /* _cfa_offset: r16 = *(cfa+0) */ |
| 155 | .uleb128 0 |
| 156 | |
| 157 | .byte 0x40 + .Lbbb4 - .Lbbb3 /* _advance_loc to .Lbbb4 */ |
| 158 | .uleb128 0x0 /* ??? */ |
| 159 | .align 8 |
| 160 | .LEFDE1: |
| 161 | /* end of the FDE for bbb */ |
| 162 | |
| 163 | .LSFDE3: |
| 164 | .long .LEFDE3-.LASFDE3 |
| 165 | .LASFDE3: |
| 166 | .long .LASFDE3-.Lframe1 |
| 167 | .long .LFB3 |
| 168 | .long .LFE3-.LFB3 |
| 169 | .uleb128 0x0 |
| 170 | .align 8 |
| 171 | .LEFDE3: |
| 172 | .LSFDE5: |
| 173 | .long .LEFDE5-.LASFDE5 |
| 174 | .LASFDE5: |
| 175 | .long .LASFDE5-.Lframe1 |
| 176 | .long .LFB4 |
| 177 | .long .LFE4-.LFB4 |
| 178 | .uleb128 0x0 |
| 179 | .byte 0x4 |
| 180 | .long .LCFI0-.LFB4 |
| 181 | .byte 0xe |
| 182 | .uleb128 0x10 |
| 183 | .align 8 |
| 184 | .LEFDE5: |
| 185 | .ident "GCC: (GNU) 4.1.2 20061115 (prerelease) (SUSE Linux)" |
| 186 | .section .note.GNU-stack,"",@progbits |