Changeset f450227 in rtems-tools


Ignore:
Timestamp:
Aug 5, 2018, 11:34:27 PM (9 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
99c90b3
Parents:
d3318eb
git-author:
Chris Johns <chrisj@…> (08/05/18 23:34:27)
git-committer:
Chris Johns <chrisj@…> (08/06/18 23:11:29)
Message:

linkers/exeinfo: Add an inlines report and DWARF data dump.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • linkers/rtems-exeinfo.cpp

    rd3318eb rf450227  
    175175       */
    176176      void output_init_fini (const char* label, const char** names);
     177
     178      /*
     179       * Output the inlined functions.
     180       */
     181      void output_inlined ();
     182
     183      /*
     184       * Output the DWARF data.
     185       */
     186      void output_dwarf ();
    177187    };
    178188
     
    295305      debug.load_debug ();
    296306      debug.load_types ();
     307      debug.load_functions ();
    297308      symbols.globals (addresses);
    298309      symbols.weaks (addresses);
     
    601612      std::cout << std::endl;
    602613    }
     614
     615    struct func_count
     616    {
     617      std::string name;
     618      int         count;
     619      size_t      size;
     620
     621      func_count (std::string name, size_t size)
     622        : name (name),
     623          count (1),
     624          size (size) {
     625      }
     626    };
     627    typedef std::vector < func_count > func_counts;
     628
     629    void image::output_inlined ()
     630    {
     631      size_t           total = 0;
     632      size_t           total_size = 0;
     633      size_t           inlined_size = 0;
     634      dwarf::functions funcs;
     635      func_counts      counts;
     636
     637      for (auto& cu : debug.get_cus ())
     638      {
     639        for (auto& f : cu.get_functions ())
     640        {
     641          if (f.size () > 0 && f.has_machine_code ())
     642          {
     643            ++total;
     644            total_size += f.size ();
     645            if (f.is_inlined ())
     646            {
     647              inlined_size += f.size ();
     648              bool counted = false;
     649              for (auto& c : counts)
     650              {
     651                if (c.name == f.name ())
     652                {
     653                  ++c.count;
     654                  c.size += f.size ();
     655                  counted = true;
     656                  break;
     657                }
     658              }
     659              if (!counted)
     660                counts.push_back (func_count (f.name (), f.size ()));
     661              funcs.push_back (f);
     662            }
     663          }
     664        }
     665      }
     666
     667      std::cout << "inlined funcs   : " << funcs.size () << std::endl
     668                << "    total funcs : " << total << std::endl
     669                << " % inline funcs : " << (funcs.size () * 100) / total << '%'
     670                << std::endl
     671                << "     total size : " << total_size << std::endl
     672                << "    inline size : " << inlined_size << std::endl
     673                << "  % inline size : " << (inlined_size * 100) / total_size << '%'
     674                << std::endl;
     675
     676      auto count_compare = [](func_count const & a, func_count const & b) {
     677        return a.size != b.size?  a.size < b.size : a.count > b.count;
     678      };
     679      std::sort (counts.begin (), counts.end (), count_compare);
     680      std::reverse (counts.begin (), counts.end ());
     681
     682      std::cout  << std::endl << "inlined repeats : " << std::endl;
     683      for (auto& c : counts)
     684        if (c.count > 1)
     685          std::cout << std::setw (6) << c.size << ' '
     686                    << std::setw (4) << c.count << ' '
     687                    << c.name << std::endl;
     688
     689      std::cout << std::endl << "inline funcs : " << std::endl;
     690      dwarf::function_compare compare (dwarf::function_compare::fc_by_size);
     691      std::sort (funcs.begin (), funcs.end (), compare);
     692      std::reverse (funcs.begin (), funcs.end ());
     693
     694      for (auto& f : funcs)
     695      {
     696        std::cout << std::setw (6) << f.size () << ' '
     697                  << (char) (f.is_external () ? 'E' : ' ')
     698                  << std::hex << std::setfill ('0')
     699                  << " 0x" << std::setw (8) << f.pc_low ()
     700                  << std::dec << std::setfill (' ')
     701                  << ' ' << f.name ()
     702                  << std::endl;
     703      }
     704    }
     705
     706    void image::output_dwarf ()
     707    {
     708      std::cout << "DWARF Data:" << std::endl;
     709      debug.dump (std::cout);
     710    }
    603711  }
    604712}
     
    617725  { "init",        no_argument,            NULL,           'I' },
    618726  { "fini",        no_argument,            NULL,           'F' },
     727  { "inlined",     no_argument,            NULL,           'i' },
     728  { "dwarf",       no_argument,            NULL,           'D' },
    619729  { NULL,          0,                      NULL,            0 }
    620730};
     
    630740            << "             to increase verbosity (also --verbose)" << std::endl
    631741            << " -M        : generate map output (also --map)" << std::endl
    632             << " -a        : all output excluding the map (also --all)" << std::endl
     742            << " -a        : all output excluding the map and DAWRF (also --all)" << std::endl
    633743            << " -S        : show all section (also --sections)" << std::endl
    634744            << " -I        : show init section tables (also --init)" << std::endl
    635745            << " -F        : show fini section tables (also --fini)" << std::endl
    636             << " -O        : show object files (also --objects)" << std::endl;
     746            << " -O        : show object files (also --objects)" << std::endl
     747            << " -i        : show inlined code (also --inlined)" << std::endl
     748            << " -D        : dump the DWARF data (also --dwarf)" << std::endl;
    637749  ::exit (exit_code);
    638750}
     
    697809    bool        fini = false;
    698810    bool        objects = false;
     811    bool        inlined = false;
     812    bool        dwarf_data = false;
    699813
    700814    rld::set_cmdline (argc, argv);
     
    702816    while (true)
    703817    {
    704       int opt = ::getopt_long (argc, argv, "hvVMaSIF", rld_opts, NULL);
     818      int opt = ::getopt_long (argc, argv, "hvVMaSIFiD", rld_opts, NULL);
    705819      if (opt < 0)
    706820        break;
     
    743857          break;
    744858
     859        case 'i':
     860          inlined = true;
     861          break;
     862
     863        case 'D':
     864          dwarf_data = true;
     865          break;
     866
    745867        case '?':
    746868          usage (3);
     
    773895      fini = true;
    774896      objects = true;
     897      inlined = true;
    775898    }
    776899
     
    809932    if (fini)
    810933      exe.output_fini ();
     934    if (inlined)
     935      exe.output_inlined ();
     936    if (dwarf_data)
     937      exe.output_dwarf ();
    811938
    812939    /*
Note: See TracChangeset for help on using the changeset viewer.