source: rtems-tools/linkers/rtems-rapper.cpp @ 89e8c2a

5
Last change on this file since 89e8c2a was efc4f09, checked in by Chris Johns <chrisj@…>, on 12/09/15 at 09:08:19

Add release versioning support.

Support a top level VERSION file that defines an RTEMS release.

Fix the install of the python modules including thertems-test.

Update the git python module to the RSB version. Fix the options to
not call clean and to call dirty.

Update the version python module.

Fix the rtld C++ support to the VERSION file and the top level waf
script.

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