summaryrefslogtreecommitdiff
path: root/library.h
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 /library.h
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 'library.h')
-rw-r--r--library.h58
1 files changed, 51 insertions, 7 deletions
diff --git a/library.h b/library.h
index 4d649e0..f8a5cf8 100644
--- a/library.h
+++ b/library.h
@@ -23,11 +23,13 @@
#define _LIBRARY_H_
#include <stdint.h>
+#include <stdbool.h>
#if defined(HAVE_LIBDW)
# include <elfutils/libdwfl.h>
#endif
+#include "dict.h"
#include "callback.h"
#include "forward.h"
#include "sysdep.h"
@@ -41,11 +43,21 @@ enum toplt {
size_t arch_addr_hash(const arch_addr_t *addr);
int arch_addr_eq(const arch_addr_t *addr1, const arch_addr_t *addr2);
-/* For handling -l. */
-struct library_exported_name {
- struct library_exported_name *next;
- const char *name;
- int own_name : 1;
+
+/* For handling -l and for handling library export aliases (different symbol
+ * name, same address)
+ *
+ * This structure needs to
+ * - store (addr, name) tuples
+ * - be searchable by addr (when populating)
+ * - be searchable by name (when looking for aliases)
+ * - be enumeratable (by activate_latent_in())
+ */
+struct library_exported_names {
+ // I store the data in several structures to facilitate different types
+ // of access
+ struct dict names; // maps a name to an address
+ struct dict addrs; // maps an address to a vect of names
};
struct library_symbol {
@@ -158,8 +170,10 @@ struct library {
/* List of names that this library implements, and that match
* -l filter. Each time a new library is mapped, its list of
* exports is examined, and corresponding PLT slots are
- * enabled. */
- struct library_exported_name *exported_names;
+ * enabled. This data structure also keeps track of export
+ * addresses to find symbols with different names, but same
+ * addresses */
+ struct library_exported_names exported_names;
/* Prototype library associated with this library. */
struct protolib *protolib;
@@ -241,4 +255,34 @@ int arch_translate_address(struct ltelf *lte,
int arch_translate_address_dyn(struct process *proc,
arch_addr_t addr, arch_addr_t *ret);
+
+/* Pushes a name/address tuple to the list of a library's exports. Returns 0 on
+ * success
+ */
+int library_exported_names_push(struct library_exported_names *names,
+ uint64_t addr, const char *name,
+ int own_name );
+
+/* Iterates through the a library's export list. The callback is called for
+ * every symbol a library exports. Symbol aliases do not apply here. If multiple
+ * symbols are defined at the same address, each is reported here. Returns true
+ * on success. If the callback fails at any point, this returns false
+ */
+bool library_exported_names_each(const struct library_exported_names *names,
+ enum callback_status (*cb)(const char *,
+ void *),
+ void *data);
+
+/* Iterates through the a library's export list, reporting each symbol that is
+ * an alias of the given 'aliasname' symbol. This 'aliasname' symbol itself is
+ * NOT reported, so if this symbol is unique, the callback is not called at all.
+ * Returns true on success
+ */
+bool library_exported_names_each_alias(
+ const struct library_exported_names *names,
+ const char *aliasname,
+ enum callback_status (*cb)(const char *,
+ void *),
+ void *data);
+
#endif /* _LIBRARY_H_ */