summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-08-25 15:54:23 +1000
committerChris Johns <chrisj@rtems.org>2016-08-25 15:57:21 +1000
commitef4a46e0293111361c970a287c29a185905121b2 (patch)
treeb32519e8167b2ba83c773108354978c084d2d365
parente6a06751cc58127a52e2948cc8b0349692f6f74b (diff)
downloadrtems-tools-ef4a46e0293111361c970a287c29a185905121b2.tar.bz2
linkers/syms: Add weak symbols to the global symbol table.4.11.14.11.0
Add any weak symbols that have been linked into the base image to the global symbol table. A weak symbol is global when view viewed from a dynamically loaded module. Closes #2704.
-rw-r--r--linkers/rtems-syms.cpp81
1 files changed, 61 insertions, 20 deletions
diff --git a/linkers/rtems-syms.cpp b/linkers/rtems-syms.cpp
index a017ffa..3670188 100644
--- a/linkers/rtems-syms.cpp
+++ b/linkers/rtems-syms.cpp
@@ -146,32 +146,73 @@ c_embedded_trailer (rld::process::tempfile& c)
* Generate the symbol map object file for loading or linking into
* a running RTEMS machine.
*/
+
+struct output_sym
+{
+ rld::process::tempfile& c;
+ const bool embed;
+ const bool weak;
+
+ output_sym(rld::process::tempfile& c,
+ bool embed,
+ bool weak)
+ : c (c),
+ embed (embed),
+ weak (weak) {
+ }
+
+ void operator ()(const rld::symbols::symtab::value_type& value);
+};
+
+void
+output_sym::operator ()(const rld::symbols::symtab::value_type& value)
+{
+ const rld::symbols::symbol& sym = *(value.second);
+
+ /*
+ * Weak symbols without a value are probably unresolved externs. Ignore them.
+ */
+ if (weak && sym.value () == 0)
+ return;
+
+ c.write_line ("asm(\" .asciz \\\"" + sym.name () + "\\\"\");");
+
+ 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 () + "\");");
+ }
+}
+
+
static void
generate_c (rld::process::tempfile& c,
- rld::symbols::table& symbols,
- bool embed)
+ rld::symbols::table& symbols,
+ bool embed)
{
temporary_file_paint (c, c_header);
- for (rld::symbols::symtab::const_iterator si = symbols.globals ().begin ();
- si != symbols.globals ().end ();
- ++si)
- {
- const rld::symbols::symbol& sym = *((*si).second);
-
- c.write_line ("asm(\" .asciz \\\"" + sym.name () + "\\\"\");");
+ /*
+ * Add the global symbols.
+ */
+ std::for_each (symbols.globals ().begin (),
+ symbols.globals ().end (),
+ output_sym (c, embed, false));
- 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 () + "\");");
- }
- }
+ /*
+ * Add the weak symbols that have been linked into the base image. A weak
+ * symbols present in the base image is no longer weak and should be consider
+ * a global symbol. You cannot link a global symbol with the same in a
+ * dynamically loaded module.
+ */
+ std::for_each (symbols.weaks ().begin (),
+ symbols.weaks ().end (),
+ output_sym (c, embed, true));
temporary_file_paint (c, c_trailer);