public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* Re: [PATCH] Fission support for multiple CUs per DWO file
@ 2017-05-22 18:01 Doug Evans via gdb-patches
  2017-06-01 23:33 ` David Blaikie
  0 siblings, 1 reply; 6+ messages in thread
From: Doug Evans via gdb-patches @ 2017-05-22 18:01 UTC (permalink / raw)
  To: David Blaikie; +Cc: gdb-patches, Pedro Alves

David Blaikie writes:
 > ...

Hi. Review comments inline.
All nits.

First one: Tab instead of spaces throughout (including ChangeLog entries).

The testcase is fine with me.

 > gdb/ChangeLog:
 > 
 > 2017-05-12  David Blaikie  <dblaikie@gmail.com>
 > 
 >         * dwarf2read.c (struct dwo_file): Use a htab of dwo_unit*
 > (rather than a singular dwo_unit*) to support multiple CUs in the same
 > way that multiple TUs are supported.
 >         (static void create_cus_hash_table): Replace create_dwo_cu
 > with a function for parsing multiple CUs from a DWO file.
 >         (open_and_init_dwo_file): Use create_cus_hash_table rather
 > than create_dwo_cu.
 >         (lookup_dwo_cutu): Lookup CU in the hash table in the dwo_file
 > with htab_find, rather than comparing the signature to a singleton CU
 > in the dwo_file.
 > 
 > gdb/testsuite/ChangeLog:
 > 
 > 2017-05-12  David Blaikie  <dblaikie@gmail.com>
 > 
 >         * gdb.dwarf2/fission-multi-cu.S: Test containing multiple CUs
 > in a DWO, built from fission-multi-cu{1,2}.c.
 >         * gdb.dwarf2/fission-multi-cu.exp: Test similar to
 > fission-base.exp, except putting 'main' and 'func' in separate CUs
 > while in the same DWO file.
 >         * gdb.dwarf2/fission-multi-cu1.c: First CU for the
 > multi-CU-single-DWO test.
 >         * gdb.dwarf2/fission-multi-cu2.c: Second CU for the
 > multi-CU-single-DWO test.
 > diff --git gdb/dwarf2read.c gdb/dwarf2read.c
 > index b58d0fc16e..29eb5a14b2 100644
 > --- gdb/dwarf2read.c
 > +++ gdb/dwarf2read.c
 > @@ -852,12 +852,9 @@ struct dwo_file
 >       sections (for lack of a better name).  */
 >    struct dwo_sections sections;
 >  
 > -  /* The CU in the file.
 > -     We only support one because having more than one requires hacking the
 > -     dwo_name of each to match, which is highly unlikely to happen.
 > -     Doing this means all TUs can share comp_dir: We also assume that
 > -     DW_AT_comp_dir across all TUs in a DWO file will be identical.  */
 > -  struct dwo_unit *cu;
 > +  /* The CUs in the file.
 > +     Each element is a struct dwo_unit. */

Since this is currently non-standard, I think it will help some readers
to elaborate on the Why of things here. IOW, add a comment explaining why
we're now supporting multi-CUs in one DWO file.

 > +  htab_t cus;
 >  
 >    /* Table of TUs in the file.
 >       Each element is a struct dwo_unit.  */
 > @@ -9702,72 +9699,75 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
 >  			hex_string (dwo_unit->signature));
 >  }
 >  
 > -/* Create the dwo_unit for the lone CU in DWO_FILE.
 > -   Note: This function processes DWO files only, not DWP files.  */

Need to keep the function comment (just reword it).
And please keep the note about only being used for DWO files, not DWP files.

 > -
 > -static struct dwo_unit *
 > -create_dwo_cu (struct dwo_file *dwo_file)
 > +static void create_cus_hash_table (struct dwo_file &dwo_file,
 > +                                   dwarf2_section_info &section,
 > +                                   htab_t &cus_htab)
 >  {
 >    struct objfile *objfile = dwarf2_per_objfile->objfile;
 > -  struct dwarf2_section_info *section = &dwo_file->sections.info;
 > +  const struct dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev;
 >    const gdb_byte *info_ptr, *end_ptr;
 > -  struct create_dwo_cu_data create_dwo_cu_data;
 > -  struct dwo_unit *dwo_unit;
 >  
 > -  dwarf2_read_section (objfile, section);
 > -  info_ptr = section->buffer;
 > +  dwarf2_read_section (objfile, &section);
 > +  info_ptr = section.buffer;
 >  
 >    if (info_ptr == NULL)
 > -    return NULL;
 > +    return;
 >  
 >    if (dwarf_read_debug)
 >      {
 >        fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
 > -			  get_section_name (section),
 > -			  get_section_file_name (section));
 > +			  get_section_name (&section),
 > +			  get_section_file_name (&section));
 >      }
 >  
 > -  create_dwo_cu_data.dwo_file = dwo_file;
 > -  dwo_unit = NULL;
 > -
 > -  end_ptr = info_ptr + section->size;
 > +  end_ptr = info_ptr  + section.size;

extra space

 >    while (info_ptr < end_ptr)
 >      {
 >        struct dwarf2_per_cu_data per_cu;
 > +      struct create_dwo_cu_data create_dwo_cu_data;
 > +      struct dwo_unit *dwo_unit;
 > +      void **slot;
 > +      sect_offset sect_off = (sect_offset) (info_ptr - section.buffer);
 >  
 >        memset (&create_dwo_cu_data.dwo_unit, 0,
 >  	      sizeof (create_dwo_cu_data.dwo_unit));
 >        memset (&per_cu, 0, sizeof (per_cu));
 >        per_cu.objfile = objfile;
 >        per_cu.is_debug_types = 0;
 > -      per_cu.sect_off = sect_offset (info_ptr - section->buffer);
 > -      per_cu.section = section;
 > +      per_cu.sect_off = sect_offset (info_ptr - section.buffer);
 > +      per_cu.section = &section;
 > +      create_dwo_cu_data.dwo_file = &dwo_file;
 >  
 > -      init_cutu_and_read_dies_no_follow (&per_cu, dwo_file,
 > +      init_cutu_and_read_dies_no_follow (&per_cu, &dwo_file,
 >  					 create_dwo_cu_reader,
 >  					 &create_dwo_cu_data);
 > +      info_ptr += per_cu.length;
 >  
 > -      if (create_dwo_cu_data.dwo_unit.dwo_file != NULL)
 > -	{
 > -	  /* If we've already found one, complain.  We only support one
 > -	     because having more than one requires hacking the dwo_name of
 > -	     each to match, which is highly unlikely to happen.  */
 > -	  if (dwo_unit != NULL)
 > -	    {
 > -	      complaint (&symfile_complaints,
 > -			 _("Multiple CUs in DWO file %s [in module %s]"),
 > -			 dwo_file->dwo_name, objfile_name (objfile));
 > -	      break;
 > -	    }

Add a comment explaining why this test is present:

 > +      if (create_dwo_cu_data.dwo_unit.dwo_file == NULL)
 > +        continue;
 >  
 > -	  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
 > -	  *dwo_unit = create_dwo_cu_data.dwo_unit;
 > -	}
 > +      if (cus_htab == NULL)

Remove the surrounding braces.

 > +        {
 > +          cus_htab = allocate_dwo_unit_table (objfile);
 > +        }
 >  
 > -      info_ptr += per_cu.length;
 > -    }
 > +      dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
 > +      *dwo_unit = create_dwo_cu_data.dwo_unit;
 > +      slot = htab_find_slot (cus_htab, dwo_unit, INSERT);
 > +      gdb_assert (slot != NULL);
 > +      if (*slot != NULL)
 > +        {
 > +          const struct dwo_unit *dup_cu = (const struct dwo_unit *) *slot;
 > +          sect_offset dup_sect_off = dup_cu->sect_off;
 >  
 > -  return dwo_unit;
 > +	  complaint (&symfile_complaints,
 > +		     _("debug cu entry at offset 0x%x is duplicate to"
 > +		       " the entry at offset 0x%x, signature %s"),
 > +		     to_underlying (sect_off), to_underlying (dup_sect_off),
 > +		     hex_string (dwo_unit->signature));
 > +        }
 > +      *slot = (void *) dwo_unit;
 > +    }
 >  }
 >  
 >  /* DWP file .debug_{cu,tu}_index section format:
 > @@ -10772,7 +10772,7 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
 >    bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections,
 >  			 &dwo_file->sections);
 >  
 > -  dwo_file->cu = create_dwo_cu (dwo_file);
 > +  create_cus_hash_table (*dwo_file, dwo_file->sections.info, dwo_file->cus);
 >  
 >    create_debug_types_hash_table (dwo_file, dwo_file->sections.types,
 >  				 dwo_file->tus);
 > @@ -11139,10 +11139,13 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
 >  	      dwo_cutu
 >  		= (struct dwo_unit *) htab_find (dwo_file->tus, &find_dwo_cutu);
 >  	    }
 > -	  else if (!is_debug_types && dwo_file->cu)
 > +	  else if (!is_debug_types && dwo_file->cus)
 >  	    {
 > -	      if (signature == dwo_file->cu->signature)
 > -		dwo_cutu = dwo_file->cu;
 > +              struct dwo_unit find_dwo_cutu;
 > +
 > +              memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
 > +              find_dwo_cutu.signature = signature;
 > +              dwo_cutu = (struct dwo_unit *) htab_find (dwo_file->cus, &find_dwo_cutu);
 >  	    }
 >  
 >  	  if (dwo_cutu != NULL)
 > diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu.S gdb/testsuite/gdb.dwarf2/fission-multi-cu.S
 > new file mode 100644
 > index 0000000000..d09a7e543d
 > --- /dev/null
 > +++ gdb/testsuite/gdb.dwarf2/fission-multi-cu.S
 > @@ -0,0 +1,374 @@
 > +/* This testcase is part of GDB, the GNU debugger.
 > +
 > +   Copyright 2012-2017 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/>.
 > +
 > +   This file was created by doing:
 > +
 > +   clang fission-multi-cu*.c -g -fno-split-dwarf-inlining -emit-llvm -S -c
 > +   llvm-link fission-multi-cu*.ll -S -o fission-multi-cu.ll
 > +   clang-tot fission-multi-cu.ll -gsplit-dwarf -S
 > +
 > +   and then massaging the output.
 > +*/
 > +	.text
 > +	.file	"llvm-link"
 > +	.globl	func
 > +	.p2align	4, 0x90
 > +	.type	func,@function
 > +func:                                   # @func
 > +.Lfunc_begin0:
 > +	.file	1 "fission-multi-cu1.c"
 > +	.loc	1 20 0                  # fission-multi-cu1.c:20:0
 > +	.cfi_startproc
 > +# BB#0:                                 # %entry
 > +	pushq	%rbp
 > +	.cfi_def_cfa_offset 16
 > +	.cfi_offset %rbp, -16
 > +	movq	%rsp, %rbp
 > +	.cfi_def_cfa_register %rbp
 > +	movl	%edi, -4(%rbp)
 > +	.loc	1 21 10 prologue_end    # fission-multi-cu1.c:21:10
 > +	movl	-4(%rbp), %edi
 > +	.loc	1 21 14 is_stmt 0       # fission-multi-cu1.c:21:14
 > +	addl	$1, %edi
 > +	.loc	1 21 3                  # fission-multi-cu1.c:21:3
 > +	movl	%edi, %eax
 > +	popq	%rbp
 > +	retq
 > +.Lfunc_end0:
 > +	.size	func, .Lfunc_end0-func
 > +	.cfi_endproc
 > +
 > +	.globl	main
 > +	.p2align	4, 0x90
 > +	.type	main,@function
 > +main:                                   # @main
 > +.Lfunc_begin1:
 > +	.file	2 "fission-multi-cu2.c"
 > +	.loc	2 23 0 is_stmt 1        # fission-multi-cu2.c:23:0
 > +	.cfi_startproc
 > +# BB#0:                                 # %entry
 > +	pushq	%rbp
 > +	.cfi_def_cfa_offset 16
 > +	.cfi_offset %rbp, -16
 > +	movq	%rsp, %rbp
 > +	.cfi_def_cfa_register %rbp
 > +	movl	$4294967295, %edi       # imm = 0xFFFFFFFF
 > +	.loc	2 24 3 prologue_end     # fission-multi-cu2.c:24:3
 > +	movb	$0, %al
 > +	callq	func
 > +	xorl	%eax, %eax
 > +	.loc	2 25 1                  # fission-multi-cu2.c:25:1
 > +	popq	%rbp
 > +	retq
 > +.Lfunc_end1:
 > +	.size	main, .Lfunc_end1-main
 > +	.cfi_endproc
 > +
 > +	.section	.debug_str,"MS",@progbits,1
 > +.Lskel_string0:
 > +	.asciz	"fission-multi-cu.dwo"  # string offset=0
 > +.Lskel_string1:
 > +	.asciz	"/tmp/src/gdb/testsuite" # string offset=21
 > +	.section	.debug_loc.dwo,"",@progbits
 > +	.section	.debug_abbrev,"",@progbits
 > +	.byte	1                       # Abbreviation Code
 > +	.byte	17                      # DW_TAG_compile_unit
 > +	.byte	0                       # DW_CHILDREN_no
 > +	.byte	16                      # DW_AT_stmt_list
 > +	.byte	23                      # DW_FORM_sec_offset
 > +	.ascii	"\260B"                 # DW_AT_GNU_dwo_name
 > +	.byte	14                      # DW_FORM_strp
 > +	.byte	27                      # DW_AT_comp_dir
 > +	.byte	14                      # DW_FORM_strp
 > +	.ascii	"\261B"                 # DW_AT_GNU_dwo_id
 > +	.byte	7                       # DW_FORM_data8
 > +	.ascii	"\263B"                 # DW_AT_GNU_addr_base
 > +	.byte	23                      # DW_FORM_sec_offset
 > +	.byte	17                      # DW_AT_low_pc
 > +	.byte	1                       # DW_FORM_addr
 > +	.byte	18                      # DW_AT_high_pc
 > +	.byte	6                       # DW_FORM_data4
 > +	.byte	0                       # EOM(1)
 > +	.byte	0                       # EOM(2)
 > +	.byte	0                       # EOM(3)
 > +	.section	.debug_info,"",@progbits
 > +.Lcu_begin0:
 > +	.long	44                      # Length of Unit
 > +	.short	4                       # DWARF version number
 > +	.long	.debug_abbrev           # Offset Into Abbrev. Section
 > +	.byte	8                       # Address Size (in bytes)
 > +	.byte	1                       # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
 > +	.long	.Lline_table_start0     # DW_AT_stmt_list
 > +	.long	.Lskel_string0          # DW_AT_GNU_dwo_name
 > +	.long	.Lskel_string1          # DW_AT_comp_dir
 > +	.quad	7615852067747431413     # DW_AT_GNU_dwo_id
 > +	.long	.debug_addr             # DW_AT_GNU_addr_base
 > +	.quad	.Lfunc_begin0           # DW_AT_low_pc
 > +	.long	.Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
 > +.Lcu_begin1:
 > +	.long	44                      # Length of Unit
 > +	.short	4                       # DWARF version number
 > +	.long	.debug_abbrev           # Offset Into Abbrev. Section
 > +	.byte	8                       # Address Size (in bytes)
 > +	.byte	1                       # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
 > +	.long	.Lline_table_start0     # DW_AT_stmt_list
 > +	.long	.Lskel_string0          # DW_AT_GNU_dwo_name
 > +	.long	.Lskel_string1          # DW_AT_comp_dir
 > +	.quad	2037650261599692324     # DW_AT_GNU_dwo_id
 > +	.long	.debug_addr             # DW_AT_GNU_addr_base
 > +	.quad	.Lfunc_begin1           # DW_AT_low_pc
 > +	.long	.Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
 > +	.section	.debug_ranges,"",@progbits
 > +	.section	.debug_macinfo,"",@progbits
 > +.Lcu_macro_begin1:
 > +.Lcu_macro_begin3:
 > +	.byte	0                       # End Of Macro List Mark
 > +	.section	.debug_str.dwo,"MS",@progbits,1
 > +.Linfo_string0:
 > +	.asciz	"fission-multi-cu.dwo"  # string offset=0
 > +.Linfo_string1:
 > +	.asciz	"clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)" # string offset=21
 > +.Linfo_string2:
 > +	.asciz	"fission-multi-cu1.c" # string offset=76
 > +.Linfo_string3:
 > +	.asciz	"fission-multi-cu2.c" # string offset=96
 > +.Linfo_string4:
 > +	.asciz	"func"                  # string offset=116
 > +.Linfo_string5:
 > +	.asciz	"int"                   # string offset=121
 > +.Linfo_string6:
 > +	.asciz	"main"                  # string offset=125
 > +.Linfo_string7:
 > +	.asciz	"arg"                   # string offset=130
 > +	.section	.debug_str_offsets.dwo,"",@progbits
 > +	.long	0
 > +	.long	21
 > +	.long	76
 > +	.long	96
 > +	.long	116
 > +	.long	121
 > +	.long	125
 > +	.long	130
 > +	.section	.debug_info.dwo,"",@progbits
 > +	.long	53                      # Length of Unit
 > +	.short	4                       # DWARF version number
 > +	.long	0                       # Offset Into Abbrev. Section
 > +	.byte	8                       # Address Size (in bytes)
 > +	.byte	1                       # Abbrev [1] 0xb:0x2e DW_TAG_compile_unit
 > +	.byte	0                       # DW_AT_GNU_dwo_name
 > +	.byte	1                       # DW_AT_producer
 > +	.short	12                      # DW_AT_language
 > +	.byte	2                       # DW_AT_name
 > +	.quad	7615852067747431413     # DW_AT_GNU_dwo_id
 > +	.byte	2                       # Abbrev [2] 0x19:0x1b DW_TAG_subprogram
 > +	.byte	0                       # DW_AT_low_pc
 > +	.long	.Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
 > +	.byte	1                       # DW_AT_frame_base
 > +	.byte	86
 > +	.byte	4                       # DW_AT_name
 > +	.byte	1                       # DW_AT_decl_file
 > +	.byte	19                      # DW_AT_decl_line
 > +                                        # DW_AT_prototyped
 > +	.long	52                      # DW_AT_type
 > +                                        # DW_AT_external
 > +	.byte	3                       # Abbrev [3] 0x28:0xb DW_TAG_formal_parameter
 > +	.byte	2                       # DW_AT_location
 > +	.byte	145
 > +	.byte	124
 > +	.byte	7                       # DW_AT_name
 > +	.byte	1                       # DW_AT_decl_file
 > +	.byte	19                      # DW_AT_decl_line
 > +	.long	52                      # DW_AT_type
 > +	.byte	0                       # End Of Children Mark
 > +	.byte	4                       # Abbrev [4] 0x34:0x4 DW_TAG_base_type
 > +	.byte	5                       # DW_AT_name
 > +	.byte	5                       # DW_AT_encoding
 > +	.byte	4                       # DW_AT_byte_size
 > +	.byte	0                       # End Of Children Mark
 > +	.long	41                      # Length of Unit
 > +	.short	4                       # DWARF version number
 > +	.long	0                       # Offset Into Abbrev. Section
 > +	.byte	8                       # Address Size (in bytes)
 > +	.byte	1                       # Abbrev [1] 0xb:0x22 DW_TAG_compile_unit
 > +	.byte	0                       # DW_AT_GNU_dwo_name
 > +	.byte	1                       # DW_AT_producer
 > +	.short	12                      # DW_AT_language
 > +	.byte	3                       # DW_AT_name
 > +	.quad	2037650261599692324     # DW_AT_GNU_dwo_id
 > +	.byte	5                       # Abbrev [5] 0x19:0xf DW_TAG_subprogram
 > +	.byte	1                       # DW_AT_low_pc
 > +	.long	.Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
 > +	.byte	1                       # DW_AT_frame_base
 > +	.byte	86
 > +	.byte	6                       # DW_AT_name
 > +	.byte	2                       # DW_AT_decl_file
 > +	.byte	22                      # DW_AT_decl_line
 > +	.long	40                      # DW_AT_type
 > +                                        # DW_AT_external
 > +	.byte	4                       # Abbrev [4] 0x28:0x4 DW_TAG_base_type
 > +	.byte	5                       # DW_AT_name
 > +	.byte	5                       # DW_AT_encoding
 > +	.byte	4                       # DW_AT_byte_size
 > +	.byte	0                       # End Of Children Mark
 > +	.section	.debug_abbrev.dwo,"",@progbits
 > +	.byte	1                       # Abbreviation Code
 > +	.byte	17                      # DW_TAG_compile_unit
 > +	.byte	1                       # DW_CHILDREN_yes
 > +	.ascii	"\260B"                 # DW_AT_GNU_dwo_name
 > +	.ascii	"\202>"                 # DW_FORM_GNU_str_index
 > +	.byte	37                      # DW_AT_producer
 > +	.ascii	"\202>"                 # DW_FORM_GNU_str_index
 > +	.byte	19                      # DW_AT_language
 > +	.byte	5                       # DW_FORM_data2
 > +	.byte	3                       # DW_AT_name
 > +	.ascii	"\202>"                 # DW_FORM_GNU_str_index
 > +	.ascii	"\261B"                 # DW_AT_GNU_dwo_id
 > +	.byte	7                       # DW_FORM_data8
 > +	.byte	0                       # EOM(1)
 > +	.byte	0                       # EOM(2)
 > +	.byte	2                       # Abbreviation Code
 > +	.byte	46                      # DW_TAG_subprogram
 > +	.byte	1                       # DW_CHILDREN_yes
 > +	.byte	17                      # DW_AT_low_pc
 > +	.ascii	"\201>"                 # DW_FORM_GNU_addr_index
 > +	.byte	18                      # DW_AT_high_pc
 > +	.byte	6                       # DW_FORM_data4
 > +	.byte	64                      # DW_AT_frame_base
 > +	.byte	24                      # DW_FORM_exprloc
 > +	.byte	3                       # DW_AT_name
 > +	.ascii	"\202>"                 # DW_FORM_GNU_str_index
 > +	.byte	58                      # DW_AT_decl_file
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	59                      # DW_AT_decl_line
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	39                      # DW_AT_prototyped
 > +	.byte	25                      # DW_FORM_flag_present
 > +	.byte	73                      # DW_AT_type
 > +	.byte	19                      # DW_FORM_ref4
 > +	.byte	63                      # DW_AT_external
 > +	.byte	25                      # DW_FORM_flag_present
 > +	.byte	0                       # EOM(1)
 > +	.byte	0                       # EOM(2)
 > +	.byte	3                       # Abbreviation Code
 > +	.byte	5                       # DW_TAG_formal_parameter
 > +	.byte	0                       # DW_CHILDREN_no
 > +	.byte	2                       # DW_AT_location
 > +	.byte	24                      # DW_FORM_exprloc
 > +	.byte	3                       # DW_AT_name
 > +	.ascii	"\202>"                 # DW_FORM_GNU_str_index
 > +	.byte	58                      # DW_AT_decl_file
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	59                      # DW_AT_decl_line
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	73                      # DW_AT_type
 > +	.byte	19                      # DW_FORM_ref4
 > +	.byte	0                       # EOM(1)
 > +	.byte	0                       # EOM(2)
 > +	.byte	4                       # Abbreviation Code
 > +	.byte	36                      # DW_TAG_base_type
 > +	.byte	0                       # DW_CHILDREN_no
 > +	.byte	3                       # DW_AT_name
 > +	.ascii	"\202>"                 # DW_FORM_GNU_str_index
 > +	.byte	62                      # DW_AT_encoding
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	11                      # DW_AT_byte_size
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	0                       # EOM(1)
 > +	.byte	0                       # EOM(2)
 > +	.byte	5                       # Abbreviation Code
 > +	.byte	46                      # DW_TAG_subprogram
 > +	.byte	0                       # DW_CHILDREN_no
 > +	.byte	17                      # DW_AT_low_pc
 > +	.ascii	"\201>"                 # DW_FORM_GNU_addr_index
 > +	.byte	18                      # DW_AT_high_pc
 > +	.byte	6                       # DW_FORM_data4
 > +	.byte	64                      # DW_AT_frame_base
 > +	.byte	24                      # DW_FORM_exprloc
 > +	.byte	3                       # DW_AT_name
 > +	.ascii	"\202>"                 # DW_FORM_GNU_str_index
 > +	.byte	58                      # DW_AT_decl_file
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	59                      # DW_AT_decl_line
 > +	.byte	11                      # DW_FORM_data1
 > +	.byte	73                      # DW_AT_type
 > +	.byte	19                      # DW_FORM_ref4
 > +	.byte	63                      # DW_AT_external
 > +	.byte	25                      # DW_FORM_flag_present
 > +	.byte	0                       # EOM(1)
 > +	.byte	0                       # EOM(2)
 > +	.byte	0                       # EOM(3)
 > +	.section	.debug_line.dwo,"",@progbits
 > +.Ltmp4:
 > +	.long	(.Ltmp5-.Ltmp4)-4
 > +	.short	2
 > +	.long	(.Ltmp6-.Ltmp4)-10
 > +	.byte	1
 > +	.byte	1
 > +	.byte	-5
 > +	.byte	14
 > +	.byte	1
 > +	.byte	0
 > +	.byte	0
 > +.Ltmp6:
 > +.Ltmp5:
 > +	.section	.debug_addr,"",@progbits
 > +	.quad	.Lfunc_begin0
 > +	.quad	.Lfunc_begin1
 > +	.section	.debug_pubnames,"",@progbits
 > +	.long	.LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info
 > +.LpubNames_begin0:
 > +	.short	2                       # DWARF Version
 > +	.long	.Lcu_begin0             # Offset of Compilation Unit Info
 > +	.long	48                      # Compilation Unit Length
 > +	.long	25                      # DIE offset
 > +	.asciz	"func"                  # External Name
 > +	.long	0                       # End Mark
 > +.LpubNames_end0:
 > +	.long	.LpubNames_end1-.LpubNames_begin1 # Length of Public Names Info
 > +.LpubNames_begin1:
 > +	.short	2                       # DWARF Version
 > +	.long	.Lcu_begin1             # Offset of Compilation Unit Info
 > +	.long	48                      # Compilation Unit Length
 > +	.long	25                      # DIE offset
 > +	.asciz	"main"                  # External Name
 > +	.long	0                       # End Mark
 > +.LpubNames_end1:
 > +	.section	.debug_pubtypes,"",@progbits
 > +	.long	.LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info
 > +.LpubTypes_begin0:
 > +	.short	2                       # DWARF Version
 > +	.long	.Lcu_begin0             # Offset of Compilation Unit Info
 > +	.long	48                      # Compilation Unit Length
 > +	.long	52                      # DIE offset
 > +	.asciz	"int"                   # External Name
 > +	.long	0                       # End Mark
 > +.LpubTypes_end0:
 > +	.long	.LpubTypes_end1-.LpubTypes_begin1 # Length of Public Types Info
 > +.LpubTypes_begin1:
 > +	.short	2                       # DWARF Version
 > +	.long	.Lcu_begin1             # Offset of Compilation Unit Info
 > +	.long	48                      # Compilation Unit Length
 > +	.long	40                      # DIE offset
 > +	.asciz	"int"                   # External Name
 > +	.long	0                       # End Mark
 > +.LpubTypes_end1:
 > +
 > +	.ident	"clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)"
 > +	.ident	"clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)"
 > +	.section	".note.GNU-stack","",@progbits
 > +	.section	.debug_line,"",@progbits
 > +.Lline_table_start0:
 > diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp
 > new file mode 100644
 > index 0000000000..1f23c5b6ee
 > --- /dev/null
 > +++ gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp
 > @@ -0,0 +1,67 @@
 > +# Copyright 2012-2017 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
 > +
 > +# We run objcopy locally to split out the .dwo file.
 > +if [is_remote host] {
 > +    return 0
 > +}
 > +
 > +# 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
 > +}
 > +
 > +standard_testfile .S
 > +
 > +if [build_executable_from_fission_assembler \
 > +	"$testfile.exp" "$binfile" "$srcfile" {nodebug}] {
 > +    return -1
 > +}
 > +
 > +gdb_exit
 > +gdb_start
 > +gdb_reinitialize_dir $srcdir/$subdir
 > +# Make sure we can find the .dwo file, regardless of whether we're
 > +# running in parallel mode.
 > +gdb_test_no_output "set debug-file-directory [file dirname $binfile]" \
 > +    "set debug-file-directory"
 > +gdb_load $binfile
 > +
 > +if ![runto_main] {
 > +    return -1
 > +}
 > +
 > +# Do a few basic things to verify we're finding the DWO debug info.
 > +
 > +gdb_test "ptype main" "type = int \\(\\)"
 > +gdb_test "ptype func" "type = int \\(int\\)"
 > +
 > +gdb_test "frame" "#0 *main \\(\\) at ${testfile}2\\.c:$decimal.*" \
 > +    "frame in main"
 > +
 > +gdb_test "break func" "Breakpoint.*at.* file .*${testfile}1\\.c, line .*"
 > +
 > +gdb_test "continue" "Breakpoint.* func \\(arg=-1\\).*" \
 > +    "continue to func"
 > +
 > +gdb_test "frame" "#0 *func \\(arg=-1\\) at ${testfile}1\\.c:$decimal.*" \
 > +    "frame in func"
 > diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c
 > new file mode 100644
 > index 0000000000..d93e2f912e
 > --- /dev/null
 > +++ gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c
 > @@ -0,0 +1,22 @@
 > +/* This testcase is part of GDB, the GNU debugger.
 > +
 > +   Copyright 2012-2017 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/>.  */
 > +
 > +int
 > +func (int arg)
 > +{
 > +  return arg + 1;
 > +}
 > diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c
 > new file mode 100644
 > index 0000000000..053b3ea141
 > --- /dev/null
 > +++ gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c
 > @@ -0,0 +1,24 @@
 > +/* This testcase is part of GDB, the GNU debugger.
 > +
 > +   Copyright 2012-2017 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/>.  */
 > +
 > +void func ();
 > +
 > +int
 > +main ()
 > +{
 > +  func (-1);
 > +}

-- 
/dje

^ permalink raw reply	[flat|nested] 6+ messages in thread
* [PATCH] Fission support for multiple CUs per DWO file
@ 2017-05-14 16:20 David Blaikie
  0 siblings, 0 replies; 6+ messages in thread
From: David Blaikie @ 2017-05-14 16:20 UTC (permalink / raw)
  To: gdb-patches, dje, Pedro Alves

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

(previous thread: https://sourceware.org/ml/gdb-patches/2017-04/msg00749.html )

LLVM LTO (ThinLTO, full LTO, any other situation where two LLVM
modules with debug info are merged into one/cross imported, etc)
produces multiple CUs in a single object file.

The best guess at how this should be combined with Fission (though it
seem there's any particular plan/spec for this, so it's a bit
off-label, for sure), is that multiple skeletons and dwo CUs should be
produced - but all dwo CUs in one .dwo file (matching (actually
objcopy'd out of) the .o file produced) and all the skeleton CUs
providing that one/same file name as the dwo_name.

Here's a patch to support that and seems to work well with LLVM's output here.

[An extra wrinkle is that LLVM would normally try to use
DW_FORM_ref_addr to refer to entities across the CU boundary (types,
to avoid duplicating type information in each CU, abstract
subprograms/variables to avoid duplication and accurately reflect
cross-CU inlining (eg: a file-local function (namespace static, or
anonymous namespace) in one CU might end inlined into a function in
another CU)). The problem with this is that the DWP format doesn't
carry enough information currently to make this possible (the INFO
column contains only the contribution of a single CU, even if it came
from a multi-CU DWO file - so there's no way to know where to resolve
the ref_addr relative to). So for now I've added a workaround to LLVM
to duplicate rather than using ref_addr in this case. But I hope/plan
to fix this as soon as possible once a reasonable format can be
decided on (see dwarf-discuss mailing list thread) and DWP tool and
GDB are fixed to address that. But for now, multiple CUs in a DWO
without cross-CU references is still valuable]


gdb/ChangeLog:

2017-05-12  David Blaikie  <dblaikie@gmail.com>

        * dwarf2read.c (struct dwo_file): Use a htab of dwo_unit*
(rather than a singular dwo_unit*) to support multiple CUs in the same
way that multiple TUs are supported.
        (static void create_cus_hash_table): Replace create_dwo_cu
with a function for parsing multiple CUs from a DWO file.
        (open_and_init_dwo_file): Use create_cus_hash_table rather
than create_dwo_cu.
        (lookup_dwo_cutu): Lookup CU in the hash table in the dwo_file
with htab_find, rather than comparing the signature to a singleton CU
in the dwo_file.

gdb/testsuite/ChangeLog:

2017-05-12  David Blaikie  <dblaikie@gmail.com>

        * gdb.dwarf2/fission-multi-cu.S: Test containing multiple CUs
in a DWO, built from fission-multi-cu{1,2}.c.
        * gdb.dwarf2/fission-multi-cu.exp: Test similar to
fission-base.exp, except putting 'main' and 'func' in separate CUs
while in the same DWO file.
        * gdb.dwarf2/fission-multi-cu1.c: First CU for the
multi-CU-single-DWO test.
        * gdb.dwarf2/fission-multi-cu2.c: Second CU for the
multi-CU-single-DWO test.

[-- Attachment #2: multiple_cus_per_dwo.diff --]
[-- Type: text/plain, Size: 25983 bytes --]

diff --git gdb/dwarf2read.c gdb/dwarf2read.c
index b58d0fc16e..29eb5a14b2 100644
--- gdb/dwarf2read.c
+++ gdb/dwarf2read.c
@@ -852,12 +852,9 @@ struct dwo_file
      sections (for lack of a better name).  */
   struct dwo_sections sections;
 
-  /* The CU in the file.
-     We only support one because having more than one requires hacking the
-     dwo_name of each to match, which is highly unlikely to happen.
-     Doing this means all TUs can share comp_dir: We also assume that
-     DW_AT_comp_dir across all TUs in a DWO file will be identical.  */
-  struct dwo_unit *cu;
+  /* The CUs in the file.
+     Each element is a struct dwo_unit. */
+  htab_t cus;
 
   /* Table of TUs in the file.
      Each element is a struct dwo_unit.  */
@@ -9702,72 +9699,75 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
 			hex_string (dwo_unit->signature));
 }
 
-/* Create the dwo_unit for the lone CU in DWO_FILE.
-   Note: This function processes DWO files only, not DWP files.  */
-
-static struct dwo_unit *
-create_dwo_cu (struct dwo_file *dwo_file)
+static void create_cus_hash_table (struct dwo_file &dwo_file,
+                                   dwarf2_section_info &section,
+                                   htab_t &cus_htab)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct dwarf2_section_info *section = &dwo_file->sections.info;
+  const struct dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev;
   const gdb_byte *info_ptr, *end_ptr;
-  struct create_dwo_cu_data create_dwo_cu_data;
-  struct dwo_unit *dwo_unit;
 
-  dwarf2_read_section (objfile, section);
-  info_ptr = section->buffer;
+  dwarf2_read_section (objfile, &section);
+  info_ptr = section.buffer;
 
   if (info_ptr == NULL)
-    return NULL;
+    return;
 
   if (dwarf_read_debug)
     {
       fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
-			  get_section_name (section),
-			  get_section_file_name (section));
+			  get_section_name (&section),
+			  get_section_file_name (&section));
     }
 
-  create_dwo_cu_data.dwo_file = dwo_file;
-  dwo_unit = NULL;
-
-  end_ptr = info_ptr + section->size;
+  end_ptr = info_ptr  + section.size;
   while (info_ptr < end_ptr)
     {
       struct dwarf2_per_cu_data per_cu;
+      struct create_dwo_cu_data create_dwo_cu_data;
+      struct dwo_unit *dwo_unit;
+      void **slot;
+      sect_offset sect_off = (sect_offset) (info_ptr - section.buffer);
 
       memset (&create_dwo_cu_data.dwo_unit, 0,
 	      sizeof (create_dwo_cu_data.dwo_unit));
       memset (&per_cu, 0, sizeof (per_cu));
       per_cu.objfile = objfile;
       per_cu.is_debug_types = 0;
-      per_cu.sect_off = sect_offset (info_ptr - section->buffer);
-      per_cu.section = section;
+      per_cu.sect_off = sect_offset (info_ptr - section.buffer);
+      per_cu.section = &section;
+      create_dwo_cu_data.dwo_file = &dwo_file;
 
-      init_cutu_and_read_dies_no_follow (&per_cu, dwo_file,
+      init_cutu_and_read_dies_no_follow (&per_cu, &dwo_file,
 					 create_dwo_cu_reader,
 					 &create_dwo_cu_data);
+      info_ptr += per_cu.length;
 
-      if (create_dwo_cu_data.dwo_unit.dwo_file != NULL)
-	{
-	  /* If we've already found one, complain.  We only support one
-	     because having more than one requires hacking the dwo_name of
-	     each to match, which is highly unlikely to happen.  */
-	  if (dwo_unit != NULL)
-	    {
-	      complaint (&symfile_complaints,
-			 _("Multiple CUs in DWO file %s [in module %s]"),
-			 dwo_file->dwo_name, objfile_name (objfile));
-	      break;
-	    }
+      if (create_dwo_cu_data.dwo_unit.dwo_file == NULL)
+        continue;
 
-	  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
-	  *dwo_unit = create_dwo_cu_data.dwo_unit;
-	}
+      if (cus_htab == NULL)
+        {
+          cus_htab = allocate_dwo_unit_table (objfile);
+        }
 
-      info_ptr += per_cu.length;
-    }
+      dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+      *dwo_unit = create_dwo_cu_data.dwo_unit;
+      slot = htab_find_slot (cus_htab, dwo_unit, INSERT);
+      gdb_assert (slot != NULL);
+      if (*slot != NULL)
+        {
+          const struct dwo_unit *dup_cu = (const struct dwo_unit *) *slot;
+          sect_offset dup_sect_off = dup_cu->sect_off;
 
-  return dwo_unit;
+	  complaint (&symfile_complaints,
+		     _("debug cu entry at offset 0x%x is duplicate to"
+		       " the entry at offset 0x%x, signature %s"),
+		     to_underlying (sect_off), to_underlying (dup_sect_off),
+		     hex_string (dwo_unit->signature));
+        }
+      *slot = (void *) dwo_unit;
+    }
 }
 
 /* DWP file .debug_{cu,tu}_index section format:
@@ -10772,7 +10772,7 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
   bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections,
 			 &dwo_file->sections);
 
-  dwo_file->cu = create_dwo_cu (dwo_file);
+  create_cus_hash_table (*dwo_file, dwo_file->sections.info, dwo_file->cus);
 
   create_debug_types_hash_table (dwo_file, dwo_file->sections.types,
 				 dwo_file->tus);
@@ -11139,10 +11139,13 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
 	      dwo_cutu
 		= (struct dwo_unit *) htab_find (dwo_file->tus, &find_dwo_cutu);
 	    }
-	  else if (!is_debug_types && dwo_file->cu)
+	  else if (!is_debug_types && dwo_file->cus)
 	    {
-	      if (signature == dwo_file->cu->signature)
-		dwo_cutu = dwo_file->cu;
+              struct dwo_unit find_dwo_cutu;
+
+              memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
+              find_dwo_cutu.signature = signature;
+              dwo_cutu = (struct dwo_unit *) htab_find (dwo_file->cus, &find_dwo_cutu);
 	    }
 
 	  if (dwo_cutu != NULL)
diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu.S gdb/testsuite/gdb.dwarf2/fission-multi-cu.S
new file mode 100644
index 0000000000..d09a7e543d
--- /dev/null
+++ gdb/testsuite/gdb.dwarf2/fission-multi-cu.S
@@ -0,0 +1,374 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2017 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/>.
+
+   This file was created by doing:
+
+   clang fission-multi-cu*.c -g -fno-split-dwarf-inlining -emit-llvm -S -c
+   llvm-link fission-multi-cu*.ll -S -o fission-multi-cu.ll
+   clang-tot fission-multi-cu.ll -gsplit-dwarf -S
+
+   and then massaging the output.
+*/
+	.text
+	.file	"llvm-link"
+	.globl	func
+	.p2align	4, 0x90
+	.type	func,@function
+func:                                   # @func
+.Lfunc_begin0:
+	.file	1 "fission-multi-cu1.c"
+	.loc	1 20 0                  # fission-multi-cu1.c:20:0
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	movl	%edi, -4(%rbp)
+	.loc	1 21 10 prologue_end    # fission-multi-cu1.c:21:10
+	movl	-4(%rbp), %edi
+	.loc	1 21 14 is_stmt 0       # fission-multi-cu1.c:21:14
+	addl	$1, %edi
+	.loc	1 21 3                  # fission-multi-cu1.c:21:3
+	movl	%edi, %eax
+	popq	%rbp
+	retq
+.Lfunc_end0:
+	.size	func, .Lfunc_end0-func
+	.cfi_endproc
+
+	.globl	main
+	.p2align	4, 0x90
+	.type	main,@function
+main:                                   # @main
+.Lfunc_begin1:
+	.file	2 "fission-multi-cu2.c"
+	.loc	2 23 0 is_stmt 1        # fission-multi-cu2.c:23:0
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	movl	$4294967295, %edi       # imm = 0xFFFFFFFF
+	.loc	2 24 3 prologue_end     # fission-multi-cu2.c:24:3
+	movb	$0, %al
+	callq	func
+	xorl	%eax, %eax
+	.loc	2 25 1                  # fission-multi-cu2.c:25:1
+	popq	%rbp
+	retq
+.Lfunc_end1:
+	.size	main, .Lfunc_end1-main
+	.cfi_endproc
+
+	.section	.debug_str,"MS",@progbits,1
+.Lskel_string0:
+	.asciz	"fission-multi-cu.dwo"  # string offset=0
+.Lskel_string1:
+	.asciz	"/tmp/src/gdb/testsuite" # string offset=21
+	.section	.debug_loc.dwo,"",@progbits
+	.section	.debug_abbrev,"",@progbits
+	.byte	1                       # Abbreviation Code
+	.byte	17                      # DW_TAG_compile_unit
+	.byte	0                       # DW_CHILDREN_no
+	.byte	16                      # DW_AT_stmt_list
+	.byte	23                      # DW_FORM_sec_offset
+	.ascii	"\260B"                 # DW_AT_GNU_dwo_name
+	.byte	14                      # DW_FORM_strp
+	.byte	27                      # DW_AT_comp_dir
+	.byte	14                      # DW_FORM_strp
+	.ascii	"\261B"                 # DW_AT_GNU_dwo_id
+	.byte	7                       # DW_FORM_data8
+	.ascii	"\263B"                 # DW_AT_GNU_addr_base
+	.byte	23                      # DW_FORM_sec_offset
+	.byte	17                      # DW_AT_low_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	18                      # DW_AT_high_pc
+	.byte	6                       # DW_FORM_data4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	0                       # EOM(3)
+	.section	.debug_info,"",@progbits
+.Lcu_begin0:
+	.long	44                      # Length of Unit
+	.short	4                       # DWARF version number
+	.long	.debug_abbrev           # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+	.long	.Lline_table_start0     # DW_AT_stmt_list
+	.long	.Lskel_string0          # DW_AT_GNU_dwo_name
+	.long	.Lskel_string1          # DW_AT_comp_dir
+	.quad	7615852067747431413     # DW_AT_GNU_dwo_id
+	.long	.debug_addr             # DW_AT_GNU_addr_base
+	.quad	.Lfunc_begin0           # DW_AT_low_pc
+	.long	.Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+.Lcu_begin1:
+	.long	44                      # Length of Unit
+	.short	4                       # DWARF version number
+	.long	.debug_abbrev           # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+	.long	.Lline_table_start0     # DW_AT_stmt_list
+	.long	.Lskel_string0          # DW_AT_GNU_dwo_name
+	.long	.Lskel_string1          # DW_AT_comp_dir
+	.quad	2037650261599692324     # DW_AT_GNU_dwo_id
+	.long	.debug_addr             # DW_AT_GNU_addr_base
+	.quad	.Lfunc_begin1           # DW_AT_low_pc
+	.long	.Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+	.section	.debug_ranges,"",@progbits
+	.section	.debug_macinfo,"",@progbits
+.Lcu_macro_begin1:
+.Lcu_macro_begin3:
+	.byte	0                       # End Of Macro List Mark
+	.section	.debug_str.dwo,"MS",@progbits,1
+.Linfo_string0:
+	.asciz	"fission-multi-cu.dwo"  # string offset=0
+.Linfo_string1:
+	.asciz	"clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)" # string offset=21
+.Linfo_string2:
+	.asciz	"fission-multi-cu1.c" # string offset=76
+.Linfo_string3:
+	.asciz	"fission-multi-cu2.c" # string offset=96
+.Linfo_string4:
+	.asciz	"func"                  # string offset=116
+.Linfo_string5:
+	.asciz	"int"                   # string offset=121
+.Linfo_string6:
+	.asciz	"main"                  # string offset=125
+.Linfo_string7:
+	.asciz	"arg"                   # string offset=130
+	.section	.debug_str_offsets.dwo,"",@progbits
+	.long	0
+	.long	21
+	.long	76
+	.long	96
+	.long	116
+	.long	121
+	.long	125
+	.long	130
+	.section	.debug_info.dwo,"",@progbits
+	.long	53                      # Length of Unit
+	.short	4                       # DWARF version number
+	.long	0                       # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] 0xb:0x2e DW_TAG_compile_unit
+	.byte	0                       # DW_AT_GNU_dwo_name
+	.byte	1                       # DW_AT_producer
+	.short	12                      # DW_AT_language
+	.byte	2                       # DW_AT_name
+	.quad	7615852067747431413     # DW_AT_GNU_dwo_id
+	.byte	2                       # Abbrev [2] 0x19:0x1b DW_TAG_subprogram
+	.byte	0                       # DW_AT_low_pc
+	.long	.Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+	.byte	1                       # DW_AT_frame_base
+	.byte	86
+	.byte	4                       # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	19                      # DW_AT_decl_line
+                                        # DW_AT_prototyped
+	.long	52                      # DW_AT_type
+                                        # DW_AT_external
+	.byte	3                       # Abbrev [3] 0x28:0xb DW_TAG_formal_parameter
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	124
+	.byte	7                       # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	19                      # DW_AT_decl_line
+	.long	52                      # DW_AT_type
+	.byte	0                       # End Of Children Mark
+	.byte	4                       # Abbrev [4] 0x34:0x4 DW_TAG_base_type
+	.byte	5                       # DW_AT_name
+	.byte	5                       # DW_AT_encoding
+	.byte	4                       # DW_AT_byte_size
+	.byte	0                       # End Of Children Mark
+	.long	41                      # Length of Unit
+	.short	4                       # DWARF version number
+	.long	0                       # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] 0xb:0x22 DW_TAG_compile_unit
+	.byte	0                       # DW_AT_GNU_dwo_name
+	.byte	1                       # DW_AT_producer
+	.short	12                      # DW_AT_language
+	.byte	3                       # DW_AT_name
+	.quad	2037650261599692324     # DW_AT_GNU_dwo_id
+	.byte	5                       # Abbrev [5] 0x19:0xf DW_TAG_subprogram
+	.byte	1                       # DW_AT_low_pc
+	.long	.Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+	.byte	1                       # DW_AT_frame_base
+	.byte	86
+	.byte	6                       # DW_AT_name
+	.byte	2                       # DW_AT_decl_file
+	.byte	22                      # DW_AT_decl_line
+	.long	40                      # DW_AT_type
+                                        # DW_AT_external
+	.byte	4                       # Abbrev [4] 0x28:0x4 DW_TAG_base_type
+	.byte	5                       # DW_AT_name
+	.byte	5                       # DW_AT_encoding
+	.byte	4                       # DW_AT_byte_size
+	.byte	0                       # End Of Children Mark
+	.section	.debug_abbrev.dwo,"",@progbits
+	.byte	1                       # Abbreviation Code
+	.byte	17                      # DW_TAG_compile_unit
+	.byte	1                       # DW_CHILDREN_yes
+	.ascii	"\260B"                 # DW_AT_GNU_dwo_name
+	.ascii	"\202>"                 # DW_FORM_GNU_str_index
+	.byte	37                      # DW_AT_producer
+	.ascii	"\202>"                 # DW_FORM_GNU_str_index
+	.byte	19                      # DW_AT_language
+	.byte	5                       # DW_FORM_data2
+	.byte	3                       # DW_AT_name
+	.ascii	"\202>"                 # DW_FORM_GNU_str_index
+	.ascii	"\261B"                 # DW_AT_GNU_dwo_id
+	.byte	7                       # DW_FORM_data8
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	2                       # Abbreviation Code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	17                      # DW_AT_low_pc
+	.ascii	"\201>"                 # DW_FORM_GNU_addr_index
+	.byte	18                      # DW_AT_high_pc
+	.byte	6                       # DW_FORM_data4
+	.byte	64                      # DW_AT_frame_base
+	.byte	24                      # DW_FORM_exprloc
+	.byte	3                       # DW_AT_name
+	.ascii	"\202>"                 # DW_FORM_GNU_str_index
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	39                      # DW_AT_prototyped
+	.byte	25                      # DW_FORM_flag_present
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	63                      # DW_AT_external
+	.byte	25                      # DW_FORM_flag_present
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	3                       # Abbreviation Code
+	.byte	5                       # DW_TAG_formal_parameter
+	.byte	0                       # DW_CHILDREN_no
+	.byte	2                       # DW_AT_location
+	.byte	24                      # DW_FORM_exprloc
+	.byte	3                       # DW_AT_name
+	.ascii	"\202>"                 # DW_FORM_GNU_str_index
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	4                       # Abbreviation Code
+	.byte	36                      # DW_TAG_base_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.ascii	"\202>"                 # DW_FORM_GNU_str_index
+	.byte	62                      # DW_AT_encoding
+	.byte	11                      # DW_FORM_data1
+	.byte	11                      # DW_AT_byte_size
+	.byte	11                      # DW_FORM_data1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	5                       # Abbreviation Code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	0                       # DW_CHILDREN_no
+	.byte	17                      # DW_AT_low_pc
+	.ascii	"\201>"                 # DW_FORM_GNU_addr_index
+	.byte	18                      # DW_AT_high_pc
+	.byte	6                       # DW_FORM_data4
+	.byte	64                      # DW_AT_frame_base
+	.byte	24                      # DW_FORM_exprloc
+	.byte	3                       # DW_AT_name
+	.ascii	"\202>"                 # DW_FORM_GNU_str_index
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	63                      # DW_AT_external
+	.byte	25                      # DW_FORM_flag_present
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	0                       # EOM(3)
+	.section	.debug_line.dwo,"",@progbits
+.Ltmp4:
+	.long	(.Ltmp5-.Ltmp4)-4
+	.short	2
+	.long	(.Ltmp6-.Ltmp4)-10
+	.byte	1
+	.byte	1
+	.byte	-5
+	.byte	14
+	.byte	1
+	.byte	0
+	.byte	0
+.Ltmp6:
+.Ltmp5:
+	.section	.debug_addr,"",@progbits
+	.quad	.Lfunc_begin0
+	.quad	.Lfunc_begin1
+	.section	.debug_pubnames,"",@progbits
+	.long	.LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info
+.LpubNames_begin0:
+	.short	2                       # DWARF Version
+	.long	.Lcu_begin0             # Offset of Compilation Unit Info
+	.long	48                      # Compilation Unit Length
+	.long	25                      # DIE offset
+	.asciz	"func"                  # External Name
+	.long	0                       # End Mark
+.LpubNames_end0:
+	.long	.LpubNames_end1-.LpubNames_begin1 # Length of Public Names Info
+.LpubNames_begin1:
+	.short	2                       # DWARF Version
+	.long	.Lcu_begin1             # Offset of Compilation Unit Info
+	.long	48                      # Compilation Unit Length
+	.long	25                      # DIE offset
+	.asciz	"main"                  # External Name
+	.long	0                       # End Mark
+.LpubNames_end1:
+	.section	.debug_pubtypes,"",@progbits
+	.long	.LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info
+.LpubTypes_begin0:
+	.short	2                       # DWARF Version
+	.long	.Lcu_begin0             # Offset of Compilation Unit Info
+	.long	48                      # Compilation Unit Length
+	.long	52                      # DIE offset
+	.asciz	"int"                   # External Name
+	.long	0                       # End Mark
+.LpubTypes_end0:
+	.long	.LpubTypes_end1-.LpubTypes_begin1 # Length of Public Types Info
+.LpubTypes_begin1:
+	.short	2                       # DWARF Version
+	.long	.Lcu_begin1             # Offset of Compilation Unit Info
+	.long	48                      # Compilation Unit Length
+	.long	40                      # DIE offset
+	.asciz	"int"                   # External Name
+	.long	0                       # End Mark
+.LpubTypes_end1:
+
+	.ident	"clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)"
+	.ident	"clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)"
+	.section	".note.GNU-stack","",@progbits
+	.section	.debug_line,"",@progbits
+.Lline_table_start0:
diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp
new file mode 100644
index 0000000000..1f23c5b6ee
--- /dev/null
+++ gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp
@@ -0,0 +1,67 @@
+# Copyright 2012-2017 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
+
+# We run objcopy locally to split out the .dwo file.
+if [is_remote host] {
+    return 0
+}
+
+# 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
+}
+
+standard_testfile .S
+
+if [build_executable_from_fission_assembler \
+	"$testfile.exp" "$binfile" "$srcfile" {nodebug}] {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+# Make sure we can find the .dwo file, regardless of whether we're
+# running in parallel mode.
+gdb_test_no_output "set debug-file-directory [file dirname $binfile]" \
+    "set debug-file-directory"
+gdb_load $binfile
+
+if ![runto_main] {
+    return -1
+}
+
+# Do a few basic things to verify we're finding the DWO debug info.
+
+gdb_test "ptype main" "type = int \\(\\)"
+gdb_test "ptype func" "type = int \\(int\\)"
+
+gdb_test "frame" "#0 *main \\(\\) at ${testfile}2\\.c:$decimal.*" \
+    "frame in main"
+
+gdb_test "break func" "Breakpoint.*at.* file .*${testfile}1\\.c, line .*"
+
+gdb_test "continue" "Breakpoint.* func \\(arg=-1\\).*" \
+    "continue to func"
+
+gdb_test "frame" "#0 *func \\(arg=-1\\) at ${testfile}1\\.c:$decimal.*" \
+    "frame in func"
diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c
new file mode 100644
index 0000000000..d93e2f912e
--- /dev/null
+++ gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2017 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/>.  */
+
+int
+func (int arg)
+{
+  return arg + 1;
+}
diff --git gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c
new file mode 100644
index 0000000000..053b3ea141
--- /dev/null
+++ gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2017 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/>.  */
+
+void func ();
+
+int
+main ()
+{
+  func (-1);
+}

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

end of thread, other threads:[~2017-07-14 17:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-22 18:01 [PATCH] Fission support for multiple CUs per DWO file Doug Evans via gdb-patches
2017-06-01 23:33 ` David Blaikie
2017-06-27 18:52   ` David Blaikie
2017-06-28  0:56     ` Doug Evans via gdb-patches
2017-07-14 17:10       ` Yao Qi
  -- strict thread matches above, loose matches on Subject: below --
2017-05-14 16:20 David Blaikie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).