summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDima Kogan <dima@secretsauce.net>2014-06-02 17:43:16 -0700
committerChanho Park <chanho61.park@samsung.com>2014-08-22 20:38:26 +0900
commitc01119876e7d43261f8dbf203a5a0d267fcbc2d9 (patch)
tree90b89d77b3e0f4fea5a2f7e4b2cbaf2cc7721e7a
parent5c5c38e500fd8f20bb8d6c0177948dbfe86b6fcd (diff)
downloadltrace-c01119876e7d43261f8dbf203a5a0d267fcbc2d9.tar.gz
ltrace-c01119876e7d43261f8dbf203a5a0d267fcbc2d9.tar.bz2
ltrace-c01119876e7d43261f8dbf203a5a0d267fcbc2d9.zip
DWARF prototypes are now generated with both the plain and the linkage names
If a die has a DW_AT_linkage_name, I now use it: this is required for C++ code, in particular. I use the plain name regardless, since sometimes the exported symbol corresponds to the plain name, NOT the linkage name. For instance I see this on my Debian/sid amd64 box. In its libc, the linkage name of __nanosleep is __GI___nanosleep, but the export is __nanosleep
-rw-r--r--dwarf_prototypes.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/dwarf_prototypes.c b/dwarf_prototypes.c
index b50c82e..9c36904 100644
--- a/dwarf_prototypes.c
+++ b/dwarf_prototypes.c
@@ -904,18 +904,10 @@ static bool get_prototype(struct prototype *result,
#undef CLEANUP_AND_RETURN_ERROR
}
-static bool import_subprogram(struct protolib *plib, struct library *lib,
- struct dict *type_dieoffset_hash,
- Dwarf_Die *die)
+static bool import_subprogram_name(struct protolib *plib, struct library *lib,
+ struct dict *type_dieoffset_hash,
+ Dwarf_Die *die, const char* function_name)
{
- // I use the linkage function name if there is one, otherwise the
- // plain name
- const char *function_name = dwarf_diename(die);
- if (function_name == NULL) {
- complain(die, "Function has no name. Not importing");
- return true;
- }
-
if (!filter_matches_symbol(options.plt_filter, function_name, lib) &&
!filter_matches_symbol(options.static_filter, function_name, lib) &&
!filter_matches_symbol(options.export_filter, function_name, lib)) {
@@ -950,6 +942,36 @@ static bool import_subprogram(struct protolib *plib, struct library *lib,
return true;
}
+static bool import_subprogram_die(struct protolib *plib, struct library *lib,
+ struct dict *type_dieoffset_hash,
+ Dwarf_Die *die)
+{
+ // If there is a linkage name, I use it (this is required for C++ code,
+ // in particular).
+ //
+ // I use the plain name regardless, since sometimes the exported symbol
+ // corresponds to the plain name, NOT the linkage name. For instance I
+ // see this on my Debian/sid amd64 box. In its libc, the linkage name of
+ // __nanosleep is __GI___nanosleep, but the export is __nanosleep
+ const char *function_name;
+ Dwarf_Attribute attr;
+
+ if (dwarf_attr(die, DW_AT_linkage_name, &attr) != NULL &&
+ (function_name = dwarf_formstring(&attr)) != NULL &&
+ !import_subprogram_name(plib, lib, type_dieoffset_hash, die,
+ function_name)) {
+ return false;
+ }
+
+ if ((function_name = dwarf_diename(die)) != NULL &&
+ !import_subprogram_name(plib, lib, type_dieoffset_hash, die,
+ function_name)) {
+ return false;
+ }
+
+ return true;
+}
+
static bool process_die_compileunit(struct protolib *plib, struct library *lib,
struct dict *type_dieoffset_hash,
Dwarf_Die *parent)
@@ -963,8 +985,8 @@ static bool process_die_compileunit(struct protolib *plib, struct library *lib,
while (1) {
if (dwarf_tag(&die) == DW_TAG_subprogram)
- if (!import_subprogram(plib, lib, type_dieoffset_hash,
- &die))
+ if (!import_subprogram_die(plib, lib, type_dieoffset_hash,
+ &die))
complain(&die, "Error importing subprogram. "
"Skipping");