source: rtems-tools/linkers/rtems-syms.cpp @ 977c3de

4.104.11
Last change on this file since 977c3de was 977c3de, checked in by Chris Johns <chrisj@…>, on Nov 17, 2012 at 6:34:33 AM

Refactor the ELF support to allow ELF write suppport.

The refactoring allows better reuse of the ELF support and cleans up
some hacks from the generic file and archive handling improving the
separation of the file handling from the file format, ie ELF. The
handling of ELF object files and ELF object files inside archives
is cleaner.

The refactor cleaned up the symbol handling where the symbols now
reside in the ELF file object and references are take in symbol
pointer containers and symbol table containers.

The main purpose of the refactor is to allow support for creating
and writing ELF files.

Also added an rtems-syms command where special symbol support
can be added.

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*
2 * Copyright (c) 2011-2012, 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_rld
20 *
21 * @brief RTEMS Symbols Main manages opions, sequence of operations and exceptions.
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>
40#include <rld-cc.h>
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/**
50 * RTEMS Linker options. This needs to be rewritten to be like cc where only a
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' },
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' },
65  { NULL,          0,                      NULL,            0 }
66};
67
68void
69usage (int exit_code)
70{
71  std::cout << "rtems-syms [options] objects" << std::endl
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
75            << " -v        : verbose (trace import parts), can be supply multiple times" << std::endl
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
82            << " -S        : search standard libraries (also --stdlibs)" << std::endl
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;
87  ::exit (exit_code);
88}
89
90static void
91fatal_signal (int signum)
92{
93  signal (signum, SIG_DFL);
94
95  rld::process::temporaries.clean_up ();
96
97  /*
98   * Get the same signal again, this time not handled, so its normal effect
99   * occurs.
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;
140    std::string         cc_name;
141    bool                standard_libs = false;
142    bool                exec_prefix_set = false;
143    bool                warnings = false;
144
145    libpaths.push_back (".");
146
147    while (true)
148    {
149      int opt = ::getopt_long (argc, argv, "hvwVSE:L:l:a:c:C:", rld_opts, NULL);
150      if (opt < 0)
151        break;
152
153      switch (opt)
154      {
155        case 'V':
156          std::cout << "rtems-syms (RTEMS Symbols) " << rld::version ()
157                    << std::endl;
158          ::exit (0);
159          break;
160
161        case 'v':
162          rld::verbose_inc ();
163          break;
164
165        case 'w':
166          warnings = true;
167          break;
168
169        case 'l':
170          /*
171           * The order is important. It is the search order.
172           */
173          libs.push_back (optarg);
174          break;
175
176        case 'L':
177          if ((optarg[::strlen (optarg) - 1] == '/') ||
178              (optarg[::strlen (optarg) - 1] == '\\'))
179            optarg[::strlen (optarg) - 1] = '\0';
180          libpaths.push_back (optarg);
181          break;
182
183        case 'S':
184          standard_libs = true;
185          break;
186
187        case 'C':
188          if (exec_prefix_set == true)
189            std::cerr << "warning: exec-prefix ignored when CC provided" << std::endl;
190          rld::cc::cc = optarg;
191          break;
192
193        case 'E':
194          exec_prefix_set = true;
195          rld::cc::exec_prefix = optarg;
196          break;
197
198        case 'a':
199          rld::cc::march = optarg;
200          break;
201
202        case 'c':
203          rld::cc::mcpu = optarg;
204          break;
205
206        case '?':
207          usage (3);
208          break;
209
210        case 'h':
211          usage (0);
212          break;
213      }
214    }
215
216    argc -= optind;
217    argv += optind;
218
219    std::cout << "RTEMS Symbols " << rld::version () << std::endl;
220
221    /*
222     * If there are no object files there is nothing to link.
223     */
224    if (argc == 0)
225      throw rld::error ("no object files", "options");
226
227    /*
228     * Load the remaining command line arguments into the cache as object
229     * files.
230     */
231    while (argc--)
232      objects.push_back (*argv++);
233
234    /*
235     * Add the object files to the cache.
236     */
237    cache.add (objects);
238
239    /*
240     * Open the cache.
241     */
242    cache.open ();
243
244    /*
245     * If the full path to CC is not provided and the exec-prefix is not set by
246     * the command line see if it can be detected from the object file
247     * types. This must be after we have added the object files because they
248     * are used when detecting.
249     */
250    if (rld::cc::cc.empty () && !exec_prefix_set)
251      rld::cc::exec_prefix = rld::elf::machine_type ();
252
253    /*
254     * Get the standard library paths
255     */
256    rld::cc::get_standard_libpaths (libpaths);
257
258    /*
259     * Get the command line libraries.
260     */
261    rld::files::find_libraries (libraries, libpaths, libs);
262
263    /*
264     * Are we to load standard libraries ?
265     */
266    if (standard_libs)
267      rld::cc::get_standard_libs (libraries, libpaths);
268
269    /*
270     * Load the library to the cache.
271     */
272    cache.add_libraries (libraries);
273
274    /*
275     * Load the symbol table.
276     */
277    cache.load_symbols (symbols);
278
279    rld::map (cache, symbols);
280  }
281  catch (rld::error re)
282  {
283    std::cerr << "error: "
284              << re.where << ": " << re.what
285              << std::endl;
286    ec = 10;
287  }
288  catch (std::exception e)
289  {
290    int   status;
291    char* realname;
292    realname = abi::__cxa_demangle (e.what(), 0, 0, &status);
293    std::cerr << "error: exception: " << realname << " [";
294    ::free (realname);
295    const std::type_info &ti = typeid (e);
296    realname = abi::__cxa_demangle (ti.name(), 0, 0, &status);
297    std::cerr << realname << "] " << e.what () << std::endl;
298    ::free (realname);
299    ec = 11;
300  }
301  catch (...)
302  {
303    /*
304     * Helps to know if this happens.
305     */
306    std::cout << "error: unhandled exception" << std::endl;
307    ec = 12;
308  }
309
310  return ec;
311}
Note: See TracBrowser for help on using the repository browser.