--- 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 ("<invalid domain>, ", outfile);
          break;
