Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] While processing a struct die, store the method's address in its fn_field
@ 2014-11-24 15:55 Siva Chandra
  2014-11-24 20:22 ` Doug Evans
  0 siblings, 1 reply; 14+ messages in thread
From: Siva Chandra @ 2014-11-24 15:55 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2683 bytes --]

[The tests in this patch depend on this patch:
https://sourceware.org/ml/gdb-patches/2014-11/msg00479.html.  Also, it
adds a new dwarf2 test which I am not very sure I got it right.]

While processing a struct die, store the method's address in its fn_field.

This enables calling the method when its physname is missing and its
minsym cannot be discovered, but its address (DW_AT_low_pc) is available.
For example, this happens for the operator() methods of c++11 lambdas.
Consider the following C++ code:

int
main ()
{
  auto lambda = [] (int j) { return j + 113; };
  return lambda (-113);
}

When compiled with g++, the DWARF corresponding to the lambda's operator()
shows up under the DWARF for the function main as follows:

DW_TAG_subprogram
  DW_AT_name                  "operator()"
  DW_AT_type                  <0x0000002d>
  DW_AT_artificial            yes(1)
  DW_AT_low_pc                0x00400566
  DW_AT_high_pc               <offset-from-lowpc>19
  DW_AT_frame_base            len 0x0001: 9c: DW_OP_call_frame_cfa
  DW_AT_object_pointer        <0x0000010f>
  DW_AT_GNU_all_call_sites    yes(1)
  DW_TAG_pointer_type
    DW_AT_byte_size             0x00000008
    DW_AT_type                  <0x000000b9>
  DW_TAG_formal_parameter
    DW_AT_name                  "__closure"
    DW_AT_type                  <0x0000011b>
    DW_AT_artificial            yes(1)
    DW_AT_location              len 0x0002: 9168: DW_OP_fbreg -24
  DW_TAG_const_type
    DW_AT_type                  <0x00000109>
  DW_TAG_formal_parameter
    DW_AT_name                  "j"
    DW_AT_decl_file             0x00000001
    DW_AT_decl_line             0x00000004
    DW_AT_type                  <0x0000002d>
    DW_AT_location              len 0x0002: 9164:DW_OP_fbreg -28

There is no physname and the minsym corresponding to the the operator()
method does not demangle to its qualified name as specified by the DWARF.
However, since DW_AT_low_pc is available, it can be used to create a value
corresponding to the method in value.c:value_fn_field and subsequently be
passed to call_function_by_hand to invoke it.

gdb/ChangeLog:

2014-11-24  Siva Chandra Reddy  <sivachandra@google.com>

        * dwarf2read.c (dwarf2_add_member_fn): Note the methods address
        if its DT_AT_low_pc is available.
        * gdbtypes.h (struct fn_field): New field ADDR.
        (TYPE_FN_FIELD_ADDR): New macro.
        * value.c (value_fn_field): Use address of the method if
        available.

gdb/testsuite/ChangeLog:

2014-11-24  Siva Chandra Reddy  <sivachandra@google.com>

        * gdb.dwarf2/dw2-member-function-addr.S: New file.
        * gdb.dwarf2/dw2-member-function-addr.exp: New file.

[-- Attachment #2: member-function-addr-v1.txt --]
[-- Type: text/plain, Size: 18167 bytes --]

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 0790388..3a36cb1 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -12654,6 +12654,11 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
 
+  /* Set the address of the method if die has DW_AT_low_pc.  */
+  attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+  if (attr)
+    fnp->addr = attr_value_as_address (attr);
+
   /* Delay processing of the physname until later.  */
   if (cu->language == language_cplus || cu->language == language_java)
     {
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index d32c97c..d98887a 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -885,6 +885,9 @@ struct cplus_struct_type
 
 	struct fn_field
 	  {
+	    /* For methods which are not virtual, then this is the
+	       real address of the method if it is non-zero.  */
+	    CORE_ADDR addr;
 
 	    /* * If is_stub is clear, this is the mangled name which
 	       we can look up to find the address of the method
@@ -1344,6 +1347,7 @@ extern void allocate_gnat_aux_type (struct type *);
 
 #define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
 #define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
+#define TYPE_FN_FIELD_ADDR(thisfn, n) (thisfn)[n].addr
 #define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type
 #define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_FIELDS ((thisfn)[n].type)
 #define TYPE_FN_FIELD_CONST(thisfn, n) ((thisfn)[n].is_const)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-member-function-addr.S b/gdb/testsuite/gdb.dwarf2/dw2-member-function-addr.S
new file mode 100644
index 0000000..a89aa27
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-member-function-addr.S
@@ -0,0 +1,460 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 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/>.  */
+
+/* The contents below were generated by compiling the code below with
+       g++ -g-dA -S -std=c++11 lambda.cc
+
+   int
+   main ()
+   {
+     auto lambda = [] (int j) { return j + 113; };
+     return lambda (-113);
+   }  */
+
+	.file	"lambda.cc"
+	.text
+.Ltext0:
+	.align 2
+	.type	_ZZ4mainENKUliE_clEi, @function
+_ZZ4mainENKUliE_clEi:
+.LFB1:
+	.file 1 "lambda.cc"
+	# lambda.cc:4
+	.loc 1 4 0
+	.cfi_startproc
+# BLOCK 2 seq:0
+# PRED: ENTRY (FALLTHRU)
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	movq	%rdi, -8(%rbp)
+	movl	%esi, -12(%rbp)
+.LBB2:
+	# lambda.cc:4
+	.loc 1 4 0
+	movl	-12(%rbp), %eax
+	addl	$113, %eax
+.LBE2:
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+# SUCC: EXIT [100.0%]
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	_ZZ4mainENKUliE_clEi, .-_ZZ4mainENKUliE_clEi
+	.globl	main
+	.type	main, @function
+main:
+.LFB0:
+	# lambda.cc:3
+	.loc 1 3 0
+	.cfi_startproc
+# BLOCK 2 seq:0
+# PRED: ENTRY (FALLTHRU)
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	subq	$16, %rsp
+.LBB3:
+	# lambda.cc:5
+	.loc 1 5 0
+	leaq	-1(%rbp), %rax
+	movl	$-113, %esi
+	movq	%rax, %rdi
+	call	_ZZ4mainENKUliE_clEi
+.LBE3:
+	# lambda.cc:6
+	.loc 1 6 0
+	leave
+	.cfi_def_cfa 7, 8
+# SUCC: EXIT [100.0%]
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	main, .-main
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x115	# Length of Compilation Unit Info
+	.value	0x4	# DWARF version number
+	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+	.byte	0x8	# Pointer Size (in bytes)
+	.uleb128 0x1	# (DIE (0xb) DW_TAG_compile_unit)
+	.long	.LASF1	# DW_AT_producer: "GNU C++ 4.8.2 -mtune=generic -march=x86-64 -g -std=c++11 -fstack-protector"
+	.byte	0x4	# DW_AT_language
+	.long	.LASF2	# DW_AT_name: "lambda.cc"
+	.long	.LASF3	# DW_AT_comp_dir: "/home/sivachandra/LAB/c++"
+	.quad	.Ltext0	# DW_AT_low_pc
+	.quad	.Letext0-.Ltext0	# DW_AT_high_pc
+	.long	.Ldebug_line0	# DW_AT_stmt_list
+	.uleb128 0x2	# (DIE (0x2d) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.ascii "int\0"	# DW_AT_name
+	.uleb128 0x3	# (DIE (0x34) DW_TAG_subprogram)
+			# DW_AT_external
+	.long	.LASF4	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (lambda.cc)
+	.byte	0x2	# DW_AT_decl_line
+	.long	0x2d	# DW_AT_type
+	.quad	.LFB0	# DW_AT_low_pc
+	.quad	.LFE0-.LFB0	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_tail_call_sites
+	.uleb128 0x4	# (DIE (0x51) DW_TAG_lexical_block)
+	.quad	.LBB3	# DW_AT_low_pc
+	.quad	.LBE3-.LBB3	# DW_AT_high_pc
+	.uleb128 0x5	# (DIE (0x62) DW_TAG_variable)
+	.long	.LASF5	# DW_AT_name: "lambda"
+	.byte	0x1	# DW_AT_decl_file (lambda.cc)
+	.byte	0x4	# DW_AT_decl_line
+	.long	0x70	# DW_AT_type
+	.uleb128 0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 -17
+	.uleb128 0x6	# (DIE (0x70) DW_TAG_structure_type)
+	.long	.LASF6	# DW_AT_name: "__lambda0"
+	.byte	0x1	# DW_AT_byte_size
+	.byte	0x1	# DW_AT_decl_file (lambda.cc)
+	.byte	0x4	# DW_AT_decl_line
+	.uleb128 0x7	# (DIE (0x78) DW_TAG_subprogram)
+	.long	.LASF0	# DW_AT_name: "<lambda>"
+			# DW_AT_artificial
+			# DW_AT_declaration
+	.long	0x85	# DW_AT_object_pointer
+	.long	0x9c	# DW_AT_sibling
+	.uleb128 0x8	# (DIE (0x85) DW_TAG_formal_parameter)
+	.long	0x8a	# DW_AT_type
+			# DW_AT_artificial
+	.uleb128 0x9	# (DIE (0x8a) DW_TAG_pointer_type)
+	.byte	0x8	# DW_AT_byte_size
+	.long	0x70	# DW_AT_type
+	.uleb128 0xa	# (DIE (0x90) DW_TAG_formal_parameter)
+	.long	0x95	# DW_AT_type
+	.uleb128 0xb	# (DIE (0x95) DW_TAG_rvalue_reference_type)
+	.byte	0x8	# DW_AT_byte_size
+	.long	0x70	# DW_AT_type
+	.byte	0	# end of children of DIE 0x78
+	.uleb128 0x7	# (DIE (0x9c) DW_TAG_subprogram)
+	.long	.LASF0	# DW_AT_name: "<lambda>"
+			# DW_AT_artificial
+			# DW_AT_declaration
+	.long	0xa9	# DW_AT_object_pointer
+	.long	0xbf	# DW_AT_sibling
+	.uleb128 0x8	# (DIE (0xa9) DW_TAG_formal_parameter)
+	.long	0x8a	# DW_AT_type
+			# DW_AT_artificial
+	.uleb128 0xa	# (DIE (0xae) DW_TAG_formal_parameter)
+	.long	0xb3	# DW_AT_type
+	.uleb128 0xc	# (DIE (0xb3) DW_TAG_reference_type)
+	.byte	0x8	# DW_AT_byte_size
+	.long	0xb9	# DW_AT_type
+	.uleb128 0xd	# (DIE (0xb9) DW_TAG_const_type)
+	.long	0x70	# DW_AT_type
+	.byte	0	# end of children of DIE 0x9c
+	.uleb128 0x7	# (DIE (0xbf) DW_TAG_subprogram)
+	.long	.LASF0	# DW_AT_name: "<lambda>"
+			# DW_AT_artificial
+			# DW_AT_declaration
+	.long	0xcc	# DW_AT_object_pointer
+	.long	0xd2	# DW_AT_sibling
+	.uleb128 0x8	# (DIE (0xcc) DW_TAG_formal_parameter)
+	.long	0x8a	# DW_AT_type
+			# DW_AT_artificial
+	.byte	0	# end of children of DIE 0xbf
+	.uleb128 0xe	# (DIE (0xd2) DW_TAG_subprogram)
+	.long	.LASF7	# DW_AT_name: "operator()"
+	.long	0x2d	# DW_AT_type
+			# DW_AT_artificial
+	.quad	.LFB1	# DW_AT_low_pc
+	.quad	.LFE1-.LFB1	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+	.long	0xf7	# DW_AT_object_pointer
+			# DW_AT_GNU_all_call_sites
+	.uleb128 0x9	# (DIE (0xf1) DW_TAG_pointer_type)
+	.byte	0x8	# DW_AT_byte_size
+	.long	0xb9	# DW_AT_type
+	.uleb128 0xf	# (DIE (0xf7) DW_TAG_formal_parameter)
+	.long	.LASF8	# DW_AT_name: "__closure"
+	.long	0x103	# DW_AT_type
+			# DW_AT_artificial
+	.uleb128 0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 -24
+	.uleb128 0xd	# (DIE (0x103) DW_TAG_const_type)
+	.long	0xf1	# DW_AT_type
+	.uleb128 0x10	# (DIE (0x108) DW_TAG_formal_parameter)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (lambda.cc)
+	.byte	0x4	# DW_AT_decl_line
+	.long	0x2d	# DW_AT_type
+	.uleb128 0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 -28
+	.byte	0	# end of children of DIE 0xd2
+	.byte	0	# end of children of DIE 0x70
+	.byte	0	# end of children of DIE 0x51
+	.byte	0	# end of children of DIE 0x34
+	.byte	0	# end of children of DIE 0xb
+	.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 0xe	# (DW_FORM_strp)
+	.uleb128 0x13	# (DW_AT_language)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x1b	# (DW_AT_comp_dir)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x7	# (DW_FORM_data8)
+	.uleb128 0x10	# (DW_AT_stmt_list)
+	.uleb128 0x17	# (DW_FORM_sec_offset)
+	.byte	0
+	.byte	0
+	.uleb128 0x2	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# 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	0
+	.byte	0
+	.uleb128 0x3	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.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 0x7	# (DW_FORM_data8)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2116	# (DW_AT_GNU_all_tail_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.byte	0
+	.byte	0
+	.uleb128 0x4	# (abbrev code)
+	.uleb128 0xb	# (TAG: DW_TAG_lexical_block)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x7	# (DW_FORM_data8)
+	.byte	0
+	.byte	0
+	.uleb128 0x5	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.byte	0
+	.byte	0
+	.uleb128 0x6	# (abbrev code)
+	.uleb128 0x13	# (TAG: DW_TAG_structure_type)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.byte	0
+	.byte	0
+	.uleb128 0x7	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x34	# (DW_AT_artificial)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x3c	# (DW_AT_declaration)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x64	# (DW_AT_object_pointer)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x8	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x34	# (DW_AT_artificial)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.byte	0
+	.byte	0
+	.uleb128 0x9	# (abbrev code)
+	.uleb128 0xf	# (TAG: DW_TAG_pointer_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xa	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xb	# (abbrev code)
+	.uleb128 0x42	# (TAG: DW_TAG_rvalue_reference_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xc	# (abbrev code)
+	.uleb128 0x10	# (TAG: DW_TAG_reference_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xd	# (abbrev code)
+	.uleb128 0x26	# (TAG: DW_TAG_const_type)
+	.byte	0	# DW_children_no
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xe	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x34	# (DW_AT_artificial)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x7	# (DW_FORM_data8)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x64	# (DW_AT_object_pointer)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.byte	0
+	.byte	0
+	.uleb128 0xf	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x34	# (DW_AT_artificial)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.byte	0
+	.byte	0
+	.uleb128 0x10	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_aranges,"",@progbits
+	.long	0x2c	# Length of Address Ranges Info
+	.value	0x2	# DWARF Version
+	.long	.Ldebug_info0	# Offset of Compilation Unit Info
+	.byte	0x8	# Size of Address
+	.byte	0	# Size of Segment Descriptor
+	.value	0	# Pad to 16 byte boundary
+	.value	0
+	.quad	.Ltext0	# Address
+	.quad	.Letext0-.Ltext0	# Length
+	.quad	0
+	.quad	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF3:
+	.string	"/home/sivachandra/LAB/c++"
+.LASF6:
+	.string	"__lambda0"
+.LASF7:
+	.string	"operator()"
+.LASF2:
+	.string	"lambda.cc"
+.LASF0:
+	.string	"<lambda>"
+.LASF1:
+	.string	"GNU C++ 4.8.2 -mtune=generic -march=x86-64 -g -std=c++11 -fstack-protector"
+.LASF4:
+	.string	"main"
+.LASF5:
+	.string	"lambda"
+.LASF8:
+	.string	"__closure"
+	.ident	"GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-member-function-addr.exp b/gdb/testsuite/gdb.dwarf2/dw2-member-function-addr.exp
new file mode 100644
index 0000000..9356e35
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-member-function-addr.exp
@@ -0,0 +1,33 @@
+# Copyright 2014 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
+
+if {![dwarf2_support]} {
+    return 0
+}
+
+standard_testfile .S
+
+if {[prepare_for_testing_full $testfile.exp \
+	 [list $testfile debug $srcfile nodebug]]} {
+    return -1
+}
+
+clean_restart $testfile
+
+gdb_test "break main" "Breakpoint 1 .*" "break main"
+gdb_test "run" "Starting program: .*Breakpoint 1.*" "run"
+gdb_test "p lambda(10)" ".* = 123" "p lambda()"
diff --git a/gdb/value.c b/gdb/value.c
index ecfb154..7c83b81 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3068,24 +3068,30 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
   struct value *v;
   struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
   const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
-  struct symbol *sym;
+  const CORE_ADDR addr = TYPE_FN_FIELD_ADDR (f, j);
+  struct symbol *sym = NULL;
   struct bound_minimal_symbol msym;
 
-  sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0);
-  if (sym != NULL)
+  if (!addr)
     {
-      memset (&msym, 0, sizeof (msym));
-    }
-  else
-    {
-      gdb_assert (sym == NULL);
-      msym = lookup_bound_minimal_symbol (physname);
-      if (msym.minsym == NULL)
-	return NULL;
+      sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0);
+      if (sym != NULL)
+	{
+	  memset (&msym, 0, sizeof (msym));
+	}
+      else
+	{
+	  gdb_assert (sym == NULL);
+	  msym = lookup_bound_minimal_symbol (physname);
+	  if (msym.minsym == NULL)
+	    return NULL;
+	}
     }
 
   v = allocate_value (ftype);
-  if (sym)
+  if (addr)
+    set_value_address (v, f->addr);
+  else if (sym)
     {
       set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (sym)));
     }

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-11-26 21:11 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-24 15:55 [RFC] While processing a struct die, store the method's address in its fn_field Siva Chandra
2014-11-24 20:22 ` Doug Evans
2014-11-24 20:28   ` Doug Evans
2014-11-26  4:36     ` Doug Evans
2014-11-26  4:46       ` Siva Chandra
2014-11-26  5:05         ` Doug Evans
2014-11-25 15:00   ` Siva Chandra
2014-11-25 22:10     ` Doug Evans
2014-11-25 23:37       ` Siva Chandra
2014-11-26  3:22         ` Doug Evans
2014-11-26  3:58           ` Siva Chandra
2014-11-26  5:19             ` Doug Evans
2014-11-26  7:31           ` Siva Chandra
2014-11-26 21:11             ` Doug Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox