[rtems-tools commit] linkers: Add base image symbol to ELF object file generation.

Chris Johns chrisj at rtems.org
Thu Oct 30 06:49:36 UTC 2014


Module:    rtems-tools
Branch:    master
Commit:    fdb1fe685ab60de784b5f20413fe54cd70a01ff2
Changeset: http://git.rtems.org/rtems-tools/commit/?id=fdb1fe685ab60de784b5f20413fe54cd70a01ff2

Author:    Chris Johns <chrisj at rtems.org>
Date:      Thu Oct 30 17:55:18 2014 +1100

linkers: Add base image symbol to ELF object file generation.

This change adds support to the rtems-syms code to generate a suitable
ELF object you can link to the base image kernel in the embed mode or
you can load with the run-time load mode.

The change fixes a bug in the framework where local ELF symbols
were being placed in the external symbol table. The external
symbol table has been removed and a global, weak and local set
of tables is now provided as this is more aligned with the ELF
format.

---

 linkers/rtems-syms.cpp        |  144 +++++++++++++++++++++--------------------
 rtemstoolkit/rld-files.cpp    |   38 +++++++++--
 rtemstoolkit/rld-process.cpp  |   13 ++--
 rtemstoolkit/rld-resolver.cpp |    4 +-
 rtemstoolkit/rld-symbols.cpp  |   71 ++++++++++++++++----
 rtemstoolkit/rld-symbols.h    |   55 +++++++++++++---
 rtemstoolkit/rtems-utils.h    |    4 +-
 7 files changed, 215 insertions(+), 114 deletions(-)

diff --git a/linkers/rtems-syms.cpp b/linkers/rtems-syms.cpp
index 618c7bd..5d9f10a 100644
--- a/linkers/rtems-syms.cpp
+++ b/linkers/rtems-syms.cpp
@@ -55,49 +55,52 @@ static const char* c_header[] =
 {
   "/*",
   " * RTEMS Global Symbol Table",
-  " *  Automatically generated so no point in hacking on it.",
+  " *  Automatically generated. Do not edit..",
   " */",
   "",
-  "#if __bfin__ || __h8300__ || __v850__",
-  " extern unsigned char _rtems_rtl_base_globals[];",
-  " extern unsigned int _rtems_rtl_base_globals_size;",
-  "#else",
-  " extern unsigned char __rtems_rtl_base_globals[];",
-  " extern unsigned int __rtems_rtl_base_globals_size;",
-  "#endif",
+  "extern const unsigned char rtems__rtl_base_globals[];",
+  "extern const unsigned int rtems__rtl_base_globals_size;",
+  "",
+  "void rtems_rtl_base_sym_global_add (const unsigned char* , unsigned int );",
+  "",
+  "asm(\".section \\\".rodata\\\"\");",
   "",
   "asm(\"  .align   4\");",
-  "asm(\"__rtems_rtl_base_globals:\");",
+  "asm(\"  .local   rtems__rtl_base_globals\");",
+  "asm(\"rtems__rtl_base_globals:\");",
+  "#if __mips__",
+  " asm(\"  .align 0\");",
+  "#else",
+  " asm(\"  .balign 1\");",
+  "#endif",
   0
 };
 
 static const char* c_trailer[] =
 {
   "asm(\"  .byte    0\");",
-  "#if __mips__",
-  " asm(\"  .align 0\");",
-  "#else",
-  " asm(\"  .balign 1\");",
-  "#endif",
-  "asm(\"  .ascii \\\"\\xde\\xad\\xbe\\xef\\\"\");",
+  "asm(\"  .ascii   \\\"\\xde\\xad\\xbe\\xef\\\"\");",
+  "asm(\"  .type    rtems__rtl_base_globals, #object\");",
+  "asm(\"  .size    rtems__rtl_base_globals, . - rtems__rtl_base_globals\");",
+  "",
+  "/*",
+  " * Symbol table size.",
+  " */",
   "asm(\"  .align   4\");",
-  "asm(\"__rtems_rtl_base_globals_size:\");",
-  "asm(\"  .long __rtems_rtl_base_globals_size - __rtems_rtl_base_globals\");",
+  "asm(\"  .local   rtems__rtl_base_globals_size\");",
+  "asm(\"  .type    rtems__rtl_base_globals_size, #object\");",
+  "asm(\"  .size    rtems__rtl_base_globals_size, 4\");",
+  "asm(\"rtems__rtl_base_globals_size:\");",
+  "asm(\"  .long rtems__rtl_base_globals_size - rtems__rtl_base_globals\");",
   "",
-  "void rtems_rtl_base_sym_global_add (const unsigned char* , unsigned int );",
   0
 };
 
 static const char* c_rtl_call_body[] =
 {
   "{",
-  "#if __bfin__ || __h8300__ || __v850__",
-  "  rtems_rtl_base_sym_global_add (_rtems_rtl_base_globals,",
-  "                                 _rtems_rtl_base_globals_size);",
-  "#else",
-  "  rtems_rtl_base_sym_global_add (__rtems_rtl_base_globals,",
-  "                                 __rtems_rtl_base_globals_size);",
-  "#endif",
+  "  rtems_rtl_base_sym_global_add ((const unsigned char*) &rtems__rtl_base_globals,",
+  "                                 rtems__rtl_base_globals_size);",
   "}",
   0
 };
@@ -118,7 +121,6 @@ temporary_file_paint (rld::process::tempfile& t, const char* lines[])
 static void
 c_constructor_trailer (rld::process::tempfile& c)
 {
-  temporary_file_paint (c, c_trailer);
   c.write_line ("static void init(void) __attribute__ ((constructor));");
   c.write_line ("static void init(void)");
   temporary_file_paint (c, c_rtl_call_body);
@@ -128,9 +130,8 @@ c_constructor_trailer (rld::process::tempfile& c)
  * The embedded trailer.
  */
 static void
-c_embedded_trailer(rld::process::tempfile& c)
+c_embedded_trailer (rld::process::tempfile& c)
 {
-  temporary_file_paint (c, c_trailer);
   c.write_line ("void rtems_rtl_base_global_syms_init(void);");
   c.write_line ("void rtems_rtl_base_global_syms_init(void)");
   temporary_file_paint (c, c_rtl_call_body);
@@ -141,40 +142,34 @@ c_embedded_trailer(rld::process::tempfile& c)
  * a running RTEMS machine.
  */
 static void
-generate_asm (rld::process::tempfile& c,
-              rld::symbols::table&    symbols,
-              bool                    embed)
+generate_c (rld::process::tempfile& c,
+              rld::symbols::table&  symbols,
+              bool                  embed)
 {
   temporary_file_paint (c, c_header);
 
-  for (rld::symbols::symtab::const_iterator si = symbols.externals ().begin ();
-       si != symbols.externals ().end ();
+  for (rld::symbols::symtab::const_iterator si = symbols.globals ().begin ();
+       si != symbols.globals ().end ();
        ++si)
   {
     const rld::symbols::symbol& sym = *((*si).second);
 
-    if (!sym.name ().empty ())
-    {
-      c.write_line ("asm(\"  .asciz \\\"" + sym.name () + "\\\"\");");
+    c.write_line ("asm(\"  .asciz \\\"" + sym.name () + "\\\"\");");
 
-      if (embed)
-      {
-        c.write_line ("#if __mips__");
-        c.write_line ("asm(\"  .align 0\");");
-        c.write_line ("#else");
-        c.write_line ("asm(\"  .balign 1\");");
-        c.write_line ("#endif");
-        c.write_line ("asm(\"  .long " + sym.name () + "\");");
-      }
-      else
-      {
-        std::stringstream oss;
-        oss << std::hex << std::setfill ('0') << std::setw (8) << sym.value ();
-        c.write_line ("asm(\"  .long 0x" + oss.str () + "\");");
-      }
+    if (embed)
+    {
+      c.write_line ("asm(\"  .long " + sym.name () + "\");");
+    }
+    else
+    {
+      std::stringstream oss;
+      oss << std::hex << std::setfill ('0') << std::setw (8) << sym.value ();
+      c.write_line ("asm(\"  .long 0x" + oss.str () + "\");");
     }
   }
 
+  temporary_file_paint (c, c_trailer);
+
   if (embed)
     c_embedded_trailer (c);
   else
@@ -192,7 +187,7 @@ generate_symmap (rld::process::tempfile& c,
   if (rld::verbose ())
     std::cout << "symbol C file: " << c.name () << std::endl;
 
-  generate_asm (c, symbols, embed);
+  generate_c (c, symbols, embed);
 
   if (rld::verbose ())
     std::cout << "symbol O file: " << output << std::endl;
@@ -203,7 +198,6 @@ generate_symmap (rld::process::tempfile& c,
   rld::cc::append_flags (rld::cc::ft_cflags, args);
 
   args.push_back ("-O2");
-  args.push_back ("-g");
   args.push_back ("-c");
   args.push_back ("-o");
   args.push_back (output);
@@ -218,6 +212,7 @@ generate_symmap (rld::process::tempfile& c,
                                   out.name (),
                                   err.name ());
 
+
   if ((status.type != rld::process::status::normal) ||
       (status.code != 0))
   {
@@ -324,7 +319,7 @@ main (int argc, char* argv[])
 
     while (true)
     {
-      int opt = ::getopt_long (argc, argv, "hvVwS:o:m:E:c:C:", rld_opts, NULL);
+      int opt = ::getopt_long (argc, argv, "hvVwkef:S:o:m:E:c:C:", rld_opts, NULL);
       if (opt < 0)
         break;
 
@@ -408,8 +403,8 @@ main (int argc, char* argv[])
       throw rld::error ("no kernel file", "options");
     if (argc != 1)
       throw rld::error ("only one kernel file", "options");
-    if (output.empty ())
-      throw rld::error ("no output file", "options");
+    if (output.empty () && map.empty ())
+      throw rld::error ("no output or map", "options");
 
     kernel_name = *argv;
 
@@ -421,6 +416,9 @@ main (int argc, char* argv[])
      */
     try
     {
+      /*
+       * Load the kernel ELF file symbol table.
+       */
       kernel.open ();
       kernel.add (kernel_name);
       kernel.load_symbols (symbols, true);
@@ -436,21 +434,8 @@ main (int argc, char* argv[])
       if (!rld::cc::is_cc_set () && !rld::cc::is_exec_prefix_set ())
         rld::cc::set_exec_prefix (rld::elf::machine_type ());
 
-      rld::process::tempfile c (".c");
-
-      if (!symc.empty ())
-      {
-        c.override (symc);
-        c.keep ();
-      }
-
-      /*
-       * Generate and compile the symbol map.
-       */
-      generate_symmap (c, output, symbols, embed);
-
       /*
-       * Create a map file is asked to.
+       * Create a map file if asked too.
        */
       if (!map.empty ())
       {
@@ -465,6 +450,25 @@ main (int argc, char* argv[])
         mout.close ();
       }
 
+      /*
+       * Create an output file if asked too.
+       */
+      if (!output.empty ())
+      {
+        rld::process::tempfile c (".c");
+
+        if (!symc.empty ())
+        {
+          c.override (symc);
+          c.keep ();
+        }
+
+        /*
+         * Generate and compile the symbol map.
+         */
+        generate_symmap (c, output, symbols, embed);
+      }
+
       kernel.close ();
     }
     catch (...)
diff --git a/rtemstoolkit/rld-files.cpp b/rtemstoolkit/rld-files.cpp
index 03310e8..995b059 100644
--- a/rtemstoolkit/rld-files.cpp
+++ b/rtemstoolkit/rld-files.cpp
@@ -1040,10 +1040,32 @@ namespace rld
 
       rld::symbols::pointers syms;
 
-      elf ().get_symbols (syms, false, local, false, true);
+      if (local)
+      {
+        elf ().get_symbols (syms, false, true, false, false);
+
+        if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS)
+          std::cout << "object:load-sym: local: total "
+                    << syms.size () << std::endl;
+
+        for (symbols::pointers::iterator si = syms.begin ();
+             si != syms.end ();
+             ++si)
+        {
+          symbols::symbol& sym = *(*si);
+
+          if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS)
+            std::cout << "object:load-sym: local: " << sym << std::endl;
+
+          sym.set_object (*this);
+          symbols.add_local (sym);
+        }
+      }
+
+      elf ().get_symbols (syms, false, false, true, false);
 
       if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS)
-        std::cout << "object:load-sym: exported: total "
+        std::cout << "object:load-sym: weak: total "
                   << syms.size () << std::endl;
 
       for (symbols::pointers::iterator si = syms.begin ();
@@ -1053,17 +1075,17 @@ namespace rld
         symbols::symbol& sym = *(*si);
 
         if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS)
-          std::cout << "object:load-sym: exported: " << sym << std::endl;
+          std::cout << "object:load-sym: weak: " << sym << std::endl;
 
         sym.set_object (*this);
-        symbols.add_external (sym);
+        symbols.add_weak (sym);
         externals.push_back (&sym);
       }
 
-      elf ().get_symbols (syms, false, false, true, false);
+      elf ().get_symbols (syms, false, false, false, true);
 
       if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS)
-        std::cout << "object:load-sym: weak: total "
+        std::cout << "object:load-sym: global: total "
                   << syms.size () << std::endl;
 
       for (symbols::pointers::iterator si = syms.begin ();
@@ -1073,10 +1095,10 @@ namespace rld
         symbols::symbol& sym = *(*si);
 
         if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS)
-          std::cout << "object:load-sym: weak: " << sym << std::endl;
+          std::cout << "object:load-sym: global: " << sym << std::endl;
 
         sym.set_object (*this);
-        symbols.add_weak (sym);
+        symbols.add_global (sym);
         externals.push_back (&sym);
       }
 
diff --git a/rtemstoolkit/rld-process.cpp b/rtemstoolkit/rld-process.cpp
index bfd6734..e91796f 100644
--- a/rtemstoolkit/rld-process.cpp
+++ b/rtemstoolkit/rld-process.cpp
@@ -271,7 +271,7 @@ namespace rld
         {
           if (level < (sizeof (buf) - 1))
           {
-            memset (buf + level, 0, sizeof (buf) - level);
+            ::memset (buf + level, 0, sizeof (buf) - level);
             int read = ::read (fd, buf + level, sizeof (buf) - level - 1);
             if (read < 0)
               throw rld::error (::strerror (errno), "tempfile read:" + _name);
@@ -285,15 +285,14 @@ namespace rld
             char* lf = ::strchr (buf, '\n');
             int   len = level;
             if (lf)
-              len = lf - &buf[0] + 1;
-            if (lf || !reading)
             {
-              line.append (buf, len);
-              level -= len;
+              len = lf - &buf[0] + 1;
+              reading = false;
             }
+            line.append (buf, len);
+            level -= len;
             if (level)
               ::memmove (buf, &buf[len], level + 1);
-            reading = false;
           }
         }
       }
@@ -354,7 +353,7 @@ namespace rld
         {
           read_line (line);
           ++lc;
-          if (line.empty ())
+          if (line.empty () && (level == 0))
             break;
           if (!prefix.empty ())
             out << prefix << ": ";
diff --git a/rtemstoolkit/rld-resolver.cpp b/rtemstoolkit/rld-resolver.cpp
index d2a9f1e..e837af1 100644
--- a/rtemstoolkit/rld-resolver.cpp
+++ b/rtemstoolkit/rld-resolver.cpp
@@ -108,7 +108,7 @@ namespace rld
         if ((urs.binding () != STB_WEAK) && urs.object ())
           continue;
 
-        symbols::symbol* es = base_symbols.find_external (urs.name ());
+        symbols::symbol* es = base_symbols.find_global (urs.name ());
         bool             base = true;
 
         if (rld::verbose () >= RLD_VERBOSE_INFO)
@@ -120,7 +120,7 @@ namespace rld
 
         if (!es)
         {
-          es = symbols.find_external (urs.name ());
+          es = symbols.find_global (urs.name ());
           if (!es)
           {
             es = symbols.find_weak (urs.name ());
diff --git a/rtemstoolkit/rld-symbols.cpp b/rtemstoolkit/rld-symbols.cpp
index 79212db..081d3e1 100644
--- a/rtemstoolkit/rld-symbols.cpp
+++ b/rtemstoolkit/rld-symbols.cpp
@@ -132,6 +132,24 @@ namespace rld
       return (name_[0] == '_') && (name_[1] == 'Z');
     }
 
+    bool
+    symbol::is_local () const
+    {
+      return binding () == STB_LOCAL;
+    }
+
+    bool
+    symbol::is_weak () const
+    {
+      return binding () == STB_WEAK;
+    }
+
+    bool
+    symbol::is_global () const
+    {
+      return binding () == STB_GLOBAL;
+    }
+
     int
     symbol::type () const
     {
@@ -275,22 +293,28 @@ namespace rld
     }
 
     void
-    table::add_external (symbol& sym)
+    table::add_global (symbol& sym)
     {
-      _externals[sym.name ()] = &sym;
+      globals_[sym.name ()] = &sym;
     }
 
     void
     table::add_weak (symbol& sym)
     {
-      _weaks[sym.name ()] = &sym;
+      weaks_[sym.name ()] = &sym;
+    }
+
+    void
+    table::add_local (symbol& sym)
+    {
+      locals_[sym.name ()] = &sym;
     }
 
     symbol*
-    table::find_external (const std::string& name)
+    table::find_global (const std::string& name)
     {
-      symtab::iterator sti = _externals.find (name);
-      if (sti == _externals.end ())
+      symtab::iterator sti = globals_.find (name);
+      if (sti == globals_.end ())
         return 0;
       return (*sti).second;
     }
@@ -298,8 +322,17 @@ namespace rld
     symbol*
     table::find_weak (const std::string& name)
     {
-      symtab::iterator sti = _weaks.find (name);
-      if (sti == _weaks.end ())
+      symtab::iterator sti = weaks_.find (name);
+      if (sti == weaks_.end ())
+        return 0;
+      return (*sti).second;
+    }
+
+    symbol*
+    table::find_local (const std::string& name)
+    {
+      symtab::iterator sti = locals_.find (name);
+      if (sti == locals_.end ())
         return 0;
       return (*sti).second;
     }
@@ -307,19 +340,25 @@ namespace rld
     size_t
     table::size () const
     {
-      return _externals.size () + _weaks.size ();
+      return globals_.size () + weaks_.size () + locals_.size ();
     }
 
     const symtab&
-    table::externals () const
+    table::globals () const
     {
-      return _externals;
+      return globals_;
     }
 
     const symtab&
     table::weaks () const
     {
-      return _weaks;
+      return weaks_;
+    }
+
+    const symtab&
+    table::locals () const
+    {
+      return locals_;
     }
 
     void
@@ -329,7 +368,7 @@ namespace rld
            sbi != bucket_.end ();
            ++sbi)
       {
-        table_.add_external (*sbi);
+        table_.add_global (*sbi);
       }
     }
 
@@ -364,10 +403,12 @@ namespace rld
     void
     output (std::ostream& out, const table& symbols)
     {
-      out << "Externals:" << std::endl;
-      output (out, symbols.externals ());
+      out << "Globals:" << std::endl;
+      output (out, symbols.globals ());
       out << "Weaks:" << std::endl;
       output (out, symbols.weaks ());
+      out << "Locals:" << std::endl;
+      output (out, symbols.locals ());
     }
 
     void
diff --git a/rtemstoolkit/rld-symbols.h b/rtemstoolkit/rld-symbols.h
index 5405d2f..02a41a3 100644
--- a/rtemstoolkit/rld-symbols.h
+++ b/rtemstoolkit/rld-symbols.h
@@ -101,6 +101,21 @@ namespace rld
       bool is_cplusplus () const;
 
       /**
+       * Is the symbol binding is local ?
+       */
+      bool is_local () const;
+
+      /**
+       * Is the symbol binding weak ?
+       */
+      bool is_weak () const;
+
+      /**
+       * Is the symbol binding global ?
+       */
+      bool is_global () const;
+
+      /**
        * The symbol's type.
        */
       int type () const;
@@ -190,7 +205,7 @@ namespace rld
     typedef std::map < std::string, symbol* > symtab;
 
     /**
-     * A symbols contains a symbol table of externals and weak symbols.
+     * A symbols contains a symbol table of global, weak and local symbols.
      */
     class table
     {
@@ -206,9 +221,9 @@ namespace rld
       ~table ();
 
       /**
-       * Add an external symbol.
+       * Add a global symbol.
        */
-      void add_external (symbol& sym);
+      void add_global (symbol& sym);
 
       /**
        * Add a weak symbol.
@@ -216,9 +231,14 @@ namespace rld
       void add_weak (symbol& sym);
 
       /**
-       * Find an external symbol.
+       * Add a local symbol.
        */
-      symbol* find_external (const std::string& name);
+      void add_local (symbol& sym);
+
+      /**
+       * Find a global symbol.
+       */
+      symbol* find_global (const std::string& name);
 
       /**
        * Find an weak symbol.
@@ -226,20 +246,30 @@ namespace rld
       symbol* find_weak (const std::string& name);
 
       /**
+       * Find an local symbol.
+       */
+      symbol* find_local (const std::string& name);
+
+      /**
        * Return the size of the symbols loaded.
        */
       size_t size () const;
 
       /**
-       * Return the externals symbol table.
+       * Return the globals symbol table.
        */
-      const symtab& externals () const;
+      const symtab& globals () const;
 
       /**
        * Return the weaks symbol table.
        */
       const symtab& weaks () const;
 
+      /**
+       * Return the locals symbol table.
+       */
+      const symtab& locals () const;
+
     private:
 
       /**
@@ -248,14 +278,19 @@ namespace rld
       table (const table& orig);
 
       /**
-       * A table of external symbols.
+       * A table of global symbols.
        */
-      symtab _externals;
+      symtab globals_;
 
       /**
        * A table of weak symbols.
        */
-      symtab _weaks;
+      symtab weaks_;
+
+      /**
+       * A table of local symbols.
+       */
+      symtab locals_;
     };
 
     /**
diff --git a/rtemstoolkit/rtems-utils.h b/rtemstoolkit/rtems-utils.h
index 9918570..4ce9c68 100644
--- a/rtemstoolkit/rtems-utils.h
+++ b/rtemstoolkit/rtems-utils.h
@@ -22,8 +22,8 @@
  *
  */
 
-#if !defined (_MEMORY_DUMP_H_)
-#define _MEMORY_DUMP_H_
+#if !defined (_RTEMS_UTILS_H_)
+#define _RTEMS_UTILS_H_
 
 #include <stdint.h>
 



More information about the vc mailing list