From patchwork Tue Apr 12 00:31:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: G Helffrich X-Patchwork-Id: 11697 Received: (qmail 112182 invoked by alias); 12 Apr 2016 00:31:28 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 112171 invoked by uid 89); 12 Apr 2016 00:31:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW, SPF_PASS, T_FILL_THIS_FORM_SHORT autolearn=no version=3.3.2 spammy=crosscheck, cross-check, relocate, *attr X-HELO: mail-pf0-f193.google.com Received: from mail-pf0-f193.google.com (HELO mail-pf0-f193.google.com) (209.85.192.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 12 Apr 2016 00:31:24 +0000 Received: by mail-pf0-f193.google.com with SMTP id r187so188110pfr.2 for ; Mon, 11 Apr 2016 17:31:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:subject:date:message-id:cc:to:mime-version; bh=kvLbZ7QmeFZi9LMPWDd7vZqjE1emXDgEG+PKiKyoV9w=; b=CWP5EYazN231qPx37dsImxAChgcH7Bjx5+rb0AlO0z14gzYM3DR0WO6BV2PtLE2KYX /JVsrkMdCnuygSW6su0aANBtGEvCxYyZkh84u66fUOFX+r2qMflb1rXz3CiKOe/wNtmy DgG93zM+QGvE/LF+XmD4Zp/TUR+IjgB7ySz3DU70L547iyGd/ULnBCvEOJ9GhWin/NW6 2onsJIV2HBL5njaNhWUBsrBDKhToXr0oRy2IS+jNTS6aPfvKCqS1HstooiqnYIPYeSNn my4qH3prEl59QQEMRcubyFxbNt/wGfa0vqoNgv4PVYxSoT4o2GXWx+3vsvUyw98CDyeg hufQ== X-Gm-Message-State: AOPr4FVaW0HK8U2+D4y9JgqAfg1JZtzmQqdoaJgr4vAdgFv4lhpcjk0kpOg3GGr8o5/cIw== X-Received: by 10.98.18.71 with SMTP id a68mr484992pfj.41.1460421083166; Mon, 11 Apr 2016 17:31:23 -0700 (PDT) Received: from [10.0.0.5] (NE1527lan1.rev.em-net.ne.jp. [210.237.126.1]) by smtp.gmail.com with ESMTPSA id rw2sm38799263pab.30.2016.04.11.17.31.21 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 11 Apr 2016 17:31:22 -0700 (PDT) From: G Helffrich Subject: [PATCH v2] gdb: dwarf2read: implement handling of variables in Fortran common block Date: Tue, 12 Apr 2016 09:31:18 +0900 Message-Id: <13D2DB40-8745-4CF0-BA56-C88D4741610C@gmail.com> Cc: Luis Machado To: gdb-patches@sourceware.org Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) This patch allows the gdb DWARF reader to handle variables located in Fortran common blocks. This fixes 20 unexpected failures in the gdb.fortran testsuite with host, target and build triplet x86_64-apple-darwin13.4.0 with gfortran 4.9.2. Re-posted as requested with patch file attached. Revised from original post to prevent double relocation. 2015-04-12 George Helffrich * dwarf2read.c (read_common_block): Relocate symbols in Fortran common blocks properly, and avoid double relocation. (read_new_symbol_full): Don't discard zero-offset symbols in Fortran common blocks. (_initialize_dwarf2_read): Add debug diagnostic print for common symbols. * psymtab.c (print_partial_symbols): Recognize and print COMMON_BLOCK_DOMAIN. * symmisc.c (print_symbol): Recognize and dump LOC_COMMON_BLOCK. ——— ——— --- dwarf2read.c.orig 2015-02-21 02:11:44.000000000 +0900 +++ dwarf2read.c 2016-04-06 18:50:34.000000000 +0900 @@ -84,6 +84,9 @@ static unsigned int dwarf2_read_debug = /* When non-zero, dump DIEs after they are read in. */ static unsigned int dwarf2_die_debug = 0; +/* When non-zero, report definition of common block variables. */ +static unsigned int dwarf2_common_debug = 0; + /* When non-zero, cross-check physname against demangler. */ static int check_physname = 0; @@ -13877,6 +13880,57 @@ static void read_common_block (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *attr; + CORE_ADDR baseaddr; + struct program_space *psp; + struct minimal_symbol *msym = NULL; + struct objfile *objfile = cu->objfile; + struct gdbarch *gdbarch = get_objfile_arch (objfile); + const char *name; + + attr = dwarf2_attr (die, DW_AT_name, cu); + name = dwarf2_compute_name (NULL, die, cu, 1); + if (dwarf2_common_debug) + { + fprintf_unfiltered (gdb_stdlog, + "Read common blk %s (%s)\n", + DW_STRING(attr), name); + } + ALL_PSPACES (psp) + ALL_PSPACE_OBJFILES (psp, objfile) + if (objfile->flags & OBJF_MAINLINE) goto found; +found: + if (objfile->flags & OBJF_MAINLINE) + ALL_OBJFILE_MSYMBOLS (objfile, msym) + { + struct obj_section *section = MSYMBOL_OBJ_SECTION (objfile, msym); + + if (0 == strcmp(MSYMBOL_LINKAGE_NAME (msym), name)) + { + if (dwarf2_common_debug) + { + fprintf_unfiltered (gdb_stdlog, " Found %s at ", name); + fputs_filtered (paddress (gdbarch, + MSYMBOL_VALUE_ADDRESS (objfile, msym)), + gdb_stdlog); + } + if (section && dwarf2_common_debug) + { + if (section->the_bfd_section != NULL) + fprintf_filtered (gdb_stdlog, " section %s", + bfd_section_name (objfile->obfd, + section->the_bfd_section)); + else + fprintf_filtered (gdb_stdlog, " spurious section %ld", + (long) (section - objfile->sections)); + } + if (dwarf2_common_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); + + /* Found base of common, now use it to relocate symbols in it */ + baseaddr = MSYMBOL_VALUE_ADDRESS (objfile, msym); + break; + } + } attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) @@ -13906,6 +13960,7 @@ read_common_block (struct die_info *die, size_t n_entries = 0, size; struct common_block *common_block; struct symbol *sym; + int needs_reloc = 0; for (child_die = die->child; child_die && child_die->tag; @@ -13929,6 +13984,9 @@ read_common_block (struct die_info *die, { struct attribute *member_loc; + if (common_block->n_entries == 0) + needs_reloc = SYMBOL_VALUE_ADDRESS (sym) == 0; + common_block->contents[common_block->n_entries++] = sym; member_loc = dwarf2_attr (child_die, DW_AT_data_member_location, @@ -13958,6 +14016,34 @@ read_common_block (struct die_info *die, else dwarf2_complex_location_expr_complaint (); } + + if (dwarf2_common_debug) + { + struct attribute *name = dwarf2_attr (child_die, DW_AT_name, cu); + fprintf_unfiltered (gdb_stdlog, + " Define common blk var %s at ", + DW_STRING(name)); + fputs_filtered (paddress (gdbarch, + SYMBOL_VALUE_ADDRESS (sym)), + gdb_stdlog); + if (needs_reloc) + { + fputs_filtered (" -> ", gdb_stdlog); + if (msym) + fputs_filtered (paddress (gdbarch, + SYMBOL_VALUE_ADDRESS (sym) + + baseaddr), + gdb_stdlog); + else + fputs_filtered ("(unknown)", gdb_stdlog); + } + fputs_filtered ("\n", gdb_stdlog); + } + + /* Relocate symbol in common block */ + if (msym && needs_reloc) + SYMBOL_VALUE_ADDRESS (sym) += baseaddr; + } } @@ -18165,6 +18251,8 @@ new_symbol_full (struct die_info *die, s attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) { + unsigned int fortran_common_symbol = 0; + var_decode_location (attr, sym, cu); attr2 = dwarf2_attr (die, DW_AT_external, cu); @@ -18172,16 +18260,23 @@ new_symbol_full (struct die_info *die, s scope by DW_TAG_common_block. */ if (cu->language == language_fortran && die->parent && die->parent->tag == DW_TAG_common_block) - attr2 = NULL; + { + attr2 = NULL; + fortran_common_symbol = 1; + } if (SYMBOL_CLASS (sym) == LOC_STATIC && SYMBOL_VALUE_ADDRESS (sym) == 0 + && !fortran_common_symbol && !dwarf2_per_objfile->has_section_at_zero) { /* When a static variable is eliminated by the linker, the corresponding debug information is not stripped out, but the variable address is set to null; - do not add such variables into symbol table. */ + do not add such variables into symbol table. + + An exception is Fortran, for which the first symbol + in a common block will have address/offset 0. */ } else if (attr2 && (DW_UNSND (attr2) != 0)) { @@ -23195,6 +23290,16 @@ The value is the maximum depth to print. NULL, &setdebuglist, &showdebuglist); + add_setshow_zuinteger_cmd ("dwarf2-common", + no_class, &dwarf2_common_debug, _("\ +Set debugging of dwarf2 common block handling."), _("\ +Show debugging of dwarf2 common block handling."), _("\ +When enabled (non-zero), common block variables are printed as they are\n\ +are relocated to their position in the common section."), + NULL, + NULL, + &setdebuglist, &showdebuglist); + add_setshow_boolean_cmd ("check-physname", no_class, &check_physname, _("\ Set cross-checking of \"physname\" code against demangler."), _("\ Show cross-checking of \"physname\" code against demangler."), _("\ --- symmisc.c.orig 2015-02-21 02:11:44.000000000 +0900 +++ symmisc.c 2016-03-27 18:46:17.000000000 +0900 @@ -626,6 +626,15 @@ print_symbol (void *args) fprintf_filtered (outfile, "optimized out"); break; + case LOC_COMMON_BLOCK: + fprintf_filtered (outfile, "common block storage"); + + if (section) + fprintf_filtered (outfile, " section %s", + bfd_section_name (section->the_bfd_section->owner, + section->the_bfd_section)); + break; + default: fprintf_filtered (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol)); --- psymtab.c.orig 2015-02-21 02:11:44.000000000 +0900 +++ psymtab.c 2016-03-27 18:13:25.000000000 +0900 @@ -915,6 +915,9 @@ print_partial_symbols (struct gdbarch *g case LABEL_DOMAIN: fputs_filtered ("label domain, ", outfile); break; + case COMMON_BLOCK_DOMAIN: + fputs_filtered ("common block domain, ", outfile); + break; default: fputs_filtered (", ", outfile); break; G Helffrich ghfbsd@gmail.com --- dwarf2read.c.orig 2015-02-21 02:11:44.000000000 +0900 +++ dwarf2read.c 2016-04-06 18:50:34.000000000 +0900 @@ -84,6 +84,9 @@ static unsigned int dwarf2_read_debug = /* When non-zero, dump DIEs after they are read in. */ static unsigned int dwarf2_die_debug = 0; +/* When non-zero, report definition of common block variables. */ +static unsigned int dwarf2_common_debug = 0; + /* When non-zero, cross-check physname against demangler. */ static int check_physname = 0; @@ -13877,6 +13880,57 @@ static void read_common_block (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *attr; + CORE_ADDR baseaddr; + struct program_space *psp; + struct minimal_symbol *msym = NULL; + struct objfile *objfile = cu->objfile; + struct gdbarch *gdbarch = get_objfile_arch (objfile); + const char *name; + + attr = dwarf2_attr (die, DW_AT_name, cu); + name = dwarf2_compute_name (NULL, die, cu, 1); + if (dwarf2_common_debug) + { + fprintf_unfiltered (gdb_stdlog, + "Read common blk %s (%s)\n", + DW_STRING(attr), name); + } + ALL_PSPACES (psp) + ALL_PSPACE_OBJFILES (psp, objfile) + if (objfile->flags & OBJF_MAINLINE) goto found; +found: + if (objfile->flags & OBJF_MAINLINE) + ALL_OBJFILE_MSYMBOLS (objfile, msym) + { + struct obj_section *section = MSYMBOL_OBJ_SECTION (objfile, msym); + + if (0 == strcmp(MSYMBOL_LINKAGE_NAME (msym), name)) + { + if (dwarf2_common_debug) + { + fprintf_unfiltered (gdb_stdlog, " Found %s at ", name); + fputs_filtered (paddress (gdbarch, + MSYMBOL_VALUE_ADDRESS (objfile, msym)), + gdb_stdlog); + } + if (section && dwarf2_common_debug) + { + if (section->the_bfd_section != NULL) + fprintf_filtered (gdb_stdlog, " section %s", + bfd_section_name (objfile->obfd, + section->the_bfd_section)); + else + fprintf_filtered (gdb_stdlog, " spurious section %ld", + (long) (section - objfile->sections)); + } + if (dwarf2_common_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); + + /* Found base of common, now use it to relocate symbols in it */ + baseaddr = MSYMBOL_VALUE_ADDRESS (objfile, msym); + break; + } + } attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) @@ -13906,6 +13960,7 @@ read_common_block (struct die_info *die, size_t n_entries = 0, size; struct common_block *common_block; struct symbol *sym; + int needs_reloc = 0; for (child_die = die->child; child_die && child_die->tag; @@ -13929,6 +13984,9 @@ read_common_block (struct die_info *die, { struct attribute *member_loc; + if (common_block->n_entries == 0) + needs_reloc = SYMBOL_VALUE_ADDRESS (sym) == 0; + common_block->contents[common_block->n_entries++] = sym; member_loc = dwarf2_attr (child_die, DW_AT_data_member_location, @@ -13958,6 +14016,34 @@ read_common_block (struct die_info *die, else dwarf2_complex_location_expr_complaint (); } + + if (dwarf2_common_debug) + { + struct attribute *name = dwarf2_attr (child_die, DW_AT_name, cu); + fprintf_unfiltered (gdb_stdlog, + " Define common blk var %s at ", + DW_STRING(name)); + fputs_filtered (paddress (gdbarch, + SYMBOL_VALUE_ADDRESS (sym)), + gdb_stdlog); + if (needs_reloc) + { + fputs_filtered (" -> ", gdb_stdlog); + if (msym) + fputs_filtered (paddress (gdbarch, + SYMBOL_VALUE_ADDRESS (sym) + + baseaddr), + gdb_stdlog); + else + fputs_filtered ("(unknown)", gdb_stdlog); + } + fputs_filtered ("\n", gdb_stdlog); + } + + /* Relocate symbol in common block */ + if (msym && needs_reloc) + SYMBOL_VALUE_ADDRESS (sym) += baseaddr; + } } @@ -18165,6 +18251,8 @@ new_symbol_full (struct die_info *die, s attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) { + unsigned int fortran_common_symbol = 0; + var_decode_location (attr, sym, cu); attr2 = dwarf2_attr (die, DW_AT_external, cu); @@ -18172,16 +18260,23 @@ new_symbol_full (struct die_info *die, s scope by DW_TAG_common_block. */ if (cu->language == language_fortran && die->parent && die->parent->tag == DW_TAG_common_block) - attr2 = NULL; + { + attr2 = NULL; + fortran_common_symbol = 1; + } if (SYMBOL_CLASS (sym) == LOC_STATIC && SYMBOL_VALUE_ADDRESS (sym) == 0 + && !fortran_common_symbol && !dwarf2_per_objfile->has_section_at_zero) { /* When a static variable is eliminated by the linker, the corresponding debug information is not stripped out, but the variable address is set to null; - do not add such variables into symbol table. */ + do not add such variables into symbol table. + + An exception is Fortran, for which the first symbol + in a common block will have address/offset 0. */ } else if (attr2 && (DW_UNSND (attr2) != 0)) { @@ -23195,6 +23290,16 @@ The value is the maximum depth to print. NULL, &setdebuglist, &showdebuglist); + add_setshow_zuinteger_cmd ("dwarf2-common", + no_class, &dwarf2_common_debug, _("\ +Set debugging of dwarf2 common block handling."), _("\ +Show debugging of dwarf2 common block handling."), _("\ +When enabled (non-zero), common block variables are printed as they are\n\ +are relocated to their position in the common section."), + NULL, + NULL, + &setdebuglist, &showdebuglist); + add_setshow_boolean_cmd ("check-physname", no_class, &check_physname, _("\ Set cross-checking of \"physname\" code against demangler."), _("\ Show cross-checking of \"physname\" code against demangler."), _("\ --- symmisc.c.orig 2015-02-21 02:11:44.000000000 +0900 +++ symmisc.c 2016-03-27 18:46:17.000000000 +0900 @@ -626,6 +626,15 @@ print_symbol (void *args) fprintf_filtered (outfile, "optimized out"); break; + case LOC_COMMON_BLOCK: + fprintf_filtered (outfile, "common block storage"); + + if (section) + fprintf_filtered (outfile, " section %s", + bfd_section_name (section->the_bfd_section->owner, + section->the_bfd_section)); + break; + default: fprintf_filtered (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol)); --- psymtab.c.orig 2015-02-21 02:11:44.000000000 +0900 +++ psymtab.c 2016-03-27 18:13:25.000000000 +0900 @@ -915,6 +915,9 @@ print_partial_symbols (struct gdbarch *g case LABEL_DOMAIN: fputs_filtered ("label domain, ", outfile); break; + case COMMON_BLOCK_DOMAIN: + fputs_filtered ("common block domain, ", outfile); + break; default: fputs_filtered (", ", outfile); break;