Changeset 4fd758e in rtems-tools for linkers


Ignore:
Timestamp:
Aug 5, 2014, 1:02:35 PM (5 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.10, 4.11, master
Children:
097f1fd
Parents:
a136346
Message:

rtems-tld: Add wrapper support and start the generator coding.

Location:
linkers
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • linkers/rld.h

    ra136346 r4fd758e  
    4242#define RLD_PATHSTR_SEPARATOR_STR ";"
    4343#define RLD_DRIVE_SEPARATOR       (1)
     44#define RLD_LINE_SEPARATOR        "\r\n"
    4445#else
    4546#define RLD_PATH_SEPARATOR        '/'
     
    4748#define RLD_PATHSTR_SEPARATOR_STR ":"
    4849#define RLD_DRIVE_SEPARATOR       (0)
     50#define RLD_LINE_SEPARATOR        "\n"
    4951#endif
    5052
  • linkers/rtems-tld.cpp

    ra136346 r4fd758e  
    116116      std::string   arg_trace;       /**< Code template to trace an argument. */
    117117      std::string   ret_trace;       /**< Code template to trace the return value. */
    118       std::string  code;            /**< Code block inserted before the trace code. */
     118      rld::strings& code;            /**< Code block inserted before the trace code. */
    119119      function_sigs sigs;            /**< The functions this wrapper wraps. */
    120120
     
    123123       */
    124124      wrapper (const std::string&   name,
     125               rld::strings&        code,
    125126               rld::config::config& config);
    126127
     
    167168
    168169      /**
     170       * Generate the wrapper object file.
     171       */
     172      void generate ();
     173
     174      /**
     175       * Generate the trace functions.
     176       */
     177      void generate_traces (rld::process::tempfile& c);
     178
     179      /**
    169180       * Dump the wrapper.
    170181       */
     
    173184    private:
    174185
    175       std::string  name;            /**< The name of the trace. */
    176       std::string  bsp;             /**< The BSP we are linking to. */
    177       rld::strings trace;           /**< The functions to trace. */
    178       wrappers     wrappers;        /**< Wrappers wrap trace functions. */
     186      std::string  name;      /**< The name of the trace. */
     187      std::string  bsp;       /**< The BSP we are linking to. */
     188      rld::strings traces;    /**< The functions to trace. */
     189      wrappers     wrappers;  /**< Wrappers wrap trace functions. */
     190      rld::strings code;      /**< Wrapper code records. Must be unique. */
    179191    };
    180192
     
    196208       * Generate the C file.
    197209       */
    198       void generate_c ();
     210      void generate_wrapper ();
    199211
    200212      /**
     
    262274        }
    263275      ds += ')';
    264 
    265276      return ds;
    266277    }
    267278
    268279    wrapper::wrapper (const std::string&   name,
     280                      rld::strings&        code,
    269281                      rld::config::config& config)
    270       : name (name)
     282      : name (name),
     283        code (code)
    271284    {
    272285      /*
     
    345358      arg_trace = rld::dequote (sec.get_record_item ("arg-trace"));
    346359      ret_trace = rld::dequote (sec.get_record_item ("ret-trace"));
    347       code = rld::dequote (sec.get_record_item ("code"));
     360
     361      /*
     362       * The code block, if present is placed in the code conttainer if unique.
     363       * If referenced by more than wrapper and duplicated a compiler error
     364       * will be generated.
     365       */
     366      rld::strings::iterator ci;
     367      code.push_back (rld::dequote (sec.get_record_item ("code")));
     368      ci = std::unique (code.begin (), code.end ());
     369      code.resize (std::distance (code.begin (), ci));
    348370    }
    349371
     
    395417          << "   Arg Trace Code: " << arg_trace << std::endl
    396418          << "   Return Trace Code: " << ret_trace << std::endl
    397           << "   Code: | "
    398           << rld::find_replace (code, "\n", "\n         | ") << std::endl
    399419          << "   Function Signatures: " << sigs.size () << std::endl;
    400420      for (function_sigs::const_iterator si = sigs.begin ();
     
    462482           ++wsi)
    463483      {
    464         wrappers.push_back (wrapper (*wsi, config));
     484        wrappers.push_back (wrapper (*wsi, code, config));
    465485      }
    466486
     
    474494           ++tsi)
    475495      {
    476         rld::config::parse_items (config, *tsi, "trace", trace, true);
    477       }
    478 
     496        rld::config::parse_items (config, *tsi, "trace", traces, true);
     497      }
     498
     499    }
     500
     501    void
     502    tracer::generate ()
     503    {
     504      rld::process::tempfile c (".c");
     505
     506      c.open (true);
     507
     508      if (rld::verbose ())
     509        std::cout << "wrapper C file: " << c.name () << std::endl;
     510
     511      try
     512      {
     513        c.write_line ("/*");
     514        c.write_line (" * RTEMS Trace Linker Wrapper");
     515        c.write_line (" *  Automatically generated.");
     516        c.write_line (" */");
     517
     518        for (wrappers::const_iterator wi = wrappers.begin ();
     519             wi != wrappers.end ();
     520             ++wi)
     521        {
     522          const wrapper& wrap = *wi;
     523          c.write_line ("");
     524          c.write_line ("/*");
     525          c.write_line (" * Wrapper: " + wrap.name);
     526          c.write_line (" */");
     527          c.write_lines (wrap.defines);
     528          c.write_lines (wrap.headers);
     529        }
     530
     531        c.write_line ("");
     532        c.write_line ("/*");
     533        c.write_line (" * Code blocks");
     534        c.write_line (" */");
     535        c.write_lines (code);
     536
     537        generate_traces (c);
     538      }
     539      catch (...)
     540      {
     541        c.close ();
     542        throw;
     543      }
     544
     545      c.close ();
     546    }
     547
     548    void
     549    tracer::generate_traces (rld::process::tempfile& c)
     550    {
     551      for (rld::strings::const_iterator ti = traces.begin ();
     552           ti != traces.end ();
     553           ++ti)
     554      {
     555        const std::string& func = *ti;
     556        bool               found = false;
     557
     558        for (wrappers::const_iterator wi = wrappers.begin ();
     559             wi != wrappers.end ();
     560             ++wi)
     561        {
     562          const wrapper&                wrap = *wi;
     563          function_sigs::const_iterator fsi = wrap.sigs.find (func);
     564
     565          if (fsi != wrap.sigs.end ())
     566          {
     567            found = true;
     568
     569            const function_sig& fs = (*fsi).second;
     570
     571            c.write_line("");
     572            c.write_line(fs.decl ());
     573            c.write_line("{");
     574
     575            std::string l;
     576
     577            /*
     578             * @todo Need to define as part of the function signature if ret
     579             *       processing is required.
     580             */
     581            if (fs.ret != "void")
     582            {
     583              c.write_line(" " + fs.ret + " ret;");
     584              l = " ret =";
     585            }
     586
     587            l += " " + wrap.map_sym_prefix + fs.name + '(';
     588            for (size_t a = 0; a < fs.args.size (); ++a)
     589            {
     590              if (a)
     591                l += ", ";
     592              l += "a" + rld::to_string ((int) (a + 1));
     593            }
     594            l += ");";
     595            c.write_line(l);
     596
     597            if (fs.ret != "void")
     598            {
     599              c.write_line(" return ret;");
     600            }
     601
     602            c.write_line("}");
     603          }
     604        }
     605
     606        if (!found)
     607          throw rld::error ("not found", "trace function: " + func);
     608      }
    479609    }
    480610
     
    490620        (*wi).dump (out);
    491621      }
     622      out << "  Code blocks: " << std::endl;
     623      for (rld::strings::const_iterator ci = code.begin ();
     624           ci != code.end ();
     625           ++ci)
     626      {
     627        out << "    > "
     628            << rld::find_replace (*ci, "\n", "\n    | ") << std::endl;
     629      }
    492630    }
    493631
     
    506644
    507645    void
     646    linker::generate_wrapper ()
     647    {
     648      tracer.generate ();
     649    }
     650
     651    void
    508652    linker::dump (std::ostream& out) const
    509653    {
    510654      const rld::config::paths& cpaths = config.get_paths ();
    511       out << "RTEMS Trace Linker" << std::endl
    512           << " Configuration Files: " << cpaths.size () << std::endl;
     655      out << " Configuration Files: " << cpaths.size () << std::endl;
    513656      for (rld::config::paths::const_iterator pi = cpaths.begin ();
    514657           pi != cpaths.end ();
     
    533676  { "verbose",     no_argument,            NULL,           'v' },
    534677  { "warn",        no_argument,            NULL,           'w' },
     678  { "keep",        no_argument,            NULL,           'k' },
    535679  { "exec-prefix", required_argument,      NULL,           'E' },
    536680  { "march",       required_argument,      NULL,           'a' },
     
    550694            << "             to increase verbosity (also --verbose)" << std::endl
    551695            << " -w        : generate warnings (also --warn)" << std::endl
     696            << " -k        : keep temporary files (also --keep)" << std::endl
    552697            << " -E prefix : the RTEMS tool prefix (also --exec-prefix)" << std::endl
    553698            << " -a march  : machine architecture (also --march)" << std::endl
     
    562707  signal (signum, SIG_DFL);
    563708
    564   rld::process::temporaries.clean_up ();
     709  rld::process::temporaries_clean_up ();
    565710
    566711  /*
     
    611756    while (true)
    612757    {
    613       int opt = ::getopt_long (argc, argv, "hvwVE:a:c:C:", rld_opts, NULL);
     758      int opt = ::getopt_long (argc, argv, "hvwkVE:a:c:C:", rld_opts, NULL);
    614759      if (opt < 0)
    615760        break;
     
    633778          break;
    634779
     780        case 'k':
     781          rld::process::set_keep_temporary_files ();
     782          break;
     783
    635784        case 'E':
    636785          exec_prefix_set = true;
     
    688837    {
    689838      linker.load_config (configuration, trace);
    690       linker.dump (std::cout);
     839      linker.generate_wrapper ();
     840
     841      if (rld::verbose ())
     842        linker.dump (std::cout);
    691843    }
    692844    catch (...)
Note: See TracChangeset for help on using the changeset viewer.