summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-04-03 16:26:36 +1000
committerChris Johns <chrisj@rtems.org>2016-04-03 16:26:36 +1000
commit6c94148e62076c52794dd43a529793bdc33e4b8d (patch)
treed7943a527307ae8f2fc292efb9ea944095037de2
parentlinkers: Add a tool to show RTEMS executable information. (diff)
downloadrtems-tools-6c94148e62076c52794dd43a529793bdc33e4b8d.tar.bz2
linkers: Demangle the C++ labels in the .ctors/.dtors sections.
Show user friendly labels for the C++ constructors and destructors.
-rw-r--r--linkers/rtems-exeinfo.cpp26
-rw-r--r--rtemstoolkit/rld-symbols.cpp22
-rw-r--r--rtemstoolkit/rld-symbols.h6
3 files changed, 44 insertions, 10 deletions
diff --git a/linkers/rtems-exeinfo.cpp b/linkers/rtems-exeinfo.cpp
index dd04bd1..dc3e1ec 100644
--- a/linkers/rtems-exeinfo.cpp
+++ b/linkers/rtems-exeinfo.cpp
@@ -111,7 +111,7 @@ namespace rld
*/
struct image
{
- files::object exe; //< The object file that is the executable.
+ files::object exe; //< The object file that is the executable.
symbols::table symbols; //< The synbols for a map.
symbols::addrtab addresses; //< The symbols keyed by address.
files::sections secs; //< The sections in the executable.
@@ -214,10 +214,11 @@ namespace rld
{
if (fsec.name == names[n])
{
- section sec (fsec);
if (rld::verbose () >= RLD_VERBOSE_DETAILS)
std::cout << "init:section-loader: " << fsec.name
<< " added" << std::endl;
+
+ section sec (fsec);
img.exe.seek (fsec.offset);
sec.data.read (img.exe, fsec.size);
secs.push_back (sec);
@@ -342,13 +343,26 @@ namespace rld
sym = addresses[address];
std::cout << " "
<< std::hex << std::setfill ('0')
- << "0x" << std::setw (8) << address;
+ << "0x" << std::setw (8) << address
+ << std::dec << std::setfill ('0');
if (sym)
- std::cout << " " << sym->name ();
+ {
+ /*
+ * C++ is adding '_GLOBAL__sub_I_' to the label. If present, strip
+ * and check the label.
+ */
+ std::string label = sym->name ();
+ if (rld::starts_with (label, "_GLOBAL__sub_I_"))
+ label = rld::find_replace (label, "_GLOBAL__sub_I_", "");
+ if (rld::symbols::is_cplusplus (label))
+ rld::symbols::demangle_name (label, label);
+ std::cout << " " << label;
+ }
else
+ {
std::cout << " no symbol";
- std::cout << std::dec << std::setfill ('0')
- << std::endl;
+ }
+ std::cout << std::endl;
}
}
diff --git a/rtemstoolkit/rld-symbols.cpp b/rtemstoolkit/rld-symbols.cpp
index 92803d8..19d5680 100644
--- a/rtemstoolkit/rld-symbols.cpp
+++ b/rtemstoolkit/rld-symbols.cpp
@@ -37,8 +37,22 @@ namespace rld
/**
* Get the demangled name.
*/
- static void
- denamgle_name (std::string& name, std::string& demangled)
+ bool
+ is_cplusplus (const std::string& name)
+ {
+ char* demangled_name = ::cplus_demangle (name.c_str (),
+ DMGL_ANSI | DMGL_PARAMS);
+ bool yes = false;
+ if (demangled_name)
+ {
+ yes = true;
+ ::free (demangled_name);
+ }
+ return yes;
+ }
+
+ void
+ demangle_name (std::string& name, std::string& demangled)
{
char* demangled_name = ::cplus_demangle (name.c_str (),
DMGL_ANSI | DMGL_PARAMS);
@@ -70,7 +84,7 @@ namespace rld
if (!object_)
throw rld_error_at ("object pointer is 0");
if (is_cplusplus ())
- denamgle_name (name_, demangled_);
+ demangle_name (name_, demangled_);
}
symbol::symbol (int index,
@@ -83,7 +97,7 @@ namespace rld
references_ (0)
{
if (is_cplusplus ())
- denamgle_name (name_, demangled_);
+ demangle_name (name_, demangled_);
}
symbol::symbol (const std::string& name,
diff --git a/rtemstoolkit/rld-symbols.h b/rtemstoolkit/rld-symbols.h
index c8a61f4..6a71a3d 100644
--- a/rtemstoolkit/rld-symbols.h
+++ b/rtemstoolkit/rld-symbols.h
@@ -45,6 +45,12 @@ namespace rld
namespace symbols
{
/**
+ * C++ demangler.
+ */
+ bool is_cplusplus (const std::string& name);
+ void demangle_name (std::string& name, std::string& demangled);
+
+ /**
* Use a local type for the address.
*/
typedef elf::elf_addr address;