This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: error reading variable: value has been optimized out


On 12/09/2012 6:29 PM, Tom Tromey wrote:
>>>>>> "Andrew" == Andrew Burgess <aburgess@broadcom.com> writes:
> 
> Andrew> (3) Structures the size of two registers split over two
> Andrew> registers using dwarf piece information.
> 
> Andrew> (4) Values the size of a single register split over two
> Andrew> registers using dwarf piece information to describe the
> Andrew> location.
> 
> Andrew> Cases (3) and (4) are not fixed by my original patch, and fail
> Andrew> for a different reason.  I could remove these from the test, but
> Andrew> I believe the tests are reasonable, or at least not totally
> Andrew> crazy, so I'm reluctant to just delete them.  I could just
> Andrew> commit the test with these two examples marked as known failing
> Andrew> .... or I could fix them :)
> 
> Andrew> The problem is this,
> 
> Andrew>   - In dwarf2loc.c:dwarf_evaluate_loc_desc_full we create the
> Andrew>   computed value from the pieced location information.
> 
> Andrew>   - In dwarf2loc.c:read_pieced_value we spot that some of the
> Andrew>   registers are missing and mark the computed value as optimized
> Andrew>   out.
> 
> This scenario seems odd to me.  I think what it means is that the
> compiler declares an object as being split between two registers -- but
> then also knows that one of the registers is not in fact available.
> 
> Does any compiler actually do this?

I have never seen such debug, I was just thinking up similar cases to the original test #1, that I have seen.  I agree that in all these cases, if they did occur, it would be incorrect (though not invalid) debug information.

> If it is just a theoretical problem I think we can just declare it
> unsupported; and, if we do see it, try reporting it as a compiler bug
> first.  After all, the compiler could just emit an empty piece instead.

I'm happy to mark these tests as unsupported.  As the tests (#2 -> #4) are pretty much zero cost given that I'm adding test #1 anyway I'd like to leave them in.  I've created a new patch, the only change is that test #3 and #4 now report unsupported (with comment), and test #2 reports pass, with a comment to explain the reasoning.

Full patch below, would everyone be happy with this?

Thanks,

Andrew

gdb/ChangeLog

2012-08-24  Andrew Burgess  <aburgess@broadcom.com>

	* findvar.c (read_frame_register_value): Mark the result value as
	optimized out if any of the input registers have been optimized out.

diff --git a/gdb/findvar.c b/gdb/findvar.c
index 66bcebe..ec9dde7 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -677,7 +677,10 @@ default_value_from_register (struct type *type, int regnum,
 /* VALUE must be an lval_register value.  If regnum is the value's
    associated register number, and len the length of the values type,
    read one or more registers in FRAME, starting with register REGNUM,
-   until we've read LEN bytes.  */
+   until we've read LEN bytes.
+
+   If any of the registers we try to read are optimized out, then mark the
+   complete resulting value as optimized out.  */
 
 void
 read_frame_register_value (struct value *value, struct frame_info *frame)
@@ -703,6 +706,12 @@ read_frame_register_value (struct value *value, struct frame_info *frame)
       struct value *regval = get_frame_register_value (frame, regnum);
       int reg_len = TYPE_LENGTH (value_type (regval)) - reg_offset;
 
+      if (value_optimized_out (regval))
+	{
+	  set_value_optimized_out (value, 1);
+	  break;
+	}
+
       /* If the register length is larger than the number of bytes
          remaining to copy, then only copy the appropriate bytes.  */
       if (reg_len > len)


gdb/testsuite/ChangeLog

2012-08-31  Andrew Burgess  <aburgess@broadcom.com>

	* gdb.dwarf2/dw2-op-out-param.S: New file.
	* gdb.dwarf2/dw2-op-out-param.exp: New file.

diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.S b/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.S
new file mode 100644
index 0000000..48fa136
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.S
@@ -0,0 +1,678 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */        
+
+
+/* Test the behaviour of gdb in the following situation, the dwarf debug
+   information describes a parameter as being in a register but a more
+   recent (inner) frame marks the register as being undefined.
+
+   This can arrise if the dwarf producer has the location of a parameter in
+   a callee clobbered register at the time of a call.  Older versions of
+   gcc used to do this, newer versions seem to avoid this issue.
+
+   Though it could be argued that such dwarf is incorrect, we would still
+   like gdb to behave in a user friendly, and helpful way when presented
+   with such dwarf.  */
+
+/* There are 4 test cases in this assembler file.  In each case funcion
+   main calls each test function in turn, each test case then calls the
+   breakpt function.
+
+   We don't actually pass any parameters around, we don't need to, instead
+   the dwarf for each test function declares that the function has some
+   parameters, and tells us which registers these parameters are in.  The
+   breakpt function marks some of these registers as undefined.  The main
+   function helpfully places some marker values into all the registers that
+   are used as parameters so we can see if they ever get printed.
+
+   We use gdb to break in the breakpt function for each of the 4 test
+   cases, and then backtrace through the test function back to main.  In
+   each case some or all of the parameters to the test function should be
+   marked as optimized out, due to the breakpt function effectively
+   clobbering them.
+
+   The dwarf register numbering is different to the gdb register number.
+   In some of the tests we rely on gdb behaviour of being able to specify a
+   struct using a single register location, the structure will then "flow"
+   into the next gdb register.  The initial register is specified using a
+   dwarf register number, but the "next" register will depend on gdb
+   register ordering.
+
+   Exposing this internal gdb register numbering is really a gdb bug, the
+   functionality for selecting the "next" register should be moved into
+   target dependent code (such as AVR).  Right now we work around this
+   bug in this test; if the bug is ever fixed this test is going to need
+   some tweaking.
+
+   The breakpt function always marks rcx, rsi, and rdi as undefined.
+
+      register | dwarf | gdb   |         |
+      name     | reg # | reg # | breakpt |
+     ----------|-------|-------|---------|
+        rdx    | 1     | 3     |         |
+        rcx    | 2     | 2     | undef   |
+        rbx    | 3     | 1     |         |
+        rsi    | 4     | 4     | undef   |
+        rdi    | 5     | 5     | undef   |
+
+   We declare the test parameters to be in the register rdx, rcx, rbx, rsi,
+   and rdi.  Of these, rdx and rbx are not traditionally used for parameter
+   passing, but that really doesn't matter for this test.
+   
+   int_param_single_reg_loc: Passes 8-byte integer parameters in 8-byte
+                             registers using DW_OP_regn style location
+                             information.  The parameters are placed as
+                             follows, operand0 (rcx), operand1 (rbx),
+                             operand2 (rsi).  We expect operand0 and
+                             operand2 to be marked as optimised out, but
+                             operand1 to be valid.
+
+   struct_param_single_reg_loc: Passes 16-byte structures in two 8-byte
+                                registers using dwarf DW_OP_regn location
+                                information to describe a single register,
+                                gdb will assume that the structure flows
+                                into the next sequential register.  The
+                                parameters are placed as follows, operand0
+                                (rbx/rcx), operand1 (rcx/rdx), and operand2
+                                (rsi/rdi).  The reuse of rcx between
+                                operand0 and operand1 is intentional.
+
+   struct_param_two_reg_pieces: Passes 16-byte structure in two 8-byte
+                                registers using dwarf DW_OP_piece based
+                                location information to describe both
+                                registers.  The parameters are placed as
+                                follows, operand0 (rdx/rcx), operand1
+                                (rcx/rbx), and operand2 (rsi/rdi).  The
+                                reuse of rcx between operand0 and operand1
+                                is intentional.
+
+   int_param_two_reg_pieces: Passes 8-byte integer values in two 8-byte
+                             registers with 4-bytes being placed in each
+                             register, using dwarf DW_OP_piece based
+                             location information to describe how the
+                             parameters are split up.The parameters are
+                             placed as follows, operand0 (rdx/rcx),
+                             operand1 (rcx/rbx), and operand2 (rsi/rdi).
+                             The reuse of rcx between operand0 and operand1
+                             is intentional.
+*/
+
+        .text
+
+.Ltext0:
+        
+        /* main */
+.globl main
+        .type   main, @function
+main:
+.Ltext1:
+        sub    $0x8,%rsp
+.Ltext2:
+        movq    $0xdeadbe00deadbe01, %rbx
+        movq    $0xdeadbe02deadbe03, %rcx
+        movq    $0xdeadbe04deadbe05, %rdx
+        movq    $0xdeadbe06deadbe07, %rsi
+        movq    $0xdeadbe08deadbe09, %rdi
+        
+        callq    int_param_single_reg_loc
+        nop
+
+        callq    struct_param_single_reg_loc
+        nop
+
+        callq    struct_param_two_reg_pieces
+        nop
+
+        callq    int_param_two_reg_pieces
+        nop
+        
+        add    $0x8,%rsp
+        retq
+.Ltext3:
+        .size   main, .-main
+
+        /* breakpt */
+.globl breakpt
+        .type   breakpt, @function
+breakpt:
+.Ltext4:
+        sub    $0x8,%rsp
+        add    $0x8, %rsp
+        retq
+.Ltext5:
+        .size   breakpt, .-breakpt
+        
+        /* int_param_single_reg_loc */
+.globl int_param_single_reg_loc
+        .type   int_param_single_reg_loc, @function
+int_param_single_reg_loc:
+.Ltext5:
+        sub    $0x8,%rsp
+.Ltext6:
+        nop
+        callq    breakpt
+        nop
+        add    $0x8,%rsp
+        retq
+.Ltext7:
+        .size   int_param_single_reg_loc, .-int_param_single_reg_loc
+
+        /* struct_param_single_reg_loc */
+.globl struct_param_single_reg_loc
+        .type   struct_param_single_reg_loc, @function
+struct_param_single_reg_loc:
+.Ltext8:
+        sub    $0x8,%rsp
+.Ltext9:
+        nop
+        callq    breakpt
+        nop
+        add    $0x8,%rsp
+        retq
+.Ltext10:
+        .size   struct_param_single_reg_loc, .-struct_param_single_reg_loc
+
+        /* struct_param_two_reg_pieces */
+.globl struct_param_two_reg_pieces
+        .type   struct_param_two_reg_pieces, @function
+struct_param_two_reg_pieces:
+.Ltext11:
+        sub    $0x8,%rsp
+.Ltext12:
+        nop
+        callq    breakpt
+        nop
+        add    $0x8,%rsp
+        retq
+.Ltext13:
+        .size   struct_param_two_reg_pieces, .-struct_param_two_reg_pieces
+
+        /* int_param_two_reg_pieces */
+.globl int_param_two_reg_pieces
+        .type   int_param_two_reg_pieces, @function
+int_param_two_reg_pieces:
+.Ltext14:
+        sub    $0x8,%rsp
+.Ltext15:
+        nop
+        callq    breakpt
+        nop
+        add    $0x8,%rsp
+        retq
+.Ltext16:
+        .size   int_param_two_reg_pieces, .-int_param_two_reg_pieces
+        
+
+.Letext0:
+
+        /*******************************************************/
+
+        .section	.debug_frame,"",@progbits
+        
+        /* CIE */
+.Lframe0:
+	.long	.LECIE0-.LSCIE0 /* length */
+.LSCIE0:
+	.long	0xffffffff      /* CIE_id */
+	.byte	0x1             /* version */
+	.string	""              /* augmentation */
+	.uleb128 0x1            /* code alignment */
+	.sleb128 -8             /* data alignment */
+	.byte	0x10            /* R/A column */
+        /* Initial instructions */
+	.byte	0xc             /* DW_CFA_def_cfa */
+	.uleb128 0x7            /* reg# */
+	.uleb128 0x8            /* offset */
+	.byte	0x90            /* DW_CFA_offset (r16) */
+	.uleb128 0x1            /* offset */
+	.align 8
+.LECIE0:
+
+        /* FDE : breakpt */
+.LSFDE0:
+	.long	.LEFDE0-.LASFDE0        /* length */
+.LASFDE0:
+	.long	.Lframe0                /* CIE reference */
+	.quad	.Ltext4                 /* start */
+	.quad	.Ltext5-.Ltext4         /* length */
+        /* Instructions */
+        .byte   0x7                     /* DW_CFA_undefined */
+        .uleb128 0x2                    /* reg# */
+        .byte   0x7                     /* DW_CFA_undefined */
+        .uleb128 0x4                    /* reg# */
+        .byte   0x7                     /* DW_CFA_undefined */
+        .uleb128 0x5                    /* reg# */
+	.align 8
+.LEFDE0:
+
+        /* FDE : int_param_single_reg_loc */
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2        /* length */
+.LASFDE2:
+	.long	.Lframe0                /* CIE reference */
+	.quad	.Ltext5                 /* start */
+	.quad	.Ltext7-.Ltext5         /* length */
+        /* Instructions */
+ 	.byte	0x4
+	.long	.Ltext6-.Ltext5
+	.byte	0xe
+	.uleb128 0x10
+	.align 8
+.LEFDE2:
+
+        /* FDE : struct_param_single_reg_loc */
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3        /* length */
+.LASFDE3:
+	.long	.Lframe0                /* CIE reference */
+	.quad	.Ltext8                 /* start */
+	.quad	.Ltext10-.Ltext8        /* length */
+        /* Instructions */
+ 	.byte	0x4
+	.long	.Ltext9-.Ltext8
+	.byte	0xe
+	.uleb128 0x10
+	.align 8
+.LEFDE3:
+
+        /* FDE : struct_param_two_reg_pieces */
+.LSFDE4:
+	.long	.LEFDE4-.LASFDE4        /* length */
+.LASFDE4:
+	.long	.Lframe0                /* CIE reference */
+	.quad	.Ltext11                /* start */
+	.quad	.Ltext13-.Ltext11       /* length */
+        /* Instructions */
+ 	.byte	0x4
+	.long	.Ltext12-.Ltext11
+	.byte	0xe
+	.uleb128 0x10
+	.align 8
+.LEFDE4:
+
+        /* FDE : int_param_two_reg_pieces */
+.LSFDE5:
+	.long	.LEFDE5-.LASFDE5        /* length */
+.LASFDE5:
+	.long	.Lframe0                /* CIE reference */
+	.quad	.Ltext14                /* start */
+	.quad	.Ltext16-.Ltext14       /* length */
+        /* Instructions */
+ 	.byte	0x4
+	.long	.Ltext15-.Ltext14
+	.byte	0xe
+	.uleb128 0x10
+	.align 8
+.LEFDE5:
+
+        /* FDE : main */
+.LSFDE9:
+	.long	.LEFDE9-.LASFDE9        /* length */
+.LASFDE9:
+	.long	.Lframe0                /* CIE reference */
+	.quad	.Ltext1                 /* start */
+	.quad	.Ltext3-.Ltext1         /* length */
+        /* Instructions */
+ 	.byte	0x4
+	.long	.Ltext2-.Ltext1
+	.byte	0xe
+	.uleb128 0x10
+	.align 8
+.LEFDE9:
+
+        /*******************************************************/        
+        
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+        .long  .Ldebug_info_end - .Ldebug_info_start   /* Length */
+.Ldebug_info_start:
+	.value	0x2                     /* DWARF version number. */
+	.long	.Ldebug_abbrev0         /* Offset into .debug_abbrev */
+	.byte	0x8                     /* Pointer size */
+
+.LDI0:        
+	.uleb128 0x1                    /* DW_TAG_compile_unit */
+	.string	"GNU C 4.2.1"           /* DW_AT_producer */
+	.byte	0x1                     /* DW_AT_language */
+	.quad	.Ltext0                 /* DW_AT_low_pc */
+	.quad	.Letext0                /* DW_AT_high_pc */
+
+.LDI1:
+	.uleb128 0x2                    /* DW_TAG_subprogram */
+	.byte	0x1                     /* DW_AT_external */
+	.string	"breakpt"               /* DW_AT_name */
+	.byte	0x1                     /* DW_AT_prototyped */
+	.quad	.Ltext4                 /* DW_AT_low_pc */
+	.quad	.Ltext5                 /* DW_AT_high_pc */        
+
+.LDI2:
+	.uleb128 0x5                    /* DW_TAG_base_type */
+	.byte	0x8                     /* DW_AT_byte_size */
+	.byte	0x5                     /* DW_AT_encoding (DW_ATE_signed) */
+	.string	"long int"              /* DW_AT_name */
+
+.LDI3:
+        .uleb128 0x7                    /* DW_TAG_structure_type */
+        .string "big"                   /* DW_AT_name */
+        .byte   0x10                    /* DW_AT_byte_size */
+        .long   .LDI6                   /* DW_AT_sibling */
+        
+.LDI4:
+        .uleb128 0x8                    /* DW_TAG_member */
+        .string "a"                     /* DW_AT_name */
+        .long   .LDI2                   /* DW_AT_type */
+        .byte   0x2                     /* DW_AT_data_member_location : length */
+        .byte   0x23                    /* DW_OP_plus_uconst */
+        .uleb128 0x0                    /*   + 0 */
+        
+.LDI5:
+        .uleb128 0x8                    /* DW_TAG_structure_type */
+        .string "b"                     /* DW_AT_name */
+        .long   .LDI2                   /* DW_AT_type */
+        .byte   0x2                     /* DW_AT_data_member_location : length */
+        .byte   0x23                    /* DW_OP_plus_uconst */
+        .uleb128 0x8                    /*   + 8 */
+        .byte   0x0
+
+.LDI6:
+	.uleb128 0x6                    /* DW_TAG_subprogram */
+	.byte	0x1                     /* DW_AT_external */
+	.string	"main"                  /* DW_AT_name */
+	.long	.LDI2                   /* DW_AT_type */
+	.quad	.Ltext1                 /* DW_AT_low_pc */
+	.quad	.Ltext3                 /* DW_AT_high_pc */
+
+.LDI7:
+	.uleb128 0x3                    /* DW_TAG_subprogram */
+	.byte	0x1                     /* DW_AT_external */
+	.string	"int_param_single_reg_loc"                 /* DW_AT_name */
+	.byte	0x1                     /* DW_AT_prototyped */
+	.quad	.Ltext5                 /* DW_AT_low_pc */
+	.quad	.Ltext7                 /* DW_AT_high_pc */
+	.long	.LDI11                  /* DW_AT_sibling */        
+        
+.LDI8:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand0"              /* DW_AT_name */
+	.long	.LDI2                   /* DW_AT_type */
+	.byte	1                       /* DW_AT_location : length */
+	.byte	0x52                    /* DW_OP_reg2 */
+
+.LDI9:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand1"              /* DW_AT_name */
+	.long	.LDI2                   /* DW_AT_type */
+	.byte	1                       /* DW_AT_location : length */
+	.byte	0x53                    /* DW_OP_reg3 */        
+        
+.LDI10:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand2"              /* DW_AT_name */
+	.long	.LDI2                   /* DW_AT_type */
+	.byte	1                       /* DW_AT_location : length */
+	.byte	0x54                    /* DW_OP_reg4 */
+        
+	.byte	0x0        
+
+.LDI11:
+	.uleb128 0x3                    /* DW_TAG_subprogram */
+	.byte	0x1                     /* DW_AT_external */
+	.string	"struct_param_single_reg_loc"                 /* DW_AT_name */
+	.byte	0x1                     /* DW_AT_prototyped */
+	.quad	.Ltext8                 /* DW_AT_low_pc */
+	.quad	.Ltext10                /* DW_AT_high_pc */
+	.long	.LDI15                   /* DW_AT_sibling */        
+        
+.LDI12:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand0"              /* DW_AT_name */
+	.long	.LDI3                   /* DW_AT_type */
+	.byte	1                       /* DW_AT_location : length */
+	.byte	0x53                    /* DW_OP_reg3 */
+
+.LDI13:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand1"              /* DW_AT_name */
+	.long	.LDI3                   /* DW_AT_type */
+	.byte	1                       /* DW_AT_location : length */
+	.byte	0x52                    /* DW_OP_reg2 */        
+        
+.LDI14:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand2"              /* DW_AT_name */
+	.long	.LDI3                   /* DW_AT_type */
+	.byte	1                       /* DW_AT_location : length */
+	.byte	0x54                    /* DW_OP_reg4 */
+        
+	.byte	0x0
+
+.LDI15:
+	.uleb128 0x3                    /* DW_TAG_subprogram */
+	.byte	0x1                     /* DW_AT_external */
+	.string	"struct_param_two_reg_pieces"                 /* DW_AT_name */
+	.byte	0x1                     /* DW_AT_prototyped */
+	.quad	.Ltext11                /* DW_AT_low_pc */
+	.quad	.Ltext13                /* DW_AT_high_pc */
+	.long	.LDI19                  /* DW_AT_sibling */        
+        
+.LDI16:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand0"              /* DW_AT_name */
+	.long	.LDI3                   /* DW_AT_type */
+	.byte	6                       /* DW_AT_location : length */
+	.byte	0x51                    /* DW_OP_reg1 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x8                    /*    8 bytes */
+	.byte	0x52                    /* DW_OP_reg2 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x8                    /*    8 bytes */
+
+.LDI17:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand1"              /* DW_AT_name */
+	.long	.LDI3                   /* DW_AT_type */
+	.byte	6                       /* DW_AT_location : length */
+	.byte	0x52                    /* DW_OP_reg2 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x8                    /*    8 bytes */
+	.byte	0x53                    /* DW_OP_reg3 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x8                    /*    8 bytes */
+        
+.LDI18:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand2"              /* DW_AT_name */
+	.long	.LDI3                   /* DW_AT_type */
+	.byte	6                       /* DW_AT_location : length */
+	.byte	0x54                    /* DW_OP_reg4 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x8                    /*    8 bytes */
+	.byte	0x55                    /* DW_OP_reg5 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x8                    /*    8 bytes */
+        
+	.byte	0x0
+
+.LDI19:
+	.uleb128 0x3                    /* DW_TAG_subprogram */
+	.byte	0x1                     /* DW_AT_external */
+	.string	"int_param_two_reg_pieces"                 /* DW_AT_name */
+	.byte	0x1                     /* DW_AT_prototyped */
+	.quad	.Ltext14                /* DW_AT_low_pc */
+	.quad	.Ltext16                /* DW_AT_high_pc */
+	.long	.LDIE0                  /* DW_AT_sibling */        
+        
+.LDI20:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand0"              /* DW_AT_name */
+	.long	.LDI2                   /* DW_AT_type */
+	.byte	6                       /* DW_AT_location : length */
+	.byte	0x51                    /* DW_OP_reg1 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x4                    /*    4 bytes */
+	.byte	0x52                    /* DW_OP_reg2 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x4                    /*    4 bytes */
+
+.LDI21:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand1"              /* DW_AT_name */
+	.long	.LDI2                   /* DW_AT_type */
+	.byte	6                       /* DW_AT_location : length */
+	.byte	0x52                    /* DW_OP_reg2 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x4                    /*    4 bytes */
+	.byte	0x53                    /* DW_OP_reg3 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x4                    /*    4 bytes */
+        
+.LDI22:
+	.uleb128 0x4                    /* DW_TAG_formal_parameter */
+	.string	"operand2"              /* DW_AT_name */
+	.long	.LDI2                   /* DW_AT_type */
+	.byte	6                       /* DW_AT_location : length */
+	.byte	0x54                    /* DW_OP_reg4 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x4                    /*    4 bytes */
+	.byte	0x55                    /* DW_OP_reg5 */
+        .byte   0x93                    /* DW_OP_piece */
+        .uleb128 0x4                    /*    4 bytes */
+        
+	.byte	0x0
+        
+.LDIE0:
+	.byte	0x0
+.Ldebug_info_end:
+
+        /*******************************************************/        
+        
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1    /* abbrev code */
+	.uleb128 0x11   /* TAG: DW_TAG_compile_unit */
+	.byte	0x1     /* DW_CHILDREN_yes */
+	.uleb128 0x25   /* DW_AT_producer */
+	.uleb128 0x8    /*   DW_FORM_string */
+	.uleb128 0x13   /* DW_AT_language */
+	.uleb128 0xb    /*   DW_FORM_data1 */
+        .uleb128 0x11   /* DW_AT_low_pc */
+        .uleb128 0x1    /*   DW_FORM_addr */
+        .uleb128 0x12   /* DW_AT_high_pc */
+        .uleb128 0x1    /*   DW_FORM_addr */
+	.byte	0x0
+	.byte	0x0
+        
+	.uleb128 0x2    /* abbrev code */
+	.uleb128 0x2e   /* TAG: DW_TAG_subprogram */
+	.byte	0x0     /* DW_CHILDREN_no */
+	.uleb128 0x3f   /* DW_AT_external */
+	.uleb128 0xc    /*   DW_FORM_flag */
+	.uleb128 0x3    /* DW_AT_name */
+	.uleb128 0x8    /*   DW_FORM_string */
+	.uleb128 0x27   /* DW_AT_prototyped */
+	.uleb128 0xc    /*    DW_FORM_flag*/
+	.uleb128 0x11   /* DW_AT_low_pc */
+	.uleb128 0x1    /*   DW_FORM_addr */
+	.uleb128 0x12   /* DW_AT_high_pc */
+	.uleb128 0x1    /*   DW_FORM_addr */
+	.byte	0x0
+	.byte	0x0
+        
+	.uleb128 0x3    /* abbrev code */
+	.uleb128 0x2e   /* TAG: DW_TAG_subprogram */
+	.byte	0x1     /* DW_CHILDREN_yes */
+	.uleb128 0x3f   /* DW_AT_external */
+	.uleb128 0xc    /*   DW_FORM_flag */
+	.uleb128 0x3    /* DW_AT_name */
+	.uleb128 0x8    /*   DW_FORM_string */
+	.uleb128 0x27   /* DW_AT_prototyped */
+	.uleb128 0xc    /*    DW_FORM_flag*/
+	.uleb128 0x11   /* DW_AT_low_pc */
+	.uleb128 0x1    /*   DW_FORM_addr */
+	.uleb128 0x12   /* DW_AT_high_pc */
+	.uleb128 0x1    /*   DW_FORM_addr */
+	.uleb128 0x1    /* DW_AT_sibling */
+	.uleb128 0x13   /*   DW_FORM_ref4 */
+	.byte	0x0
+	.byte	0x0
+        
+	.uleb128 0x4    /* abbrev code */
+	.uleb128 0x5    /* TAG: DW_TAG_formal_parameter */
+	.byte	0x0     /* DW_CHILDREN_no */
+	.uleb128 0x3    /* DW_AT_name */
+	.uleb128 0x8    /*   DW_FORM_string */
+	.uleb128 0x49   /* DW_AT_type */
+	.uleb128 0x13   /*   DW_FORM_ref4 */
+	.uleb128 0x2    /* DW_AT_location */
+	.uleb128 0xa    /*   DW_FORM_block1 */
+	.byte	0x0
+	.byte	0x0
+        
+	.uleb128 0x5    /* abbrev code */
+	.uleb128 0x24   /* TAG: DW_TAG_base_type */
+	.byte	0x0     /* DW_CHILDREN_no */
+	.uleb128 0xb    /* DW_AT_byte_size */
+	.uleb128 0xb    /*   DW_FORM_data1 */
+	.uleb128 0x3e   /* DW_AT_encoding */
+	.uleb128 0xb    /*   DW_FORM_data1 */
+	.uleb128 0x3    /* DW_AT_name */
+	.uleb128 0x8    /*   DW_FORM_string */
+	.byte	0x0
+	.byte	0x0
+        
+	.uleb128 0x6    /* abbrev code */
+	.uleb128 0x2e   /* TAG: DW_TAG_subprogram */
+	.byte	0x0     /* DW_CHILDREN_no */
+	.uleb128 0x3f   /* DW_AT_external */
+	.uleb128 0xc    /*   DW_FORM_flag */
+	.uleb128 0x3    /* DW_AT_name */
+	.uleb128 0x8    /*   DW_FORM_string */
+	.uleb128 0x49   /* DW_AT_type */
+	.uleb128 0x13   /*   DW_FORM_ref4 */
+	.uleb128 0x11   /* DW_AT_low_pc */
+	.uleb128 0x1    /*   DW_FORM_addr */
+	.uleb128 0x12   /* DW_AT_high_pc */
+	.uleb128 0x1    /*   DW_FORM_addr */
+	.byte	0x0
+	.byte	0x0
+
+        .uleb128 0x7    /* abbrev code */
+        .uleb128 0x13   /* DW_TAG_structure_type */
+        .byte   0x1     /* DW_CHILDREN_yes */
+        .uleb128 0x3    /* DW_AT_name */
+        .uleb128 0x8    /*   DW_FORM_string */
+        .uleb128 0xb    /* DW_AT_byte_size */
+        .uleb128 0xb    /*    DW_FORM_data1 */
+        .uleb128 0x1    /* DW_AT_sibling */
+        .uleb128 0x13   /*   DW_FORM_ref4 */
+        .byte   0x0
+        .byte   0x0
+        
+        .uleb128 0x8    /* abbrev code */
+        .uleb128 0xd    /* DW_TAG_member */
+        .byte   0x0     /* DW_children_no */
+        .uleb128 0x3    /* DW_AT_name */
+        .uleb128 0x8    /*   DW_FORM_string */
+        .uleb128 0x49   /* DW_AT_type */
+        .uleb128 0x13   /*   DW_FORM_ref4 */
+        .uleb128 0x38   /* DW_AT_data_member_location */
+        .uleb128 0xa    /*   DW_FORM_block1 */
+        .byte   0x0
+        .byte   0x0
+        
+	.byte	0x0
+
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp b/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp
new file mode 100644
index 0000000..ec98a3a
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp
@@ -0,0 +1,108 @@
+# Copyright 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib dwarf.exp
+
+set test "dw2-op-out-param"
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if ![dwarf2_support] {
+    return 0  
+}
+
+# This test can only be run on x86-64 targets.
+if {![istarget x86_64-*] || ![is_lp64_target]} {
+    return 0
+}
+
+if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_breakpoint "breakpt"
+
+# Change the radix, making it easier to spot 0xdeadbeef in output.
+gdb_test "set output-radix 16" \
+    "Output radix now set to decimal 16, hex 10, octal 20."
+
+# So we get to see the structure arguments.
+gdb_test_no_output "set print frame-arguments all"
+
+# (1) int_param_single_reg_loc
+gdb_continue_to_breakpoint "Stop in breakpt for test int_param_single_reg_loc"
+gdb_test "bt" "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_single_reg_loc \\(operand0=<optimized out>, operand1=0xdeadbe00deadbe01, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)" "Backtrace for test int_param_single_reg_loc"
+
+# (2) struct_param_single_reg_loc
+gdb_continue_to_breakpoint "Stop in breakpt for struct_param_single_reg_loc"
+set test "Backtrace for test struct_param_single_reg_loc"
+gdb_test_multiple "bt" "$test" {
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_single_reg_loc \\(operand0={a = 0xdeadbe00deadbe01, b = <optimized out>}, operand1={a = <optimized out>, b = 0xdeadbe04deadbe05}, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+	# If we ever fix gdb so that we start to hit this case then we
+	# should delete the passing case below as this is a better state to
+	# be in, and we don't want to regress back to the case below.
+	xpass $test
+    }
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_single_reg_loc \\(operand0=<optimized out>, operand1=<optimized out>, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+	# Having DWARF debug information placing things into registers that
+	# are then clobbered is really bad debug information.  If this is
+	# ever seen we'd prefer to fix the producer of the debug
+	# information.  Right now there are no plans to improve this case
+	# in gdb so we're happy with the output given above.
+	pass $test
+    }
+}
+
+# (3) struct_param_two_reg_pieces
+gdb_continue_to_breakpoint "Stop in breakpt for struct_param_two_reg_pieces"
+set test "Backtrace for test struct_param_two_reg_pieces"
+gdb_test_multiple "bt" "$test" {
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_two_reg_pieces \\(operand0={a = 0xdeadbe04deadbe05, b = <optimized out>}, operand1={a = <optimized out>, b = 0xdeadbe00deadbe01}, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+	# If we ever fix gdb so this passes we should delete the
+	# unsupported case below.
+	xpass $test
+    }
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_two_reg_pieces \\(operand0=.*, operand1=.*, operand2=.*\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+	# Having DWARF debug information placing things into registers that
+	# are then clobbered is really bad debug information.  If this is
+	# ever seen we'd prefer to fix the producer of the debug
+	# information.  Right now there are no plans to fix this case in
+	# gdb.
+	unsupported $test
+    }
+}
+
+# (4) int_param_two_reg_pieces
+gdb_continue_to_breakpoint "Stop in breakpt for int_param_two_reg_pieces"
+set test "Backtrace for test int_param_two_reg_pieces"
+gdb_test_multiple "bt" "$test" {
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_two_reg_pieces \\(operand0=<optimized out>, operand1=<optimized out>, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+	# If we ever fix gdb so this passes we should delete the
+	# unsupported case below.
+	xpass $test
+    }
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_two_reg_pieces \\(operand0=.*, operand1=.*, operand2=.*\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+	# Having DWARF debug information placing things into registers that
+	# are then clobbered is really bad debug information.  If this is
+	# ever seen we'd prefer to fix the producer of the debug
+	# information.  Right now there are no plans to fix this case in
+	# gdb.
+	unsupported $test
+    }
+}
+



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]