source: rtems-tools/linkers/rtems-rapper.cpp @ 347c9b5

4.104.115
Last change on this file since 347c9b5 was 347c9b5, checked in by Peng Fan <van.freenix@…>, on 08/01/13 at 08:15:07

Add section size for rap details

Add elf section size to the section details, because gdb will use the size of
a section.

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