summaryrefslogtreecommitdiff
path: root/output.c
diff options
context:
space:
mode:
authorDima Kogan <dima@secretsauce.net>2014-06-02 02:01:57 -0700
committerChanho Park <chanho61.park@samsung.com>2014-08-22 20:38:26 +0900
commit5c5c38e500fd8f20bb8d6c0177948dbfe86b6fcd (patch)
tree4f05fbaf41292a7c264cbe2caedd5c78c8e24a91 /output.c
parent703e5c6363ae5d07be62c2efa0a17862ce3c1c45 (diff)
downloadltrace-5c5c38e500fd8f20bb8d6c0177948dbfe86b6fcd.tar.gz
ltrace-5c5c38e500fd8f20bb8d6c0177948dbfe86b6fcd.tar.bz2
ltrace-5c5c38e500fd8f20bb8d6c0177948dbfe86b6fcd.zip
We now use known prototypes for all aliased symbols (same address)
Some libraries have multiple names for the same function. Prior to this patch, it was possible to define a prototype for a symbol, and not have ltrace use it because it saw a different symbol be called. libc is a common source of this. For instance (on my amd64 Debian box) it defines the nanosleep symbol as both 'nanosleep' and '__GI___nanosleep', at the same address. If a calling library calls '__GI___nanosleep', then an ltrace prototype for 'nanosleep' would not be used, even though it should apply to this call
Diffstat (limited to 'output.c')
-rw-r--r--output.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/output.c b/output.c
index 10faee2..2128816 100644
--- a/output.c
+++ b/output.c
@@ -197,6 +197,28 @@ snip_period(char *buf)
}
}
+struct lookup_prototype_alias_context
+{
+ struct library *lib;
+ struct prototype *result; // output
+};
+static enum callback_status
+lookup_prototype_alias_cb(const char *name, void *data)
+{
+ struct lookup_prototype_alias_context *context =
+ (struct lookup_prototype_alias_context*)data;
+
+ struct library *lib = context->lib;
+
+ context->result =
+ protolib_lookup_prototype(lib->protolib, name,
+ lib->type != LT_LIBTYPE_SYSCALL);
+ if (context->result != NULL)
+ return CBS_STOP;
+
+ return CBS_CONT;
+}
+
static struct prototype *
library_get_prototype(struct library *lib, const char *name)
{
@@ -235,8 +257,21 @@ library_get_prototype(struct library *lib, const char *name)
if (lib->protolib == NULL)
return NULL;
- return protolib_lookup_prototype(lib->protolib, name,
- lib->type != LT_LIBTYPE_SYSCALL);
+ struct prototype *result =
+ protolib_lookup_prototype(lib->protolib, name,
+ lib->type != LT_LIBTYPE_SYSCALL);
+ if (result != NULL)
+ return result;
+
+ // prototype not found. Is it aliased?
+ struct lookup_prototype_alias_context context = {.lib = lib,
+ .result = NULL};
+ library_exported_names_each_alias(&lib->exported_names, name,
+ lookup_prototype_alias_cb,
+ &context);
+
+ // if found, the prototype is stored here, otherwise it's NULL
+ return context.result;
}
struct find_proto_data {