Changeset 1e21ea7 in rtems-tools


Ignore:
Timestamp:
May 8, 2018, 5:09:47 AM (12 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
881824f
Parents:
b73f905
git-author:
Chris Johns <chrisj@…> (05/08/18 05:09:47)
git-committer:
Chris Johns <chrisj@…> (06/18/18 02:26:16)
Message:

linkers/exe-info: Add DWARF support to gather and check producer details.

  • Provide support to list the compilers and assemblers used to build an executable.
  • List the machine flags showing which flags are common and which are not.
Location:
linkers
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • linkers/rtems-exeinfo.cpp

    rb73f905 r1e21ea7  
    4444#include <rld.h>
    4545#include <rld-buffer.h>
     46#include <rld-dwarf.h>
    4647#include <rld-files.h>
    4748#include <rld-process.h>
     
    132133    {
    133134      files::object    exe;         //< The object file that is the executable.
     135      dwarf::file      debug;       //< The executable's DWARF details.
    134136      symbols::table   symbols;     //< The synbols for a map.
    135137      symbols::addrtab addresses;   //< The symbols keyed by address.
     
    148150       */
    149151      ~image ();
     152
     153      /*
     154       * Check the compiler and flags match.
     155       */
     156      void output_compilation_unit (bool objects);
    150157
    151158      /*
     
    261268      exe.open ();
    262269      exe.begin ();
     270      debug.begin (exe.elf ());
    263271
    264272      if (!exe.valid ())
     
    285293       */
    286294      exe.load_symbols (symbols, true);
     295      debug.load_debug ();
    287296      symbols.globals (addresses);
    288297      symbols.weaks (addresses);
     
    293302    image::~image ()
    294303    {
    295       exe.close ();
     304    }
     305
     306    void
     307    image::output_compilation_unit (bool objects)
     308    {
     309      dwarf::compilation_units& cus = debug.get_cus ();
     310
     311      std::cout << "Compilation: " << std::endl;
     312
     313      rld::strings flag_exceptions = { "-O",
     314                                       "-g",
     315                                       "-mtune=",
     316                                       "-fno-builtin",
     317                                       "-fno-inline",
     318                                       "-fexceptions",
     319                                       "-fnon-call-exceptions",
     320                                       "-fvisibility=",
     321                                       "-fno-stack-protector",
     322                                       "-fbuilding-libgcc",
     323                                       "-fno-implicit-templates",
     324                                       "-ffunction-sections",
     325                                       "-fdata-sections",
     326                                       "-frandom-seed=",
     327                                       "-fno-common",
     328                                       "-fno-keep-inline-functions" };
     329
     330      dwarf::producer_sources producers;
     331
     332      debug.get_producer_sources (producers);
     333
     334      /*
     335       * Find which flags are common to the building of all source. We are only
     336       * interested in files that have any flags. This filters out things like
     337       * the assembler which does not have flags.
     338       */
     339
     340      rld::strings all_flags;
     341
     342      size_t source_max = 0;
     343
     344      for (auto& p : producers)
     345      {
     346        dwarf::source_flags_compare compare;
     347        std::sort (p.sources.begin (), p.sources.end (), compare);
     348
     349        for (auto& s : p.sources)
     350        {
     351          size_t len = rld::path::basename (s.source).length ();
     352          if (len > source_max)
     353            source_max = len;
     354
     355          if (!s.flags.empty ())
     356          {
     357            for (auto& f : s.flags)
     358            {
     359              bool add = true;
     360              for (auto& ef : flag_exceptions)
     361              {
     362                if (rld::starts_with (f, ef))
     363                {
     364                  add = false;
     365                  break;
     366                }
     367              }
     368              if (add)
     369              {
     370                for (auto& af : all_flags)
     371                {
     372                  if (f == af)
     373                  {
     374                    add = false;
     375                    break;
     376                  }
     377                }
     378                if (add)
     379                  all_flags.push_back (f);
     380              }
     381            }
     382          }
     383        }
     384      }
     385
     386      rld::strings common_flags;
     387
     388      for (auto& flag : all_flags)
     389      {
     390        bool found_in_all = true;
     391        for (auto& p : producers)
     392        {
     393          for (auto& s : p.sources)
     394          {
     395            if (!s.flags.empty ())
     396            {
     397              bool flag_found = false;
     398              for (auto& f : s.flags)
     399              {
     400                if (flag == f)
     401                {
     402                  flag_found = true;
     403                  break;
     404                }
     405              }
     406              if (!flag_found)
     407              {
     408                found_in_all = false;
     409                break;
     410              }
     411            }
     412            if (!found_in_all)
     413              break;
     414          }
     415        }
     416        if (found_in_all)
     417          common_flags.push_back (flag);
     418      }
     419
     420      std::cout << " Producers: " << producers.size () << std::endl;
     421
     422      for (auto& p : producers)
     423      {
     424        std::cout << "  | " << p.producer
     425                  << ": " << p.sources.size () << " objects" << std::endl;
     426      }
     427
     428      std::cout << " Common flags: " << common_flags.size () << std::endl
     429                << "  |";
     430
     431      for (auto& f : common_flags)
     432        std::cout << ' ' << f;
     433      std::cout << std::endl;
     434
     435      if (objects)
     436      {
     437        std::cout << " Object files: " << cus.size () << std::endl;
     438
     439        rld::strings filter_flags = common_flags;
     440        filter_flags.insert (filter_flags.end (),
     441                             flag_exceptions.begin (),
     442                             flag_exceptions.end());
     443
     444        for (auto& p : producers)
     445        {
     446          std::cout << ' ' << p.producer
     447                    << ": " << p.sources.size () << " objects" << std::endl;
     448          for (auto& s : p.sources)
     449          {
     450            std::cout << "   | "
     451                      << std::setw (source_max + 1) << std::left
     452                      << rld::path::basename (s.source);
     453            if (!s.flags.empty ())
     454            {
     455              bool first = true;
     456              for (auto& f : s.flags)
     457              {
     458                bool present = false;
     459                for (auto& ff : filter_flags)
     460                {
     461                  if (rld::starts_with(f, ff))
     462                  {
     463                    present = true;
     464                    break;
     465                  }
     466                }
     467                if (!present)
     468                {
     469                  if (first)
     470                  {
     471                    std::cout << ':';
     472                    first = false;
     473                  }
     474                  std::cout << ' ' << f;
     475                }
     476              }
     477            }
     478            std::cout << std::endl;
     479          }
     480        }
     481      }
     482
     483      std::cout << std::endl;
    296484    }
    297485
     
    443631            << " -S        : show all section (also --sections)" << std::endl
    444632            << " -I        : show init section tables (also --init)" << std::endl
    445             << " -F        : show fini section tables (also --fini)" << std::endl;
     633            << " -F        : show fini section tables (also --fini)" << std::endl
     634            << " -O        : show object files (also --objects)" << std::endl;
    446635  ::exit (exit_code);
    447636}
     
    481670}
    482671
     672void
     673unhandled_exception (void)
     674{
     675  std::cerr << "error: exception handling error, please report" << std::endl;
     676  exit (1);
     677}
     678
    483679int
    484680main (int argc, char* argv[])
     
    487683
    488684  setup_signals ();
     685
     686  std::set_terminate(unhandled_exception);
    489687
    490688  try
     
    496694    bool        init = false;
    497695    bool        fini = false;
     696    bool        objects = false;
    498697
    499698    rld::set_cmdline (argc, argv);
     
    538737          break;
    539738
     739        case 'O':
     740          objects = true;
     741          break;
     742
    540743        case '?':
    541744          usage (3);
     
    567770      init = true;
    568771      fini = true;
     772      objects = true;
    569773    }
    570774
     
    590794    rld::exeinfo::image exe (exe_name);
    591795
    592     std::cout << "exe: " << exe.exe.name ().full () << std::endl;
     796    std::cout << "exe: " << exe.exe.name ().full () << std::endl
     797              << std::endl;
    593798
    594799    /*
    595800     * Generate the output.
    596801     */
     802    exe.output_compilation_unit (objects);
    597803    if (sections)
    598804      exe.output_sections ();
  • linkers/wscript

    rb73f905 r1e21ea7  
    7171    # The list of modules.
    7272    #
    73     modules = ['rld', 'elf', 'iberty']
     73    modules = ['rld', 'dwarf', 'elf', 'iberty']
    7474
    7575    #
Note: See TracChangeset for help on using the changeset viewer.