summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-10-30 17:55:18 +1100
committerChris Johns <chrisj@rtems.org>2014-10-30 17:55:18 +1100
commitfdb1fe685ab60de784b5f20413fe54cd70a01ff2 (patch)
tree05b75e65b705a08c46220416423d64331a68752e
parentlinkers: Add kernel symbol support. (diff)
downloadrtems-tools-fdb1fe685ab60de784b5f20413fe54cd70a01ff2.tar.bz2
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.
-rw-r--r--linkers/rtems-syms.cpp144
-rw-r--r--rtemstoolkit/rld-files.cpp38
-rw-r--r--rtemstoolkit/rld-process.cpp13
-rw-r--r--rtemstoolkit/rld-resolver.cpp4
-rw-r--r--rtemstoolkit/rld-symbols.cpp71
-rw-r--r--rtemstoolkit/rld-symbols.h55
-rw-r--r--rtemstoolkit/rtems-utils.h4
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>