From ef4a46e0293111361c970a287c29a185905121b2 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Thu, 25 Aug 2016 15:54:23 +1000 Subject: linkers/syms: Add weak symbols to the global symbol table. 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. --- linkers/rtems-syms.cpp | 81 +++++++++++++++++++++++++++++++++++++------------- 1 file 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); -- cgit v1.2.3