source: rtems-tools/rtemstoolkit/rld.cpp @ 87e0e76

4.104.11
Last change on this file since 87e0e76 was 87e0e76, checked in by Chris Johns <chrisj@…>, on Sep 13, 2014 at 2:09:16 AM

Refactor code into the RTEMS Toolkit.

  • Property mode set to 100644
File size: 7.0 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    progname = rld::path::path_abs (progname_);
239  }
240
241  const std::string
242  get_progname ()
243  {
244    return progname;
245  }
246
247  const std::string
248  get_program_name ()
249  {
250    return rld::path::basename (progname);
251  }
252
253  const std::string
254  get_program_path ()
255  {
256    return rld::path::dirname (progname);
257  }
258
259  const std::string
260  get_prefix ()
261  {
262    std::string pp = get_program_path ();
263    if (rld::path::basename (pp) == "bin")
264      return rld::path::dirname (pp);
265    return "";
266  }
267
268  void
269  map (rld::files::cache& cache, rld::symbols::table& symbols)
270  {
271    std::cout << "Archive files    : " << cache.archive_count () << std::endl;
272    std::cout << "Object files     : " << cache.object_count () << std::endl;
273    std::cout << "Exported symbols : " << symbols.size () << std::endl;
274
275    std::cout << "Archives:" << std::endl;
276    cache.output_archive_files (std::cout);
277    std::cout << "Objects:" << std::endl;
278    cache.output_object_files (std::cout);
279
280    std::cout << "Exported symbols:" << std::endl;
281    rld::symbols::output (std::cout, symbols);
282    std::cout << "Unresolved symbols:" << std::endl;
283    cache.output_unresolved_symbols (std::cout);
284  }
285
286  void
287  warn_unused_externals (rld::files::object_list& objects)
288  {
289    bool first = true;
290    for (rld::files::object_list::iterator oli = objects.begin ();
291         oli != objects.end ();
292         ++oli)
293    {
294      rld::files::object&     object = *(*oli);
295      rld::symbols::pointers& externals = object.external_symbols ();
296
297      if (rld::symbols::referenced (externals) != externals.size ())
298      {
299        if (first)
300        {
301          std::cout << "Unreferenced externals in object files:" << std::endl;
302          first = false;
303        }
304
305        std::cout << ' ' << object.name ().basename () << std::endl;
306
307        for (rld::symbols::pointers::iterator sli = externals.begin ();
308             sli != externals.end ();
309             ++sli)
310        {
311          rld::symbols::symbol& sym = *(*sli);
312          if (sym.references () == 0)
313            std::cout << "  " << sym.name () << std::endl;
314        }
315      }
316    }
317  }
318
319}
Note: See TracBrowser for help on using the repository browser.