From 463831374ce73e6792c6fc6c02e705cf3b8fc349 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Tue, 15 Sep 2020 13:10:56 +1000 Subject: 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. @@ -175,6 +175,11 @@ namespace rld */ void output_init_fini (const char* label, const char** names); + /* + * Output the configuration. + */ + void output_config (); + /* * Output the TLS data. */ @@ -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_); @@ -1673,6 +1770,38 @@ namespace rld //dump_die (); } + 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 () { @@ -1992,6 +2121,13 @@ namespace rld cu.load_types (); } + void + file::load_variables () + { + for (auto& cu : cus) + cu.load_variables (); + } + void file::load_functions () { 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 @@ -276,6 +276,59 @@ namespace rld dwarf_offset die_offset; }; + /** + * 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. */ @@ -619,6 +672,11 @@ namespace rld */ void load_types (); + /** + * Load the variables. + */ + void load_variables (); + /** * Load the 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. @@ -780,6 +839,11 @@ namespace rld */ void load_functions (); + /** + * Load the DWARF variables information. + */ + void load_variables (); + /** * Get the source location given an address. */ @@ -792,6 +856,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. */ -- cgit v1.2.3