Index: cpukit/include/rtems/rtl/rtl-obj.h
===================================================================
--- cpukit/include/rtems/rtl/rtl-obj.h	(revision 52c7cb1fdc69a032ca2859e1704412dc489ea0ac)
+++ cpukit/include/rtems/rtl/rtl-obj.h	(revision 803eac954ed7a3481c6af9b020d5d25419d3a19d)
@@ -295,4 +295,21 @@
 
 /**
+ * Align the size to the next alignment point. Assume the alignment is a
+ * positive integral power of 2 if not 0 or 1. If 0 or 1 then there is no
+ * alignment.
+ *
+ * @param offset Offset to align up from.
+ * @param alignment The alignment.
+ * @return size_t Aligned offset.
+ */
+static inline size_t rtems_rtl_obj_align (size_t   offset,
+                                          uint32_t alignment)
+{
+  if ((alignment > 1) && ((offset & (alignment - 1)) != 0))
+    offset = (offset + alignment) & ~(alignment - 1);
+  return offset;
+}
+
+/**
  * Allocate an object structure on the heap.
  *
@@ -411,4 +428,20 @@
 
 /**
+ * Find a section given a section's mask. The index is the section after which
+ * the mask is matched. An index of -1 starts the search from the beginning of
+ * the section list. You can find multiple matches for a mask by passing the
+ * index of the last section that matched the mask on a subsequent call.
+ *
+ * @param obj The object file's descriptor.
+ * @param index The section's index to start searching from, -1 for the start.
+ * @param mask The section's mask to match against the section's flags.
+ * @retval NULL The section was not found.
+ * @return rtems_rtl_obj_sect_t* The found section.
+ */
+rtems_rtl_obj_sect* rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
+                                                        int                  index,
+                                                        uint32_t             mask);
+
+/**
  * The text section size. Only use once all the sections has been added. It
  * includes alignments between sections that are part of the object's text
Index: cpukit/libdl/rtl-elf.c
===================================================================
--- cpukit/libdl/rtl-elf.c	(revision 52c7cb1fdc69a032ca2859e1704412dc489ea0ac)
+++ cpukit/libdl/rtl-elf.c	(revision 803eac954ed7a3481c6af9b020d5d25419d3a19d)
@@ -73,5 +73,6 @@
   rtems_rtl_obj_sect* sect;
 
-  if (ELF_ST_TYPE(sym->st_info) == STT_NOTYPE)
+  if (ELF_ST_TYPE(sym->st_info) == STT_NOTYPE ||
+      sym->st_shndx == SHN_COMMON)
   {
     /*
@@ -186,7 +187,8 @@
 
     /*
-     * Only need the name of the symbol if global.
+     * Only need the name of the symbol if global or a common symbol.
      */
-    if (ELF_ST_TYPE (sym.st_info) == STT_NOTYPE)
+    if (ELF_ST_TYPE (sym.st_info) == STT_NOTYPE ||
+        sym.st_shndx == SHN_COMMON)
     {
       size_t len;
@@ -338,4 +340,66 @@
 }
 
+/**
+ * Common symbol iterator data.
+ */
+typedef struct
+{
+  size_t   size;      /**< The size of the common section */
+  uint32_t alignment; /**< The alignment of the common section. */
+} rtems_rtl_elf_common_data;
+
+static bool
+rtems_rtl_elf_common (rtems_rtl_obj*      obj,
+                      int                 fd,
+                      rtems_rtl_obj_sect* sect,
+                      void*               data)
+{
+  rtems_rtl_elf_common_data* common = (rtems_rtl_elf_common_data*) data;
+  rtems_rtl_obj_cache*       symbols;
+  int                        sym;
+
+  rtems_rtl_obj_caches (&symbols, NULL, NULL);
+
+  if (!symbols)
+    return false;
+
+  /*
+   * Find the number size of the common section by finding all symbols that
+   * reference the SHN_COMMON section.
+   */
+  for (sym = 0; sym < (sect->size / sizeof (Elf_Sym)); ++sym)
+  {
+    Elf_Sym symbol;
+    off_t   off;
+
+    off = obj->ooffset + sect->offset + (sym * sizeof (symbol));
+
+    if (!rtems_rtl_obj_cache_read_byval (symbols, fd, off,
+                                         &symbol, sizeof (symbol)))
+      return false;
+
+    if ((symbol.st_shndx == SHN_COMMON) &&
+        ((ELF_ST_TYPE (symbol.st_info) == STT_OBJECT) ||
+         (ELF_ST_TYPE (symbol.st_info) == STT_COMMON)))
+    {
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+        printf ("rtl: com:elf:%-2d bind:%-2d type:%-2d size:%d value:%d\n",
+                sym, (int) ELF_ST_BIND (symbol.st_info),
+                (int) ELF_ST_TYPE (symbol.st_info),
+                (int) symbol.st_size, (int) symbol.st_value);
+      /*
+       * If the size is zero this is the first entry, it defines the common
+       * section's aligment. The symbol's value is the alignment.
+       */
+      if (common->size == 0)
+        common->alignment = symbol.st_value;
+      common->size +=
+        rtems_rtl_obj_align (common->size, symbol.st_value) + symbol.st_size;
+    }
+  }
+
+  return true;
+}
+
 static bool
 rtems_rtl_elf_symbols (rtems_rtl_obj*      obj,
@@ -355,4 +419,5 @@
   rtems_rtl_obj_sym*   gsym;
   char*                gstring;
+  size_t               common_offset;
   int                  sym;
 
@@ -404,13 +469,26 @@
      * we need to make sure there is a valid seciton.
      */
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+      printf ("rtl: sym:elf:%-2d name:%-2d:%-20s bind:%-2d " \
+              "type:%-2d sect:%d size:%d\n",
+              sym, (int) symbol.st_name, name,
+              (int) ELF_ST_BIND (symbol.st_info),
+              (int) ELF_ST_TYPE (symbol.st_info),
+              symbol.st_shndx,
+              (int) symbol.st_size);
+
     if ((symbol.st_shndx != 0) &&
         ((ELF_ST_TYPE (symbol.st_info) == STT_OBJECT) ||
+         (ELF_ST_TYPE (symbol.st_info) == STT_COMMON) ||
          (ELF_ST_TYPE (symbol.st_info) == STT_FUNC) ||
          (ELF_ST_TYPE (symbol.st_info) == STT_NOTYPE)))
     {
+      /*
+       * There needs to be a valid section for the symbol.
+       */
       rtems_rtl_obj_sect* symsect;
 
       symsect = rtems_rtl_obj_find_section_by_index (obj, symbol.st_shndx);
-      if (symsect)
+      if (symsect != NULL)
       {
         if ((ELF_ST_BIND (symbol.st_info) == STB_GLOBAL) ||
@@ -432,4 +510,7 @@
           else
           {
+            if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+              printf ("rtl: sym:elf:%-2d name:%-2d:%-20s: global\n",
+                      sym, (int) symbol.st_name, name);
             ++globals;
             global_string_space += strlen (name) + 1;
@@ -438,4 +519,7 @@
         else if (ELF_ST_BIND (symbol.st_info) == STB_LOCAL)
         {
+          if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
+            printf ("rtl: sym:elf:%-2d name:%-2d:%-20s: local\n",
+                    sym, (int) symbol.st_name, name);
           ++locals;
           local_string_space += strlen (name) + 1;
@@ -487,4 +571,6 @@
   gstring =
     (((char*) obj->global_table) + (globals * sizeof (rtems_rtl_obj_sym)));
+
+  common_offset = 0;
 
   for (sym = 0; sym < (sect->size / sizeof (Elf_Sym)); ++sym)
@@ -525,4 +611,5 @@
     if ((symbol.st_shndx != 0) &&
         ((ELF_ST_TYPE (symbol.st_info) == STT_OBJECT) ||
+         (ELF_ST_TYPE (symbol.st_info) == STT_COMMON) ||
          (ELF_ST_TYPE (symbol.st_info) == STT_FUNC) ||
          (ELF_ST_TYPE (symbol.st_info) == STT_NOTYPE)) &&
@@ -534,4 +621,5 @@
         rtems_rtl_obj_sym*  osym;
         char*               string;
+        Elf_Word            value;
 
         symsect = rtems_rtl_obj_find_section_by_index (obj, symbol.st_shndx);
@@ -554,8 +642,23 @@
           }
 
+          /*
+           * Allocate any common symbols in the common section.
+           */
+          if (symbol.st_shndx == SHN_COMMON)
+          {
+            size_t value_off = rtems_rtl_obj_align (common_offset,
+                                                    symbol.st_value);
+            common_offset = value_off + symbol.st_size;
+            value = value_off;
+          }
+          else
+          {
+            value = symbol.st_value;
+          }
+
           rtems_chain_set_off_chain (&osym->node);
           memcpy (string, name, strlen (name) + 1);
           osym->name = string;
-          osym->value = symbol.st_value + (uint8_t*) symsect->base;
+          osym->value = value + (uint8_t*) symsect->base;
           osym->data = symbol.st_info;
 
@@ -657,10 +760,10 @@
       return false;
 
-    flags = 0;
-
     if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
       printf ("rtl: section: %2d: type=%d flags=%08x link=%d info=%d\n",
               section, (int) shdr.sh_type, (unsigned int) shdr.sh_flags,
               (int) shdr.sh_link, (int) shdr.sh_info);
+
+    flags = 0;
 
     switch (shdr.sh_type)
@@ -769,4 +872,17 @@
   }
 
+  return true;
+}
+
+static bool
+rtems_rtl_elf_add_common (rtems_rtl_obj* obj, size_t size, uint32_t alignment)
+{
+  if (size > 0)
+  {
+    if (!rtems_rtl_obj_add_section (obj, SHN_COMMON, ".common.rtems.rtl",
+                                    size, 0, alignment, 0, 0,
+                                    RTEMS_RTL_OBJ_SECT_BSS | RTEMS_RTL_OBJ_SECT_ZERO))
+      return false;
+  }
   return true;
 }
@@ -907,6 +1023,7 @@
 rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
 {
-  rtems_rtl_obj_cache* header;
-  Elf_Ehdr             ehdr;
+  rtems_rtl_obj_cache*      header;
+  Elf_Ehdr                  ehdr;
+  rtems_rtl_elf_common_data common = { .size = 0, .alignment = 0 };
 
   rtems_rtl_obj_caches (&header, NULL, NULL);
@@ -966,6 +1083,21 @@
     return false;
 
+  /*
+   * See if there are any common variables and if there are add a common
+   * section.
+   */
+  if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_common, &common))
+    return false;
+  if (!rtems_rtl_elf_add_common (obj, common.size, common.alignment))
+    return false;
+
+  /*
+   * Set the entry point if there is one.
+   */
   obj->entry = (void*)(uintptr_t) ehdr.e_entry;
 
+  /*
+   * Load the sections and symbols and then relocation to the base address.
+   */
   if (!rtems_rtl_obj_load_sections (obj, fd, rtems_rtl_elf_loader, &ehdr))
     return false;
Index: cpukit/libdl/rtl-obj.c
===================================================================
--- cpukit/libdl/rtl-obj.c	(revision 52c7cb1fdc69a032ca2859e1704412dc489ea0ac)
+++ cpukit/libdl/rtl-obj.c	(revision 803eac954ed7a3481c6af9b020d5d25419d3a19d)
@@ -247,17 +247,4 @@
 
 /**
- * Align the size to the next alignment point. Assume the alignment is a
- * positive integral power of 2 if not 0 or 1. If 0 or 1 then there is no
- * alignment.
- */
-static size_t
-rtems_rtl_sect_align (size_t offset, uint32_t alignment)
-{
-  if ((alignment > 1) && ((offset & (alignment - 1)) != 0))
-    offset = (offset + alignment) & ~(alignment - 1);
-  return offset;
-}
-
-/**
  * Section size summer iterator data.
  */
@@ -275,5 +262,5 @@
   if ((sect->flags & summer->mask) == summer->mask)
     summer->size =
-      rtems_rtl_sect_align (summer->size, sect->alignment) + sect->size;
+      rtems_rtl_obj_align (summer->size, sect->alignment) + sect->size;
   return true;
 }
@@ -439,7 +426,7 @@
 
     if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
-      printf ("rtl: sect: %-2d: %s (%zu)\n", section, name, size);
-  }
-
+      printf ("rtl: sect: add: %-2d: %s (%zu) 0x%08lx\n",
+              section, name, size, flags);
+  }
   return true;
 }
@@ -468,4 +455,6 @@
   const char*          name;  /**< The name to match. */
   int                  index; /**< The index to match. */
+  uint32_t             mask;  /**< The mask to match. */
+  unsigned int         flags; /**< The flags to use when matching. */
 } rtems_rtl_obj_sect_finder;
 
@@ -490,4 +479,6 @@
   match.sect = NULL;
   match.name = name;
+  match.mask = 0;
+  match.flags = 0;
   rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
                            rtems_rtl_obj_sect_match_name,
@@ -516,6 +507,44 @@
   match.sect = NULL;
   match.index = index;
+  match.mask = 0;
+  match.flags = 0;
   rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
                            rtems_rtl_obj_sect_match_index,
+                           &match);
+  return match.sect;
+}
+
+static bool
+rtems_rtl_obj_sect_match_mask (rtems_chain_node* node, void* data)
+{
+  rtems_rtl_obj_sect*        sect = (rtems_rtl_obj_sect*) node;
+  rtems_rtl_obj_sect_finder* match = data;
+  if (match->flags == 0)
+  {
+    if (match->index < 0 || sect->section == match->index)
+      match->flags = 1;
+    if (match->index >= 0)
+      return true;
+  }
+  if ((sect->flags & match->mask) != 0)
+  {
+    match->sect = sect;
+    return false;
+  }
+  return true;
+}
+
+rtems_rtl_obj_sect*
+rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
+                                    int                  index,
+                                    uint32_t             mask)
+{
+  rtems_rtl_obj_sect_finder match;
+  match.sect = NULL;
+  match.index = index;
+  match.mask = mask;
+  match.flags = 0;
+  rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
+                           rtems_rtl_obj_sect_match_mask,
                            &match);
   return match.sect;
@@ -776,5 +805,5 @@
       {
         if (!first)
-          base_offset = rtems_rtl_sect_align (base_offset, sect->alignment);
+          base_offset = rtems_rtl_obj_align (base_offset, sect->alignment);
 
         first = false;
