[rtems-tools commit] linker/exeinfo: Optionally output full flags when listing object files

Chris Johns chrisj at rtems.org
Tue Sep 15 03:12:00 UTC 2020


Module:    rtems-tools
Branch:    master
Commit:    463831374ce73e6792c6fc6c02e705cf3b8fc349
Changeset: http://git.rtems.org/rtems-tools/commit/?id=463831374ce73e6792c6fc6c02e705cf3b8fc349

Author:    Chris Johns <chrisj at rtems.org>
Date:      Tue Sep 15 13:10:56 2020 +1000

linker/exeinfo: Optionally output full flags when listing object files

- Start adding support to dump configuration tables

---

 linkers/rtems-exeinfo.cpp  |  98 ++++++++++++++++++++++++++------
 rtemstoolkit/rld-dwarf.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++++-
 rtemstoolkit/rld-dwarf.h   |  69 +++++++++++++++++++++++
 3 files changed, 287 insertions(+), 18 deletions(-)

diff --git a/linkers/rtems-exeinfo.cpp b/linkers/rtems-exeinfo.cpp
index 28f24ce..1e6d4b4 100644
--- a/linkers/rtems-exeinfo.cpp
+++ b/linkers/rtems-exeinfo.cpp
@@ -153,7 +153,7 @@ namespace rld
       /*
        * Check the compiler and flags match.
        */
-      void output_compilation_unit (bool objects);
+      void output_compilation_unit (bool objects, bool full_flags);
 
       /*
        * Output the sections.
@@ -176,6 +176,11 @@ namespace rld
       void output_init_fini (const char* label, const char** names);
 
       /*
+       * Output the configuration.
+       */
+      void output_config ();
+
+      /*
        * Output the TLS data.
        */
       void output_tls ();
@@ -189,6 +194,10 @@ namespace rld
        * Output the DWARF data.
        */
       void output_dwarf ();
+
+    private:
+
+      void config (const std::string name);
     };
 
     section::section (const files::section& sec, files::byteorder byteorder)
@@ -309,6 +318,7 @@ namespace rld
       exe.load_symbols (symbols, true);
       debug.load_debug ();
       debug.load_types ();
+      debug.load_variables ();
       debug.load_functions ();
       symbols.globals (addresses);
       symbols.weaks (addresses);
@@ -321,7 +331,7 @@ namespace rld
     }
 
     void
-    image::output_compilation_unit (bool objects)
+    image::output_compilation_unit (bool objects, bool full_flags)
     {
       dwarf::compilation_units& cus = debug.get_cus ();
 
@@ -474,12 +484,15 @@ namespace rld
               for (auto& f : s.flags)
               {
                 bool present = false;
-                for (auto& ff : filter_flags)
+                if (!full_flags)
                 {
-                  if (rld::starts_with(f, ff))
+                  for (auto& ff : filter_flags)
                   {
-                    present = true;
-                    break;
+                    if (rld::starts_with(f, ff))
+                    {
+                      present = true;
+                      break;
+                    }
                   }
                 }
                 if (!present)
@@ -627,6 +640,7 @@ namespace rld
       symbols::symbol* tls_bss_size = symbols.find_global("_TLS_BSS_size");
       symbols::symbol* tls_size = symbols.find_global("_TLS_Size");
       symbols::symbol* tls_alignment = symbols.find_global("_TLS_Alignment");
+      symbols::symbol* tls_max_size = symbols.find_global("_Thread_Maximum_TLS_size");
 
       if (tls_data_begin == nullptr ||
           tls_data_end == nullptr ||
@@ -650,36 +664,44 @@ namespace rld
             return;
         }
         std::cout << "TLS environment is INVALID (please report):" << std::endl
-                  << " _TLS_Data_begin : "
+                  << " _TLS_Data_begin          : "
                   << (char*) (tls_data_begin == nullptr ? "not-found" : "found")
                   << std::endl
-                  << " _TLS_Data_end   : "
+                  << " _TLS_Data_end            : "
                   << (char*) (tls_data_end == nullptr ? "not-found" : "found")
                   << std::endl
-                  << " _TLS_Data_size  : "
+                  << " _TLS_Data_size           : "
                   << (char*) (tls_data_size == nullptr ? "not-found" : "found")
                   << std::endl
-                  << " _TLS_BSS_begin  : "
+                  << " _TLS_BSS_begin           : "
                   << (char*) (tls_bss_begin == nullptr ? "not-found" : "found")
                   << std::endl
-                  << " _TLS_BSS_end    : "
+                  << " _TLS_BSS_end             : "
                   << (char*) (tls_bss_end == nullptr ? "not-found" : "found")
                   << std::endl
-                  << " _TLS_BSS_Size   : "
+                  << " _TLS_BSS_Size            : "
                   << (char*) (tls_bss_size == nullptr ? "not-found" : "found")
                   << std::endl
-                  << " _TLS_Size       : "
+                  << " _TLS_Size                : "
                   << (char*) (tls_size == nullptr ? "not-found" : "found")
                   << std::endl
-                  << " _TLS_Alignment  : "
+                  << " _TLS_Alignment           : "
                   << (char*) (tls_alignment == nullptr ? "not-found" : "found")
                   << std::endl
+                  << " _Thread_Maximum_TLS_size : "
+                  << (char*) (tls_max_size == nullptr ? "not-found" : "found")
+                  << std::endl
                   << std::endl;
         return;
       }
 
       std::cout << "TLS size      : " << tls_size->value () << std::endl
-                << "    data size : " << tls_data_size->value () << std::endl
+                << "     max size : ";
+      if (tls_max_size == nullptr)
+          std::cout << "not found" << std::endl;
+      else
+          std::cout << tls_max_size->value () << std::endl;
+      std::cout << "    data size : " << tls_data_size->value () << std::endl
                 << "     bss size : " << tls_bss_size->value () << std::endl
                 << "    alignment : " << tls_alignment->value () << std::endl
                 << std::right << std::hex << std::setfill ('0')
@@ -689,6 +711,31 @@ namespace rld
                 << std::endl;
     }
 
+    void image::config(const std::string name)
+    {
+      std::string table_name = "_" + name + "_Information";
+      symbols::symbol* table = symbols.find_global(table_name);
+
+      if (table != nullptr)
+        std::cout << " " << name << std::endl;
+    }
+
+    void image::output_config()
+    {
+      std::cout << "Configurations:" << std::endl;
+      config("Thread");
+      config("Barrier");
+      config("Extension");
+      config("Message_queue");
+      config("Partition");
+      config("Rate_monotonic");
+      config("Dual_ported_memory");
+      config("Region");
+      config("Semaphore");
+      config("Timer");
+      config("RTEMS_tasks");
+    }
+
     struct func_count
     {
       std::string name;
@@ -835,6 +882,8 @@ static struct option rld_opts[] = {
   { "init",        no_argument,            NULL,           'I' },
   { "fini",        no_argument,            NULL,           'F' },
   { "objects",     no_argument,            NULL,           'O' },
+  { "full-flags",  no_argument,            NULL,           'A' },
+  { "config",      no_argument,            NULL,           'C' },
   { "tls",         no_argument,            NULL,           'T' },
   { "inlined",     no_argument,            NULL,           'i' },
   { "dwarf",       no_argument,            NULL,           'D' },
@@ -856,6 +905,8 @@ usage (int exit_code)
             << " -I        : show init section tables (also --init)" << std::endl
             << " -F        : show fini section tables (also --fini)" << std::endl
             << " -O        : show object files (also --objects)" << std::endl
+            << "           :  add --full-flags for compiler options" << std::endl
+            << " -C        : show configuration (also --config)" << std::endl
             << " -T        : show thread local storage data (also --tls)" << std::endl
             << " -i        : show inlined code (also --inlined)" << std::endl
             << " -D        : dump the DWARF data (also --dwarf)" << std::endl;
@@ -921,6 +972,8 @@ main (int argc, char* argv[])
     bool        init = false;
     bool        fini = false;
     bool        objects = false;
+    bool        full_flags = false;
+    bool        config = false;
     bool        tls = false;
     bool        inlined = false;
     bool        dwarf_data = false;
@@ -929,7 +982,7 @@ main (int argc, char* argv[])
 
     while (true)
     {
-      int opt = ::getopt_long (argc, argv, "hvVMaSIFOTiD", rld_opts, NULL);
+      int opt = ::getopt_long (argc, argv, "hvVMaSIFOCTiD", rld_opts, NULL);
       if (opt < 0)
         break;
 
@@ -970,6 +1023,14 @@ main (int argc, char* argv[])
           objects = true;
           break;
 
+        case 'A':
+          full_flags = true;
+          break;
+
+        case 'C':
+          config = true;
+          break;
+
         case 'T':
           tls = true;
           break;
@@ -1012,6 +1073,7 @@ main (int argc, char* argv[])
       init = true;
       fini = true;
       objects = true;
+      config = true;
       tls = true;
       inlined = true;
     }
@@ -1043,13 +1105,15 @@ main (int argc, char* argv[])
     /*
      * Generate the output.
      */
-    exe.output_compilation_unit (objects);
+    exe.output_compilation_unit (objects, full_flags);
     if (sections)
       exe.output_sections ();
     if (init)
       exe.output_init ();
     if (fini)
       exe.output_fini ();
+    if (config)
+      exe.output_config ();
     if (tls)
       exe.output_tls ();
     if (inlined)
diff --git a/rtemstoolkit/rld-dwarf.cpp b/rtemstoolkit/rld-dwarf.cpp
index 1e62b3c..fc4399a 100644
--- a/rtemstoolkit/rld-dwarf.cpp
+++ b/rtemstoolkit/rld-dwarf.cpp
@@ -575,6 +575,104 @@ namespace rld
       return *this;
     }
 
+    variable::variable (file& debug, debug_info_entry& die)
+      : debug (debug),
+        external_ (false),
+        declaration_ (false)
+    {
+      dwarf_bool db;
+
+      if (die.attribute (DW_AT_external, db, false))
+        external_ = db ? true : false;
+
+      if (die.attribute (DW_AT_declaration, db, false))
+        declaration_ = db ? true : false;
+
+      /*
+       * Get the name attribute. (if present)
+       */
+      die.attribute (DW_AT_name, name_);
+      die.attribute (DW_AT_decl_file, decl_file_);
+      die.attribute (DW_AT_decl_line, decl_line_);
+
+      if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+      {
+        std::cout << "dwarf::variable: ";
+        dump (std::cout);
+        std::cout << std::endl;
+      }
+    }
+
+    variable::variable (const variable& orig)
+      : debug (orig.debug),
+        external_ (orig.external_),
+        declaration_ (orig.declaration_),
+        name_ (orig.name_),
+        decl_file_ (orig.decl_file_),
+        decl_line_ (orig. decl_line_)
+    {
+    }
+
+    variable::~variable ()
+    {
+    }
+
+    std::string
+    variable::name () const
+    {
+      return name_;
+    }
+
+    bool
+    variable::is_external () const
+    {
+      return external_;
+    }
+
+    bool
+    variable::is_declaration () const
+    {
+      return declaration_;
+    }
+
+    size_t
+    variable::size () const
+    {
+      size_t s = 0;
+      return s;
+    }
+
+    variable&
+    variable::operator = (const variable& rhs)
+    {
+      if (this != &rhs)
+      {
+        debug = rhs.debug;
+        external_ = rhs.external_;
+        declaration_ = rhs.declaration_;
+        name_ = rhs.name_;
+        decl_file_ = rhs.decl_file_;
+        decl_line_ = rhs.decl_line_;
+      }
+      return *this;
+    }
+
+    void
+    variable::dump (std::ostream& out) const
+    {
+      if (name_.empty ())
+        out << "NO-NAME";
+      else
+        out << name_;
+      out << " ["
+          << (char) (external_ ? 'E' : '-')
+          << (char) (declaration_ ? 'D' : '-')
+          << "] size=" << size ()
+          << std::hex << std::setfill ('0')
+          << " (0x" << size () << ')'
+          << std::dec << std::setfill (' ');
+    }
+
 
     function::function (file& debug, debug_info_entry& die)
       : debug (debug),
@@ -1513,7 +1611,6 @@ namespace rld
         source_ (debug, die_offset)
     {
       die.attribute (DW_AT_name, name_);
-      name_ = name_;
 
       die.attribute (DW_AT_producer, producer_);
 
@@ -1674,6 +1771,38 @@ namespace rld
     }
 
     void
+    compilation_unit::load_variables ()
+    {
+      debug_info_entry die (debug, die_offset);
+      debug_info_entry child (debug);
+      if (die.get_child (child))
+        load_variables (child);
+    }
+
+    void
+    compilation_unit::load_variables (debug_info_entry& die)
+    {
+      while (true)
+      {
+        if (die.tag () == DW_TAG_variable)
+        {
+          function func (debug, die);
+          functions_.push_back (func);
+        }
+
+        debug_info_entry next (die.get_debug ());
+
+        if (die.get_child (next))
+          load_functions (next);
+
+        if (!die.get_sibling (next))
+          break;
+
+        die = next;
+      }
+    }
+
+    void
     compilation_unit::load_functions ()
     {
       debug_info_entry die (debug, die_offset);
@@ -1993,6 +2122,13 @@ namespace rld
     }
 
     void
+    file::load_variables ()
+    {
+      for (auto& cu : cus)
+        cu.load_variables ();
+    }
+
+    void
     file::load_functions ()
     {
       for (auto& cu : cus)
diff --git a/rtemstoolkit/rld-dwarf.h b/rtemstoolkit/rld-dwarf.h
index 030be3a..45fbab1 100644
--- a/rtemstoolkit/rld-dwarf.h
+++ b/rtemstoolkit/rld-dwarf.h
@@ -277,6 +277,59 @@ namespace rld
     };
 
     /**
+     * Variable.
+     */
+    class variable
+    {
+    public:
+
+      variable (file& debug, debug_info_entry& die);
+      variable (const variable& orig);
+      ~variable ();
+
+      /**
+       * Get the name of the variable.
+       */
+      std::string name () const;
+
+      /**
+       * Is the variable external?
+       */
+      bool is_external () const;
+
+      /**
+       * Is this just a declaration?
+       */
+      bool is_declaration () const;
+
+      /**
+       * Size of the variable.
+       */
+      size_t size () const;
+
+      /**
+       * Assigment operator.
+       */
+      variable& operator = (const variable& rhs);
+
+      /**
+       * Dump the variable.
+       */
+      void dump (std::ostream& out) const;
+
+    private:
+
+      file&          debug;
+      bool           external_;
+      bool           declaration_;
+      std::string    name_;
+      std::string    decl_file_;
+      dwarf_unsigned decl_line_;
+    };
+
+    typedef std::vector < variable > variables;
+
+    /**
      * Function.
      */
     class function
@@ -620,6 +673,11 @@ namespace rld
       void load_types ();
 
       /**
+       * Load the variables.
+       */
+      void load_variables ();
+
+      /**
        * Load the functions.
        */
       void load_functions ();
@@ -677,6 +735,7 @@ namespace rld
 
     private:
 
+      void load_variables (debug_info_entry& die);
       void load_functions (debug_info_entry& die);
 
       file&          debug;       ///< The DWARF debug handle.
@@ -781,6 +840,11 @@ namespace rld
       void load_functions ();
 
       /**
+       * Load the DWARF variables information.
+       */
+      void load_variables ();
+
+      /**
        * Get the source location given an address.
        */
       bool get_source (const unsigned int address,
@@ -793,6 +857,11 @@ namespace rld
       void get_producer_sources (producer_sources& producers);
 
       /**
+       * Get the variable given a name. Raises an exception if not found.
+       */
+      variable& get_variable (std::string& name);
+
+      /**
        * Does the function exist.
        */
       bool function_valid (std::string&name);



More information about the vc mailing list