* 02110-1301 USA
*/
-#ifndef _LIBRARY_H_
-#define _LIBRARY_H_
+#ifndef LIBRARY_H
+#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"
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 {
/* 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;
char own_soname : 1;
char own_pathname : 1;
+ bool should_activate_latent : 1;
struct arch_library_data arch;
struct os_library_data os;
int arch_translate_address_dyn(struct process *proc,
arch_addr_t addr, arch_addr_t *ret);
-#endif /* _LIBRARY_H_ */
+
+/* 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, char *name,
+ int own_name );
+
+/* 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.
+ *
+ * If we want to iterate through the whole alias list, set
+ * name_start_after=NULL. If we want to start iterating immediately past a
+ * particular symbol name, pass a pointer to this symbol name in
+ * name_start_after. This must be a pointer in the internal dict, preferably
+ * returned by an earlier call to this function
+ *
+ * If the callback fails at any point, a pointer to the failing key is returned.
+ * On success, returns NULL. The returned pointer can be passed back to this
+ * function in name_start_after to resume skipping this element
+ */
+const char** library_exported_names_each_alias(
+ struct library_exported_names *names,
+ const char *aliasname,
+ const char **name_start_after,
+ enum callback_status (*cb)(const char *,
+ void *),
+ void *data);
+
+/* Returns 0 if the exported names list does not contain a given name, or 1 if
+ * it does */
+int library_exported_names_contains(struct library_exported_names* names,
+ const char* queryname);
+
+#endif /* LIBRARY_H */