source: rtems-tools/linkers/rtems-syms.cpp @ a136346

4.104.115
Last change on this file since a136346 was a136346, checked in by Chris Johns <chrisj@…>, on 08/05/14 at 13:01:15

Fix temporary file handling and add tempfile write support.

Move the static objects into the rld-process file and change the
clean up to a call.

Add support to write to tempfiles.

  • Property mode set to 100644
File size: 9.1 KB
RevLine 
[ec24a37]1/*
[7461924]2 * Copyright (c) 2011-2012, Chris Johns <chrisj@rtems.org>
[ec24a37]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.
[aef6d90]7 *
[ec24a37]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_rld
20 *
[977c3de]21 * @brief RTEMS Symbols Main manages opions, sequence of operations and exceptions.
[ec24a37]22 *
23 */
24
25#if HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <iostream>
30
31#include <cxxabi.h>
32#include <signal.h>
33#include <stdlib.h>
34#include <string.h>
35#include <unistd.h>
36
37#include <getopt.h>
38
39#include <rld.h>
[7461924]40#include <rld-cc.h>
[ec24a37]41#include <rld-outputter.h>
42#include <rld-process.h>
43#include <rld-resolver.h>
44
45#ifndef HAVE_KILL
46#define kill(p,s) raise(s)
47#endif
48
49/**
[7461924]50 * RTEMS Linker options. This needs to be rewritten to be like cc where only a
[ec24a37]51 * single '-' and long options is present.
52 */
53static struct option rld_opts[] = {
54  { "help",        no_argument,            NULL,           'h' },
55  { "version",     no_argument,            NULL,           'V' },
56  { "verbose",     no_argument,            NULL,           'v' },
57  { "warn",        no_argument,            NULL,           'w' },
58  { "lib-path",    required_argument,      NULL,           'L' },
59  { "lib",         required_argument,      NULL,           'l' },
60  { "no-stdlibs",  no_argument,            NULL,           'n' },
[7461924]61  { "cc",          required_argument,      NULL,           'C' },
62  { "exec-prefix", required_argument,      NULL,           'E' },
63  { "march",       required_argument,      NULL,           'a' },
64  { "mcpu",        required_argument,      NULL,           'c' },
[ec24a37]65  { NULL,          0,                      NULL,            0 }
66};
67
68void
69usage (int exit_code)
70{
[977c3de]71  std::cout << "rtems-syms [options] objects" << std::endl
[aef6d90]72            << "Options and arguments:" << std::endl
73            << " -h        : help (also --help)" << std::endl
74            << " -V        : print linker version number and exit (also --version)" << std::endl
[6c4218b]75            << " -v        : verbose (trace import parts), can supply multiple times" << std::endl
[aef6d90]76            << "             to increase verbosity (also --verbose)" << std::endl
77            << " -w        : generate warnings (also --warn)" << std::endl
78            << " -L path   : path to a library, add multiple for more than" << std::endl
79            << "             one path (also --lib-path)" << std::endl
80            << " -l lib    : add lib to the libraries searched, add multiple" << std::endl
81            << "             for more than one library (also --lib)" << std::endl
[977c3de]82            << " -S        : search standard libraries (also --stdlibs)" << std::endl
[7461924]83            << " -C file   : execute file as the target C compiler (also --cc)" << std::endl
84            << " -E prefix : the RTEMS tool prefix (also --exec-prefix)" << std::endl
85            << " -a march  : machine architecture (also --march)" << std::endl
86            << " -c cpu    : machine architecture's CPU (also --mcpu)" << std::endl;
[ec24a37]87  ::exit (exit_code);
88}
89
90static void
91fatal_signal (int signum)
92{
93  signal (signum, SIG_DFL);
94
[a136346]95  rld::process::temporaries_clean_up ();
[ec24a37]96
[aef6d90]97  /*
[ec24a37]98   * Get the same signal again, this time not handled, so its normal effect
[aef6d90]99   * occurs.
[ec24a37]100   */
101  kill (getpid (), signum);
102}
103
104static void
105setup_signals (void)
106{
107  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
108    signal (SIGINT, fatal_signal);
109#ifdef SIGHUP
110  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
111    signal (SIGHUP, fatal_signal);
112#endif
113  if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
114    signal (SIGTERM, fatal_signal);
115#ifdef SIGPIPE
116  if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
117    signal (SIGPIPE, fatal_signal);
118#endif
119#ifdef SIGCHLD
120  signal (SIGCHLD, SIG_DFL);
121#endif
122}
123
124int
125main (int argc, char* argv[])
126{
127  int ec = 0;
128
129  setup_signals ();
130
131  try
132  {
133    rld::files::cache   cache;
134    rld::files::paths   libpaths;
135    rld::files::paths   libs;
136    rld::files::paths   objects;
137    rld::files::paths   libraries;
138    rld::symbols::table symbols;
139    std::string         base_name;
[7461924]140    std::string         cc_name;
[977c3de]141    bool                standard_libs = false;
[ec24a37]142    bool                exec_prefix_set = false;
[9ba4e48]143#if HAVE_WARNINGS
[ec24a37]144    bool                warnings = false;
[9ba4e48]145#endif
[ec24a37]146
147    libpaths.push_back (".");
148
149    while (true)
150    {
[977c3de]151      int opt = ::getopt_long (argc, argv, "hvwVSE:L:l:a:c:C:", rld_opts, NULL);
[ec24a37]152      if (opt < 0)
153        break;
[aef6d90]154
[ec24a37]155      switch (opt)
156      {
157        case 'V':
[977c3de]158          std::cout << "rtems-syms (RTEMS Symbols) " << rld::version ()
[ec24a37]159                    << std::endl;
160          ::exit (0);
161          break;
[aef6d90]162
[ec24a37]163        case 'v':
164          rld::verbose_inc ();
165          break;
[aef6d90]166
[ec24a37]167        case 'w':
[9ba4e48]168#if HAVE_WARNINGS
[ec24a37]169          warnings = true;
[9ba4e48]170#endif
[ec24a37]171          break;
172
173        case 'l':
174          /*
175           * The order is important. It is the search order.
176           */
177          libs.push_back (optarg);
178          break;
179
180        case 'L':
181          if ((optarg[::strlen (optarg) - 1] == '/') ||
182              (optarg[::strlen (optarg) - 1] == '\\'))
183            optarg[::strlen (optarg) - 1] = '\0';
184          libpaths.push_back (optarg);
185          break;
186
[977c3de]187        case 'S':
188          standard_libs = true;
[ec24a37]189          break;
190
[7461924]191        case 'C':
192          if (exec_prefix_set == true)
193            std::cerr << "warning: exec-prefix ignored when CC provided" << std::endl;
194          rld::cc::cc = optarg;
195          break;
196
[ec24a37]197        case 'E':
198          exec_prefix_set = true;
[7461924]199          rld::cc::exec_prefix = optarg;
[ec24a37]200          break;
201
202        case 'a':
[7461924]203          rld::cc::march = optarg;
[ec24a37]204          break;
205
206        case 'c':
[7461924]207          rld::cc::mcpu = optarg;
[ec24a37]208          break;
209
210        case '?':
211          usage (3);
212          break;
213
214        case 'h':
215          usage (0);
216          break;
217      }
218    }
219
220    argc -= optind;
221    argv += optind;
222
[977c3de]223    std::cout << "RTEMS Symbols " << rld::version () << std::endl;
[ec24a37]224
225    /*
226     * If there are no object files there is nothing to link.
227     */
[977c3de]228    if (argc == 0)
[ec24a37]229      throw rld::error ("no object files", "options");
230
231    /*
232     * Load the remaining command line arguments into the cache as object
233     * files.
234     */
235    while (argc--)
236      objects.push_back (*argv++);
[aef6d90]237
[ec24a37]238    /*
239     * Add the object files to the cache.
240     */
241    cache.add (objects);
242
243    /*
244     * Open the cache.
245     */
246    cache.open ();
247
248    /*
[7461924]249     * If the full path to CC is not provided and the exec-prefix is not set by
250     * the command line see if it can be detected from the object file
251     * types. This must be after we have added the object files because they
252     * are used when detecting.
[ec24a37]253     */
[7461924]254    if (rld::cc::cc.empty () && !exec_prefix_set)
255      rld::cc::exec_prefix = rld::elf::machine_type ();
[ec24a37]256
257    /*
258     * Get the standard library paths
259     */
[9b66527]260    if (standard_libs)
261      rld::cc::get_standard_libpaths (libpaths);
[ec24a37]262
263    /*
264     * Get the command line libraries.
265     */
266    rld::files::find_libraries (libraries, libpaths, libs);
267
268    /*
269     * Are we to load standard libraries ?
270     */
271    if (standard_libs)
[7461924]272      rld::cc::get_standard_libs (libraries, libpaths);
[ec24a37]273
274    /*
275     * Load the library to the cache.
276     */
277    cache.add_libraries (libraries);
278
279    /*
[8190102]280     * Begin the archive session. This opens the archives and leaves them open
281     * while we the symbol table is being used. The symbols reference object
282     * files and the object files may reference archives and it is assumed they
283     * are open and available. It is also assumed the number of library
284     * archives being managed is less than the maximum file handles this
285     * process can have open at any one time. If this is not the case this
286     * approach would need to be reconsidered and the overhead of opening and
287     * closing archives added.
[ec24a37]288     */
[8190102]289    try
290    {
291      /*
292       * Load the symbol table.
293       */
294      cache.load_symbols (symbols);
295
296      rld::map (cache, symbols);
297    }
298    catch (...)
299    {
300      cache.archives_end ();
301      throw;
302    }
[ec24a37]303
[8190102]304    cache.archives_end ();
[ec24a37]305  }
306  catch (rld::error re)
307  {
308    std::cerr << "error: "
309              << re.where << ": " << re.what
310              << std::endl;
311    ec = 10;
312  }
313  catch (std::exception e)
[aef6d90]314  {
[ec24a37]315    int   status;
316    char* realname;
317    realname = abi::__cxa_demangle (e.what(), 0, 0, &status);
[977c3de]318    std::cerr << "error: exception: " << realname << " [";
[ec24a37]319    ::free (realname);
320    const std::type_info &ti = typeid (e);
321    realname = abi::__cxa_demangle (ti.name(), 0, 0, &status);
322    std::cerr << realname << "] " << e.what () << std::endl;
323    ::free (realname);
324    ec = 11;
325  }
326  catch (...)
[aef6d90]327  {
[ec24a37]328    /*
329     * Helps to know if this happens.
330     */
331    std::cout << "error: unhandled exception" << std::endl;
332    ec = 12;
333  }
334
335  return ec;
336}
Note: See TracBrowser for help on using the repository browser.