source: rtems-tools/linkers/rtems-rapper.cpp @ 6c4218b

4.104.115
Last change on this file since 6c4218b was 6c4218b, checked in by Chris Johns <chrisj@…>, on 03/01/13 at 00:51:37

Fix the trace help.

  • Property mode set to 100644
File size: 28.0 KB
Line 
1/*
2 * Copyright (c) 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 RAP Manager lets you look at and play with RAP files.
22 *
23 */
24
25#if HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <algorithm>
30#include <iomanip>
31#include <iostream>
32#include <vector>
33
34#include <cxxabi.h>
35#include <signal.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>
39
40#include <getopt.h>
41
42#include <rld.h>
43#include <rld-compression.h>
44#include <rld-files.h>
45#include <rld-process.h>
46#include <rld-rap.h>
47
48#include <rtems-utils.h>
49
50#ifndef HAVE_KILL
51#define kill(p,s) raise(s)
52#endif
53
54/**
55 * RTEMS Application.
56 */
57namespace rap
58{
59  /**
60   * A relocation record.
61   */
62  struct relocation
63  {
64    uint32_t    info;
65    uint32_t    offset;
66    uint32_t    addend;
67    std::string symname;
68    off_t       rap_off;
69
70    relocation ();
71
72    void output ();
73  };
74
75  typedef std::vector < relocation > relocations;
76
77  /**
78   * Relocation offset sorter for the relocations container.
79   */
80  class reloc_offset_compare
81  {
82  public:
83    bool operator () (const relocation& lhs,
84                      const relocation& rhs) const {
85      return lhs.offset < rhs.offset;
86    }
87  };
88
89  /**
90   * A RAP section.
91   */
92  struct section
93  {
94    std::string name;
95    uint32_t    size;
96    uint32_t    alignment;
97    uint8_t*    data;
98    uint32_t    relocs_size;
99    relocations relocs;
100    bool        rela;
101    off_t       rap_off;
102
103    section ();
104    ~section ();
105
106    void load_data (rld::compress::compressor& comp);
107    void load_relocs (rld::compress::compressor& comp);
108  };
109
110  /**
111   * A RAP file.
112   */
113  struct file
114  {
115    enum {
116      rap_comp_buffer = 2 * 1024
117    };
118
119    std::string header;
120    size_t      rhdr_len;
121    uint32_t    rhdr_length;
122    uint32_t    rhdr_version;
123    std::string rhdr_compression;
124    uint32_t    rhdr_checksum;
125
126    off_t       machine_rap_off;
127    uint32_t    machinetype;
128    uint32_t    datatype;
129    uint32_t    class_;
130
131    off_t       layout_rap_off;
132    std::string init;
133    uint32_t    init_off;
134    std::string fini;
135    uint32_t    fini_off;
136
137    off_t       strtab_rap_off;
138    uint32_t    strtab_size;
139    uint8_t*    strtab;
140
141    off_t       symtab_rap_off;
142    uint32_t    symtab_size;
143    uint8_t*    symtab;
144
145    off_t       relocs_rap_off;
146    uint32_t    relocs_size; /* not used */
147
148    section     secs[rld::rap::rap_secs];
149
150    /**
151     * Open a RAP file and read the header.
152     */
153    file (const std::string& name, bool warnings);
154
155    /**
156     * Close the RAP file.
157     */
158    ~file ();
159
160    /**
161     * Parse header.
162     */
163    void parse_header ();
164
165    /**
166     * Load the file.
167     */
168    void load ();
169
170    /**
171     * Expand the image.
172     */
173    void expand ();
174
175    /**
176     * The name.
177     */
178    const std::string name () const;
179
180    /**
181     * The number of symbols in the symbol table.
182     */
183    int symbols () const;
184
185    /**
186     * Return a symbol given an index.
187     */
188    void symbol (int       index,
189                 uint32_t& data,
190                 uint32_t& name,
191                 uint32_t& value) const;
192
193    /**
194     * Return the string from the string table.
195     */
196    const char* string (int index);
197
198  private:
199
200    bool              warnings;
201    rld::files::image image;
202  };
203
204  template < typename T > T
205  get_value (const uint8_t* data)
206  {
207    T v = 0;
208    for (size_t b = 0; b < sizeof (T); ++b)
209    {
210      v <<= 8;
211      v |= (T) data[b];
212    }
213    return v;
214  }
215
216  relocation::relocation ()
217    : info (0),
218      offset (0),
219      addend (0),
220      rap_off (0)
221  {
222  }
223
224  void
225  relocation::output ()
226  {
227    std::cout << std::hex << std::setfill ('0')
228              << "0x" << std::setw (8) << info
229              << " 0x" << std::setw (8) << offset
230              << " 0x" << std::setw(8) << addend
231              << std::dec << std::setfill (' ')
232              << " " << symname;
233  }
234
235  section::section ()
236    : size (0),
237      alignment (0),
238      data (0),
239      relocs_size (0),
240      relocs (0),
241      rela (false),
242      rap_off (0)
243  {
244  }
245
246  section::~section ()
247  {
248    if (data)
249      delete [] data;
250  }
251
252  void
253  section::load_data (rld::compress::compressor& comp)
254  {
255    rap_off = comp.offset ();
256    if (size)
257    {
258      data = new uint8_t[size];
259      if (comp.read (data, size) != size)
260        throw rld::error ("Reading section data failed", "rapper");
261    }
262  }
263
264  void
265  section::load_relocs (rld::compress::compressor& comp)
266  {
267    uint32_t header;
268    comp >> header;
269
270    rela = header & RAP_RELOC_RELA ? true : false;
271    relocs_size = header & ~RAP_RELOC_RELA;
272
273    if (relocs_size)
274    {
275      for (uint32_t r = 0; r < relocs_size; ++r)
276      {
277        relocation reloc;
278
279        reloc.rap_off = comp.offset ();
280
281        comp >> reloc.info
282             >> reloc.offset;
283
284        if (((reloc.info & RAP_RELOC_STRING) == 0) || rela)
285          comp >> reloc.addend;
286
287        if ((reloc.info & RAP_RELOC_STRING) != 0)
288        {
289          if ((reloc.info & RAP_RELOC_STRING_EMBED) == 0)
290          {
291            size_t symname_size = (reloc.info & ~(3 << 30)) >> 8;
292            reloc.symname.resize (symname_size);
293            size_t symname_read = comp.read ((void*) reloc.symname.c_str (), symname_size);
294            if (symname_read != symname_size)
295              throw rld::error ("Reading reloc symbol name failed", "rapper");
296          }
297        }
298
299        relocs.push_back (reloc);
300      }
301
302      std::stable_sort (relocs.begin (), relocs.end (), reloc_offset_compare ());
303    }
304  }
305
306  file::file (const std::string& name, bool warnings)
307    : rhdr_len (0),
308      rhdr_length (0),
309      rhdr_version (0),
310      rhdr_checksum (0),
311      machine_rap_off (0),
312      machinetype (0),
313      datatype (0),
314      class_ (0),
315      layout_rap_off (0),
316      init_off (0),
317      fini_off (0),
318      strtab_rap_off (0),
319      strtab_size (0),
320      strtab (0),
321      symtab_rap_off (0),
322      symtab_size (0),
323      symtab (0),
324      relocs_rap_off (0),
325      relocs_size (0),
326      warnings (warnings),
327      image (name)
328  {
329    for (int s = 0; s < rld::rap::rap_secs; ++s)
330      secs[s].name = rld::rap::section_name (s);
331    image.open ();
332    parse_header ();
333  }
334
335  file::~file ()
336  {
337    image.close ();
338
339    if (symtab)
340      delete [] symtab;
341    if (strtab)
342      delete [] strtab;
343  }
344
345  void
346  file::parse_header ()
347  {
348    std::string name = image.name ().full ();
349
350    char rhdr[64];
351
352    image.seek_read (0, (uint8_t*) rhdr, 64);
353
354    if ((rhdr[0] != 'R') || (rhdr[1] != 'A') || (rhdr[2] != 'P') || (rhdr[3] != ','))
355      throw rld::error ("Invalid RAP file", "open: " + name);
356
357    char* sptr = rhdr + 4;
358    char* eptr;
359
360    rhdr_length = ::strtoul (sptr, &eptr, 10);
361
362    if (*eptr != ',')
363      throw rld::error ("Cannot parse RAP header", "open: " + name);
364
365    sptr = eptr + 1;
366
367    rhdr_version = ::strtoul (sptr, &eptr, 10);
368
369    if (*eptr != ',')
370      throw rld::error ("Cannot parse RAP header", "open: " + name);
371
372    sptr = eptr + 1;
373
374    if ((sptr[0] == 'N') &&
375        (sptr[1] == 'O') &&
376        (sptr[2] == 'N') &&
377        (sptr[3] == 'E'))
378    {
379      rhdr_compression = "NONE";
380      eptr = sptr + 4;
381    }
382    else if ((sptr[0] == 'L') &&
383             (sptr[1] == 'Z') &&
384             (sptr[2] == '7') &&
385             (sptr[3] == '7'))
386    {
387      rhdr_compression = "LZ77";
388      eptr = sptr + 4;
389    }
390    else
391      throw rld::error ("Cannot parse RAP header", "open: " + name);
392
393    if (*eptr != ',')
394      throw rld::error ("Cannot parse RAP header", "open: " + name);
395
396    sptr = eptr + 1;
397
398    rhdr_checksum = ::strtoul (sptr, &eptr, 16);
399
400    if (*eptr != '\n')
401      throw rld::error ("Cannot parse RAP header", "open: " + name);
402
403    rhdr_len = eptr - rhdr + 1;
404
405    if (warnings && (rhdr_length != image.size ()))
406      std::cout << " warning: header length does not match file size: header="
407                << rhdr_length
408                << " file-size=" << image.size ()
409                << std::endl;
410
411    header.insert (0, rhdr, rhdr_len);
412
413    image.seek (rhdr_len);
414  }
415
416  void
417  file::load ()
418  {
419    image.seek (rhdr_len);
420
421    rld::compress::compressor comp (image, rap_comp_buffer, false);
422
423    /*
424     * uint32_t: machinetype
425     * uint32_t: datatype
426     * uint32_t: class
427     */
428    machine_rap_off = comp.offset ();
429    comp >> machinetype
430         >> datatype
431         >> class_;
432
433    /*
434     * uint32_t: init
435     * uint32_t: fini
436     * uint32_t: symtab_size
437     * uint32_t: strtab_size
438     * uint32_t: relocs_size
439     */
440    layout_rap_off = comp.offset ();
441    comp >> init_off
442         >> fini_off
443         >> symtab_size
444         >> strtab_size
445         >> relocs_size;
446
447    /*
448     * uint32_t: text_size
449     * uint32_t: text_alignment
450     * uint32_t: const_size
451     * uint32_t: const_alignment
452     * uint32_t: ctor_size
453     * uint32_t: ctor_alignment
454     * uint32_t: dtor_size
455     * uint32_t: dtor_alignment
456     * uint32_t: data_size
457     * uint32_t: data_alignment
458     * uint32_t: bss_size
459     * uint32_t: bss_alignment
460     */
461    for (int s = 0; s < rld::rap::rap_secs; ++s)
462      comp >> secs[s].size
463           >> secs[s].alignment;
464
465    /*
466     * Load sections.
467     */
468    for (int s = 0; s < rld::rap::rap_secs; ++s)
469      if (s != rld::rap::rap_bss)
470        secs[s].load_data (comp);
471
472    /*
473     * Load the string table.
474     */
475    strtab_rap_off = comp.offset ();
476    if (strtab_size)
477    {
478      strtab = new uint8_t[strtab_size];
479      if (comp.read (strtab, strtab_size) != strtab_size)
480        throw rld::error ("Reading string table failed", "rapper");
481    }
482
483    /*
484     * Load the symbol table.
485     */
486    symtab_rap_off = comp.offset ();
487    if (symtab_size)
488    {
489      symtab = new uint8_t[symtab_size];
490      if (comp.read (symtab, symtab_size) != symtab_size)
491        throw rld::error ("Reading symbol table failed", "rapper");
492    }
493
494    /*
495     * Load the relocation tables.
496     */
497    relocs_rap_off = comp.offset ();
498    for (int s = 0; s < rld::rap::rap_secs; ++s)
499      secs[s].load_relocs (comp);
500  }
501
502  void
503  file::expand ()
504  {
505    std::string name = image.name ().full ();
506    std::string extension = rld::files::extension (image.name ().full ());
507
508    name = name.substr (0, name.size () - extension.size ()) + ".xrap";
509
510    image.seek (rhdr_len);
511
512    rld::compress::compressor comp (image, rap_comp_buffer, false);
513    rld::files::image         out (name);
514
515    out.open (true);
516    out.seek (0);
517    while (true)
518    {
519      if (comp.read (out, rap_comp_buffer) != rap_comp_buffer)
520        break;
521    }
522    out.close ();
523  }
524
525  const std::string
526  file::name () const
527  {
528    return image.name ().full ();
529  }
530
531  int
532  file::symbols () const
533  {
534    return symtab_size / (3 * sizeof (uint32_t));
535  }
536
537  void
538  file::symbol (int index, uint32_t& data, uint32_t& name, uint32_t& value) const
539  {
540    if (index < symbols ())
541    {
542      uint8_t* sym = symtab + (index * 3 * sizeof (uint32_t));
543      data  = get_value < uint32_t > (sym);
544      name  = get_value < uint32_t > (sym + (1 * sizeof (uint32_t)));
545      value = get_value < uint32_t > (symtab + (2 * sizeof (uint32_t)));
546    }
547  }
548
549  const char*
550  file::string (int index)
551  {
552    std::string name = image.name ().full ();
553
554    if (strtab_size == 0)
555      throw rld::error ("No string table", "string: " + name);
556
557    uint32_t offset = 0;
558    int count = 0;
559    while (offset < strtab_size)
560    {
561      if (count++ == index)
562        return (const char*) &strtab[offset];
563      offset = ::strlen ((const char*) &strtab[offset]) + 1;
564    }
565
566    throw rld::error ("Invalid string index", "string: " + name);
567  }
568}
569
570void
571rap_show (rld::files::paths& raps,
572          bool               warnings,
573          bool               show_header,
574          bool               show_machine,
575          bool               show_layout,
576          bool               show_strings,
577          bool               show_symbols,
578          bool               show_relocs)
579{
580  for (rld::files::paths::iterator pi = raps.begin();
581       pi != raps.end();
582       ++pi)
583  {
584    std::cout  << *pi << ':' << std::endl;
585
586    rap::file r (*pi, warnings);
587
588    try
589    {
590      r.load ();
591    }
592    catch (rld::error re)
593    {
594      std::cout << " error: "
595                << re.where << ": " << re.what
596                << std::endl
597                << " warning: file read failed, some data may be corrupt or not present."
598                << std::endl;
599    }
600
601    if (show_header)
602    {
603      std::cout << "  Header:" << std::endl
604                << "          string: " << r.header
605                << "          length: " << r.rhdr_len << std::endl
606                << "         version: " << r.rhdr_version << std::endl
607                << "     compression: " << r.rhdr_compression << std::endl
608                << std::hex << std::setfill ('0')
609                << "        checksum: " << std::setw (8) << r.rhdr_checksum << std::endl
610                << std::dec << std::setfill(' ');
611    }
612
613    if (show_machine)
614    {
615      std::cout << "  Machine: 0x"
616                << std::hex << std::setfill ('0')
617                << std::setw (8) << r.machine_rap_off
618                << std::setfill (' ') << std::dec
619                << " (" << r.machine_rap_off << ')' << std::endl
620                << "     machinetype: "<< r.machinetype << std::endl
621                << "        datatype: "<< r.datatype << std::endl
622                << "           class: "<< r.class_ << std::endl;
623    }
624
625    if (show_layout)
626    {
627      std::cout << "  Layout: 0x"
628                << std::hex << std::setfill ('0')
629                << std::setw (8) << r.layout_rap_off
630                << std::setfill (' ') << std::dec
631                << " (" << r.layout_rap_off << ')' << std::endl
632                << std::setw (18) << "  "
633                << "  size  align offset    " << std::endl;
634      uint32_t relocs_size = 0;
635      for (int s = 0; s < rld::rap::rap_secs; ++s)
636      {
637        relocs_size += r.secs[s].relocs.size ();
638        std::cout << std::setw (16) << rld::rap::section_name (s)
639                  << ": " << std::setw (6) << r.secs[s].size
640                  << std::setw (7)  << r.secs[s].alignment;
641        if (s != rld::rap::rap_bss)
642          std::cout << std::hex << std::setfill ('0')
643                    << " 0x" << std::setw (8) << r.secs[s].rap_off
644                    << std::setfill (' ') << std::dec
645                    << " (" << r.secs[s].rap_off << ')';
646        else
647          std::cout << " -";
648        std::cout << std::endl;
649      }
650      std::cout << std::setw (16) << "strtab" << ": "
651                << std::setw (6) << r.strtab_size
652                << std::setw (7) << '-'
653                << std::hex << std::setfill ('0')
654                << " 0x" << std::setw (8) << r.strtab_rap_off
655                << std::setfill (' ') << std::dec
656                << " (" << r.strtab_rap_off << ')' << std::endl
657                << std::setw (16) << "symtab" << ": "
658                << std::setw (6) << r.symtab_size
659                << std::setw (7) << '-'
660                << std::hex << std::setfill ('0')
661                << " 0x" << std::setw (8) << r.symtab_rap_off
662                << std::setfill (' ') << std::dec
663                << " (" << r.symtab_rap_off << ')' << std::endl
664                << std::setw (16) << "relocs" << ": "
665                << std::setw (6) << (relocs_size * 3 * sizeof (uint32_t))
666                << std::setw (7) << '-'
667                << std::hex << std::setfill ('0')
668                << " 0x" << std::setw (8) << r.relocs_rap_off
669                << std::setfill (' ') << std::dec
670                << " (" << r.relocs_rap_off << ')' << std::endl;
671    }
672
673    if (show_strings)
674    {
675      std::cout << "  Strings: 0x"
676                << std::hex << std::setfill ('0')
677                << std::setw (8) << r.strtab_rap_off
678                << std::setfill (' ') << std::dec
679                << " (" << r.strtab_rap_off << ')'
680                << " size: " << r.strtab_size
681                << std::endl;
682      if (r.strtab_size)
683      {
684        uint32_t offset = 0;
685        int count = 0;
686        while (offset < r.strtab_size)
687        {
688          std::cout << std::setw (16) << count++
689                    << std::hex << std::setfill ('0')
690                    << " (0x" << std::setw (6) << offset << "): "
691                    << std::dec << std::setfill (' ')
692                    << (char*) &r.strtab[offset] << std::endl;
693          offset += ::strlen ((char*) &r.strtab[offset]) + 1;
694        }
695      }
696      else
697      {
698        std::cout << std::setw (16) << " "
699                  << "No string table found." << std::endl;
700      }
701    }
702
703    if (show_symbols)
704    {
705      std::cout << "  Symbols: 0x"
706                << std::hex << std::setfill ('0')
707                << std::setw (8) << r.symtab_rap_off
708                << std::setfill (' ') << std::dec
709                << " (" << r.symtab_rap_off << ')'
710                << " size: " << r.symtab_size
711                << std::endl;
712      if (r.symtab_size)
713      {
714        std::cout << std::setw (18) << "  "
715                  << "  data section  value      name" << std::endl;
716        for (int s = 0; s < r.symbols (); ++s)
717        {
718          uint32_t data;
719          uint32_t name;
720          uint32_t value;
721          r.symbol (s, data, name, value);
722          std::cout << std::setw (16) << s << ": "
723                    << std::hex << std::setfill ('0')
724                    << "0x" << std::setw (4) << (data & 0xffff)
725                    << std::dec << std::setfill (' ')
726                    << " " << std::setw (8) << rld::rap::section_name (data >> 16)
727                    << std::hex << std::setfill ('0')
728                    << " 0x" << std::setw(8) << value
729                    << " " << &r.strtab[name]
730                    << std::dec << std::setfill (' ')
731                    << std::endl;
732        }
733      }
734      else
735      {
736        std::cout << std::setw (16) << " "
737                  << "No symbol table found." << std::endl;
738      }
739    }
740
741    if (show_relocs)
742    {
743      std::cout << "  Relocations: 0x"
744                << std::hex << std::setfill ('0')
745                << std::setw (8) << r.relocs_rap_off
746                << std::setfill (' ') << std::dec
747                << " (" << r.relocs_rap_off << ')' << std::endl;
748      int count = 0;
749      for (int s = 0; s < rld::rap::rap_secs; ++s)
750      {
751        if (r.secs[s].relocs.size ())
752        {
753          std::cout << std::setw (16) << r.secs[s].name
754                    << ": info       offset     addend     symbol name" << std::endl;
755          for (size_t f = 0; f < r.secs[s].relocs.size (); ++f)
756          {
757            rap::relocation& reloc = r.secs[s].relocs[f];
758            std::cout << std::setw (16) << count++ << ": ";
759            reloc.output ();
760            std::cout << std::endl;
761          }
762        }
763      }
764    }
765  }
766
767}
768
769void
770rap_overlay (rld::files::paths& raps, bool warnings)
771{
772  std::cout << "Overlay .... " << std::endl;
773  for (rld::files::paths::iterator pi = raps.begin();
774       pi != raps.end();
775       ++pi)
776  {
777    rap::file r (*pi, warnings);
778    std::cout << r.name () << std::endl;
779
780    r.load ();
781
782    for (int s = 0; s < rld::rap::rap_secs; ++s)
783    {
784      rap::section& sec = r.secs[s];
785
786      if (sec.size && sec.data)
787      {
788        std::cout << rld::rap::section_name (s) << ':' << std::endl;
789
790        size_t   line_length = 16;
791        uint32_t offset = 0;
792        size_t   reloc = 0;
793
794        while (offset < sec.size)
795        {
796          size_t length = sec.size - offset;
797
798          if (reloc < sec.relocs.size ())
799            length = sec.relocs[reloc].offset - offset;
800
801          if ((offset + length) < sec.size)
802          {
803            length += line_length;
804            length -= length % line_length;
805          }
806
807          rtems::utils::dump (sec.data + offset,
808                              length,
809                              sizeof (uint8_t),
810                              false,
811                              line_length,
812                              offset);
813
814          const int          indent = 8;
815          std::ostringstream line;
816
817          line << std::setw (indent) << ' ';
818
819          while ((reloc < sec.relocs.size ()) &&
820                 (sec.relocs[reloc].offset >= offset) &&
821                 (sec.relocs[reloc].offset < (offset + length)))
822          {
823            int spaces = ((((sec.relocs[reloc].offset + 1) % line_length) * 3) +
824                          indent - 1);
825
826            spaces -= line.str ().size ();
827
828            line << std::setw (spaces) << " ^" << reloc
829                 << ':' << std::hex
830                 << sec.relocs[reloc].addend
831                 << std::dec;
832
833            ++reloc;
834          }
835
836          std::cout << line.str () << std::endl;
837
838          offset += length;
839        }
840
841        if (sec.relocs.size ())
842        {
843          int count = 0;
844          std::cout << "     info       offset     addend     symbol name" << std::endl;
845          for (size_t f = 0; f < r.secs[s].relocs.size (); ++f)
846          {
847            rap::relocation& reloc = r.secs[s].relocs[f];
848            std::cout << std::setw (4) << count++ << ' ';
849            reloc.output ();
850            std::cout << std::endl;
851          }
852        }
853
854      }
855    }
856  }
857}
858
859void
860rap_expander (rld::files::paths& raps, bool warnings)
861{
862  std::cout << "Expanding .... " << std::endl;
863  for (rld::files::paths::iterator pi = raps.begin();
864       pi != raps.end();
865       ++pi)
866  {
867    rap::file r (*pi, warnings);
868    std::cout << ' ' << r.name () << std::endl;
869    r.expand ();
870  }
871}
872
873/**
874 * RTEMS RAP options.
875 */
876static struct option rld_opts[] = {
877  { "help",        no_argument,            NULL,           'h' },
878  { "version",     no_argument,            NULL,           'V' },
879  { "verbose",     no_argument,            NULL,           'v' },
880  { "no-warn",     no_argument,            NULL,           'n' },
881  { "all",         no_argument,            NULL,           'a' },
882  { "header",      no_argument,            NULL,           'H' },
883  { "machine",     no_argument,            NULL,           'm' },
884  { "layout",      no_argument,            NULL,           'l' },
885  { "strings",     no_argument,            NULL,           's' },
886  { "symbols",     no_argument,            NULL,           'S' },
887  { "relocs",      no_argument,            NULL,           'r' },
888  { "overlay",     no_argument,            NULL,           'o' },
889  { "expand",      no_argument,            NULL,           'x' },
890  { NULL,          0,                      NULL,            0 }
891};
892
893void
894usage (int exit_code)
895{
896  std::cout << "rtems-rap [options] objects" << std::endl
897            << "Options and arguments:" << std::endl
898            << " -h        : help (also --help)" << std::endl
899            << " -V        : print linker version number and exit (also --version)" << std::endl
900            << " -v        : verbose (trace import parts), can supply multiple times" << std::endl
901            << "             to increase verbosity (also --verbose)" << std::endl
902            << " -n        : no warnings (also --no-warn)" << std::endl
903            << " -a        : show all (also --all)" << std::endl
904            << " -H        : show header (also --header)" << std::endl
905            << " -m        : show machine details (also --machine)" << std::endl
906            << " -l        : show layout (also --layout)" << std::endl
907            << " -s        : show strings (also --strings)" << std::endl
908            << " -S        : show symbols (also --symbols)" << std::endl
909            << " -r        : show relocations (also --relocs)" << std::endl
910            << " -o        : linkage overlay (also --overlay)" << std::endl
911            << " -x        : expand (also --expand)" << std::endl;
912  ::exit (exit_code);
913}
914
915static void
916fatal_signal (int signum)
917{
918  signal (signum, SIG_DFL);
919
920  rld::process::temporaries.clean_up ();
921
922  /*
923   * Get the same signal again, this time not handled, so its normal effect
924   * occurs.
925   */
926  kill (getpid (), signum);
927}
928
929static void
930setup_signals (void)
931{
932  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
933    signal (SIGINT, fatal_signal);
934#ifdef SIGHUP
935  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
936    signal (SIGHUP, fatal_signal);
937#endif
938  if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
939    signal (SIGTERM, fatal_signal);
940#ifdef SIGPIPE
941  if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
942    signal (SIGPIPE, fatal_signal);
943#endif
944#ifdef SIGCHLD
945  signal (SIGCHLD, SIG_DFL);
946#endif
947}
948
949int
950main (int argc, char* argv[])
951{
952  int ec = 0;
953
954  setup_signals ();
955
956  try
957  {
958    rld::files::paths raps;
959    bool              warnings = true;
960    bool              show = false;
961    bool              show_header = false;
962    bool              show_machine = false;
963    bool              show_layout = false;
964    bool              show_strings = false;
965    bool              show_symbols = false;
966    bool              show_relocs = false;
967    bool              overlay = false;
968    bool              expand = false;
969
970    while (true)
971    {
972      int opt = ::getopt_long (argc, argv, "hvVnaHlsSrox", rld_opts, NULL);
973      if (opt < 0)
974        break;
975
976      switch (opt)
977      {
978        case 'V':
979          std::cout << "rtems-rap (RTEMS RAP Manager) " << rld::version ()
980                    << std::endl;
981          ::exit (0);
982          break;
983
984        case 'v':
985          rld::verbose_inc ();
986          break;
987
988        case 'n':
989          warnings = false;
990          break;
991
992        case 'a':
993          show = true;
994          show_header = true;
995          show_machine = true;
996          show_layout = true;
997          show_strings = true;
998          show_symbols = true;
999          show_relocs = true;
1000          break;
1001
1002        case 'H':
1003          show = true;
1004          show_header = true;
1005          break;
1006
1007        case 'm':
1008          show = true;
1009          show_machine = true;
1010          break;
1011
1012        case 'l':
1013          show = true;
1014          show_layout = true;
1015          break;
1016
1017        case 's':
1018          show = true;
1019          show_strings = true;
1020          break;
1021
1022        case 'S':
1023          show = true;
1024          show_symbols = true;
1025          break;
1026
1027        case 'r':
1028          show = true;
1029          show_relocs = true;
1030          break;
1031
1032        case 'o':
1033          overlay = true;
1034          break;
1035
1036        case 'x':
1037          expand = true;
1038          break;
1039
1040        case '?':
1041        case 'h':
1042          usage (0);
1043          break;
1044      }
1045    }
1046
1047    argc -= optind;
1048    argv += optind;
1049
1050    std::cout << "RTEMS RAP " << rld::version () << std::endl << std::endl;
1051
1052    /*
1053     * If there are no RAP files so there is nothing to do.
1054     */
1055    if (argc == 0)
1056      throw rld::error ("no RAP files", "options");
1057
1058    /*
1059     * Load the remaining command line arguments into a container.
1060     */
1061    while (argc--)
1062      raps.push_back (*argv++);
1063
1064    if (show)
1065      rap_show (raps,
1066                warnings,
1067                show_header,
1068                show_machine,
1069                show_layout,
1070                show_strings,
1071                show_symbols,
1072                show_relocs);
1073
1074    if (overlay)
1075      rap_overlay (raps, warnings);
1076
1077    if (expand)
1078      rap_expander (raps, warnings);
1079  }
1080  catch (rld::error re)
1081  {
1082    std::cerr << "error: "
1083              << re.where << ": " << re.what
1084              << std::endl;
1085    ec = 10;
1086  }
1087  catch (std::exception e)
1088  {
1089    int   status;
1090    char* realname;
1091    realname = abi::__cxa_demangle (e.what(), 0, 0, &status);
1092    std::cerr << "error: exception: " << realname << " [";
1093    ::free (realname);
1094    const std::type_info &ti = typeid (e);
1095    realname = abi::__cxa_demangle (ti.name(), 0, 0, &status);
1096    std::cerr << realname << "] " << e.what () << std::endl;
1097    ::free (realname);
1098    ec = 11;
1099  }
1100  catch (...)
1101  {
1102    /*
1103     * Helps to know if this happens.
1104     */
1105    std::cout << "error: unhandled exception" << std::endl;
1106    ec = 12;
1107  }
1108
1109  return ec;
1110}
Note: See TracBrowser for help on using the repository browser.