diff options
author | Chris Johns <chrisj@rtems.org> | 2014-09-08 16:06:48 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2014-09-08 16:06:48 +1000 |
commit | 6506aa14aad5db5f4f3fab80bec12964148f13ad (patch) | |
tree | 500ab8b9d012460b44ccc032fa5b4f2f0ed4a6e2 /linkers/rtems-tld.cpp | |
parent | b28e8b311550ba5296c814dfdfa1136517ce00a1 (diff) |
RTEMS trace linker builds trace applications.
The trace linker builds the both_hello example in examples-v2.
Move the various string support functions into a C++ file and stop being
inlined. Make them return const std::string.
Add ld support to rld-cc.
Add search path support to rld-config so installed common files can be used.
Fix the path bugs.
Add an absolute path function to rld-path.
Diffstat (limited to 'linkers/rtems-tld.cpp')
-rw-r--r-- | linkers/rtems-tld.cpp | 126 |
1 files changed, 100 insertions, 26 deletions
diff --git a/linkers/rtems-tld.cpp b/linkers/rtems-tld.cpp index c6d5c55..28f154d 100644 --- a/linkers/rtems-tld.cpp +++ b/linkers/rtems-tld.cpp @@ -90,7 +90,7 @@ namespace rld /** * Return the function's declaration. */ - const std::string decl () const; + const std::string decl (const std::string& prefix = "") const; }; /** @@ -194,6 +194,11 @@ namespace rld void generate_traces (rld::process::tempfile& c); /** + * Get the traces. + */ + const rld::strings& get_traces () const; + + /** * Dump the wrapper. */ void dump (std::ostream& out) const; @@ -321,9 +326,9 @@ namespace rld } const std::string - signature::decl () const + signature::decl (const std::string& prefix) const { - std::string ds = ret + ' ' + name + '('; + std::string ds = ret + ' ' + prefix + name + '('; int arg = 0; for (function_args::const_iterator ai = args.begin (); ai != args.end (); @@ -485,7 +490,6 @@ namespace rld * configuration and may contain: * * # name The name of trace being linked. - * # bsp The architecture/bsp name of the BSP. * # options A list of options as per the long command line args. * # traces The list of sections containing function lists to trace. * # functions The list of sections containing function details. @@ -503,7 +507,6 @@ namespace rld config.includes (section); name = section.get_record_item ("name"); - bsp = section.get_record_item ("bsp"); load_functions (config, section); load_traces (config, section); @@ -640,7 +643,7 @@ namespace rld const signature& sig = (*si).second; c.write_line(""); - c.write_line(sig.decl ()); + c.write_line(sig.decl ("__wrap_")); c.write_line("{"); std::string l; @@ -655,7 +658,7 @@ namespace rld l = " ret ="; } - l += " " + generator_.map_sym_prefix + sig.name + '('; + l += " __real_" + sig.name + '('; for (size_t a = 0; a < sig.args.size (); ++a) { if (a) @@ -679,6 +682,12 @@ namespace rld } } + const rld::strings& + tracer::get_traces () const + { + return traces; + } + void tracer::dump (std::ostream& out) const { @@ -710,6 +719,16 @@ namespace rld linker::load_config (const std::string& path, const std::string& trace) { + std::string sp = get_prefix (); + + rld::path::path_join (sp, "share", sp); + rld::path::path_join (sp, "rtems", sp); + rld::path::path_join (sp, "trace-linker", sp); + + if (rld::verbose () || true) + std::cout << "search path: " << sp << std::endl; + + config.set_search_path (sp); config.clear (); config.load (path); tracer_.load (config, trace); @@ -759,9 +778,38 @@ namespace rld void linker::link (rld::process::tempfile& o, - const std::string& ld_cmds) + const std::string& ld_cmd) { + rld::process::arg_container args; + + if (rld::verbose ()) + std::cout << "linking: " << o.name () << std::endl; + + std::string wrap = " -Wl,--wrap -Wl,"; + + rld::cc::make_ld_command (args); + + args.push_back (o.name ()); + + rld::process::args_append (args, ld_cmd); + rld::process::args_append (args, + wrap + rld::join (tracer_.get_traces (), wrap)); + + rld::process::tempfile out; + rld::process::tempfile err; + rld::process::status status; + + status = rld::process::execute (rld::cc::get_ld (), + args, + out.name (), + err.name ()); + if ((status.type != rld::process::status::normal) || + (status.code != 0)) + { + err.output (rld::cc::get_cc (), std::cout); + throw rld::error ("Linker error", "linking"); + } } void @@ -792,9 +840,10 @@ static struct option rld_opts[] = { { "verbose", no_argument, NULL, 'v' }, { "warn", no_argument, NULL, 'w' }, { "keep", no_argument, NULL, 'k' }, + { "compiler", required_argument, NULL, 'c' }, { "linker", required_argument, NULL, 'l' }, { "exec-prefix", required_argument, NULL, 'E' }, - { "cflags", required_argument, NULL, 'c' }, + { "cflags", required_argument, NULL, 'f' }, { "rtems", required_argument, NULL, 'r' }, { "rtems-bsp", required_argument, NULL, 'B' }, { "config", required_argument, NULL, 'C' }, @@ -807,19 +856,20 @@ usage (int exit_code) { std::cout << "rtems-trace-ld [options] objects" << std::endl << "Options and arguments:" << std::endl - << " -h : help (also --help)" << std::endl - << " -V : print linker version number and exit (also --version)" << std::endl - << " -v : verbose (trace import parts), can supply multiple times" << std::endl - << " to increase verbosity (also --verbose)" << std::endl - << " -w : generate warnings (also --warn)" << std::endl - << " -k : keep temporary files (also --keep)" << std::endl - << " -l linker : target linker is not standard (also --linker)" << std::endl - << " -E prefix : the RTEMS tool prefix (also --exec-prefix)" << std::endl - << " -c cflags : C compiler flags (also --cflags)" << std::endl - << " -r path : RTEMS path (also --rtems)" << std::endl - << " -B bsp : RTEMS arch/bsp (also --rtems-bsp)" << std::endl - << " -W wrapper : wrapper file name without ext (also --wrapper)" << std::endl - << " -C ini : user configuration INI file (also --config)" << std::endl; + << " -h : help (also --help)" << std::endl + << " -V : print linker version number and exit (also --version)" << std::endl + << " -v : verbose (trace import parts), can supply multiple times" << std::endl + << " to increase verbosity (also --verbose)" << std::endl + << " -w : generate warnings (also --warn)" << std::endl + << " -k : keep temporary files (also --keep)" << std::endl + << " -c compiler : target compiler is not standard (also --compiler)" << std::endl + << " -l linker : target linker is not standard (also --linker)" << std::endl + << " -E prefix : the RTEMS tool prefix (also --exec-prefix)" << std::endl + << " -f cflags : C compiler flags (also --cflags)" << std::endl + << " -r path : RTEMS path (also --rtems)" << std::endl + << " -B bsp : RTEMS arch/bsp (also --rtems-bsp)" << std::endl + << " -W wrappe r : wrapper file name without ext (also --wrapper)" << std::endl + << " -C ini : user configuration INI file (also --config)" << std::endl; ::exit (exit_code); } @@ -867,6 +917,7 @@ main (int argc, char* argv[]) try { rld::trace::linker linker; + std::string cc; std::string ld; std::string ld_cmd; std::string configuration; @@ -877,7 +928,7 @@ main (int argc, char* argv[]) while (true) { - int opt = ::getopt_long (argc, argv, "hvwkVl:E:c:C:r:B:W:", rld_opts, NULL); + int opt = ::getopt_long (argc, argv, "hvwkVc:l:E:f:C:r:B:W:", rld_opts, NULL); if (opt < 0) break; @@ -903,6 +954,10 @@ main (int argc, char* argv[]) rld::process::set_keep_temporary_files (); break; + case 'c': + cc = optarg; + break; + case 'l': ld = optarg; break; @@ -911,7 +966,7 @@ main (int argc, char* argv[]) rld::cc::set_exec_prefix (optarg); break; - case 'c': + case 'f': rld::cc::append_flags (optarg, rld::cc::ft_cflags); break; @@ -941,6 +996,11 @@ main (int argc, char* argv[]) } } + /* + * Set the program name. + */ + rld::set_progname (argv[0]); + argc -= optind; argv += optind; @@ -953,16 +1013,30 @@ main (int argc, char* argv[]) if (!rtems_arch_bsp.empty ()) { if (rtems_path.empty ()) - throw rld::error ("arch/bsp provide and no RTEMS path", "options"); + throw rld::error ("No RTEMS path provide with arch/bsp", "options"); rld::rtems::set_path (rtems_path); rld::rtems::set_arch_bsp (rtems_arch_bsp); } + /** + * Set the compiler and/or linker if provided. + */ + if (!cc.empty ()) + rld::cc::set_cc (cc); + if (!ld.empty ()) + rld::cc::set_ld (ld); + /* * Load the remaining command line arguments into the linker command line. */ while (argc--) - ld_cmd += ' ' + *argv++; + { + /* + * Create this value because 'ld_cmd += ' ' + *argv++' fails on clang. + */ + std::string av = *argv++; + ld_cmd += ' ' + av; + } ld_cmd = rld::trim (ld_cmd); /* |