source: rtems-tools/rtemstoolkit/rld.cpp @ 5cb66b4

4.105
Last change on this file since 5cb66b4 was b249516, checked in by Chris Johns <chrisj@…>, on 03/29/15 at 07:06:00

rtemstoolkit: Add support to return the system path split as paths.

Seacch the path for the program name if not found and set it as
an absolute path. This allow the prefix to be found.

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/*
2 * Copyright (c) 2011, Chris Johns <chrisj@rtems.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/**
17 * @file
18 *
19 * @ingroup rtems_ld
20 *
21 * @brief RTEMS Linker.
22 *
23 */
24
25#if HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <iostream>
30
31#include <sys/stat.h>
32
33#include <rld.h>
34
35#define RLD_VERSION_MAJOR   (1)
36#define RLD_VERSION_MINOR   (0)
37#define RLD_VERSION_RELEASE (0)
38
39namespace rld
40{
41  static int verbose_level = 0;
42
43  /**
44   * The program's command line.
45   */
46  static std::string cmdline;
47
48  /**
49   * The program name as set by the caller.
50   */
51  static std::string progname;
52
53  /**
54   * The option container.
55   */
56  typedef std::vector < std::string > library_container;
57
58  /**
59   * The libraries the user provided on the command line.
60   */
61  static library_container libpaths;
62
63  /**
64   * The libraries pass on the command line.
65   */
66  static library_container libs;
67
68  /**
69   * The libraries.
70   */
71  static library_container libraries;
72
73  /**
74   * The output passed on the command line.
75   */
76  //static std::string output;
77
78  bool
79  starts_with(const std::string& s1, const std::string& s2)
80  {
81    return s2.size () <= s1.size () && s1.compare (0, s2.size (), s2) == 0;
82  }
83
84  const std::string
85  ltrim (const std::string& s)
86  {
87    std::string t = s;
88    t.erase (t.begin (),
89             std::find_if (t.begin (), t.end (),
90                         std::not1 (std::ptr_fun < int, int > (std::isspace))));
91    return t;
92  }
93
94  const std::string
95  rtrim (const std::string& s)
96  {
97    std::string t = s;
98    t.erase (std::find_if (t.rbegin (), t.rend (),
99                           std::not1 (std::ptr_fun < int, int > (std::isspace))).base(),
100             t.end());
101    return t;
102  }
103
104  const std::string
105  trim (const std::string& s)
106  {
107    return ltrim (rtrim (s));
108  }
109
110  const std::string
111  dequote (const std::string& s)
112  {
113    if (!s.empty ())
114    {
115      char front = s[0];
116      char back = s[s.length () - 1];
117      if ((front == '"') || (front == '\''))
118      {
119        if (front != back)
120          throw rld::error ("invalid quoting", "string: " + s);
121        return s.substr (1, s.length () - (1 + 1));
122      }
123    }
124    return s;
125  }
126
127  const std::string
128  find_replace(const std::string& sin,
129               const std::string& out,
130               const std::string& in)
131  {
132    std::string s = sin;
133    size_t      pos = 0;
134    while ((pos = s.find (out, pos)) != std::string::npos)
135    {
136      s.replace (pos, out.length (), in);
137      pos += in.length ();
138    }
139    return s;
140  }
141
142  const strings
143  split (strings&           se,
144         const std::string& s,
145         char               delimiter,
146         bool               strip_quotes,
147         bool               strip_whitespace,
148         bool               empty)
149  {
150    std::stringstream ss(s);
151    std::string       e;
152    se.clear ();
153    while (std::getline (ss, e, delimiter))
154    {
155      if (strip_whitespace)
156        e = trim (e);
157      if (strip_quotes)
158        e = dequote (e);
159      if (empty || !e.empty ())
160      {
161        se.push_back (e);
162      }
163    }
164    return se;
165  }
166
167  const std::string
168  join (const strings& ss, const std::string& separator)
169  {
170    std::string s;
171    for (strings::const_iterator ssi = ss.begin ();
172         ssi != ss.end ();
173         ++ssi)
174    {
175      s += *ssi;
176      if ((ssi + 1) != ss.end ())
177        s += separator;
178    }
179    return s;
180  }
181
182  const std::string
183  tolower (const std::string& sin)
184  {
185    std::string s = sin;
186    std::transform (s.begin (), s.end (), s.begin (), ::tolower);
187    return s;
188  }
189
190  void
191  verbose_inc ()
192  {
193    ++verbose_level;
194  }
195
196  int
197  verbose (int level)
198  {
199    return verbose_level && (verbose_level >= level) ? verbose_level : 0;
200  }
201
202  const std::string
203  version ()
204  {
205    std::string v = (rld::to_string (RLD_VERSION_MAJOR) + '.' +
206                     rld::to_string (RLD_VERSION_MINOR) + '.' +
207                     rld::to_string (RLD_VERSION_RELEASE));
208    return v;
209  }
210
211  const std::string
212  rtems_version ()
213  {
214    return rld::to_string (RTEMS_VERSION);
215  }
216
217  void
218  set_cmdline (int argc, char* argv[])
219  {
220    cmdline.clear ();
221    for (int arg = 0; arg < argc; ++arg)
222    {
223      std::string a = argv[arg];
224      cmdline += ' ' + a;
225    }
226    cmdline = rld::trim (cmdline);
227  }
228
229  const std::string
230  get_cmdline ()
231  {
232    return cmdline;
233  }
234
235  void
236  set_progname (const std::string& progname_)
237  {
238    if (rld::path::check_file (progname_))
239      progname = rld::path::path_abs (progname_);
240    else
241    {
242      rld::path::paths paths;
243      rld::path::get_system_path (paths);
244      for (rld::path::paths::const_iterator path = paths.begin ();
245           path != paths.end ();
246           ++path)
247      {
248        std::string pp;
249        rld::path::path_join (*path, progname_, pp);
250        if (rld::path::check_file (pp))
251        {
252          progname = rld::path::path_abs (pp);
253          break;
254        }
255      }
256    }
257  }
258
259  const std::string
260  get_progname ()
261  {
262    return progname;
263  }
264
265  const std::string
266  get_program_name ()
267  {
268    return rld::path::basename (progname);
269  }
270
271  const std::string
272  get_program_path ()
273  {
274    return rld::path::dirname (progname);
275  }
276
277  const std::string
278  get_prefix ()
279  {
280    std::string pp = get_program_path ();
281    if (rld::path::basename (pp) == "bin")
282      return rld::path::dirname (pp);
283    return pp;
284  }
285
286  void
287  map (rld::files::cache& cache, rld::symbols::table& symbols)
288  {
289    std::cout << "Archive files    : " << cache.archive_count () << std::endl;
290    std::cout << "Object files     : " << cache.object_count () << std::endl;
291    std::cout << "Exported symbols : " << symbols.size () << std::endl;
292
293    std::cout << "Archives:" << std::endl;
294    cache.output_archive_files (std::cout);
295    std::cout << "Objects:" << std::endl;
296    cache.output_object_files (std::cout);
297
298    std::cout << "Exported symbols:" << std::endl;
299    rld::symbols::output (std::cout, symbols);
300    std::cout << "Unresolved symbols:" << std::endl;
301    cache.output_unresolved_symbols (std::cout);
302  }
303
304  void
305  warn_unused_externals (rld::files::object_list& objects)
306  {
307    bool first = true;
308    for (rld::files::object_list::iterator oli = objects.begin ();
309         oli != objects.end ();
310         ++oli)
311    {
312      rld::files::object&     object = *(*oli);
313      rld::symbols::pointers& externals = object.external_symbols ();
314
315      if (rld::symbols::referenced (externals) != externals.size ())
316      {
317        if (first)
318        {
319          std::cout << "Unreferenced externals in object files:" << std::endl;
320          first = false;
321        }
322
323        std::cout << ' ' << object.name ().basename () << std::endl;
324
325        for (rld::symbols::pointers::iterator sli = externals.begin ();
326             sli != externals.end ();
327             ++sli)
328        {
329          rld::symbols::symbol& sym = *(*sli);
330          if (sym.references () == 0)
331            std::cout << "  " << sym.name () << std::endl;
332        }
333      }
334    }
335  }
336
337}
Note: See TracBrowser for help on using the repository browser.