--- 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;