aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2017-02-27 23:04:14 (GMT)
committerJouni Malinen <j@w1.fi>2017-02-28 09:37:19 (GMT)
commit51183198315e74001770e65a357fbc0f0164bc6d (patch)
tree301c85638d096dca2e1396efffee79bcf0aef670 /src
parent069daec4eef380a22e34c203a1eb0c93060f826c (diff)
downloadhostap-51183198315e74001770e65a357fbc0f0164bc6d.zip
hostap-51183198315e74001770e65a357fbc0f0164bc6d.tar.gz
hostap-51183198315e74001770e65a357fbc0f0164bc6d.tar.bz2
trace: Look up start to cope with ASLR
When ASLR is enabled, like it is by default on many distros now, the trace code doesn't work right. Fix this by looking up the start of the executable mapping and subtracing it from all the lookups. Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'src')
-rw-r--r--src/utils/trace.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/utils/trace.c b/src/utils/trace.c
index d72cf60..e0b5b0b 100644
--- a/src/utils/trace.c
+++ b/src/utils/trace.c
@@ -6,6 +6,10 @@
* See README for more details.
*/
+#ifdef WPA_TRACE_BFD
+#define _GNU_SOURCE
+#include <link.h>
+#endif /* WPA_TRACE_BCD */
#include "includes.h"
#include "common.h"
@@ -25,6 +29,28 @@ static struct dl_list active_references =
static char *prg_fname = NULL;
static bfd *cached_abfd = NULL;
static asymbol **syms = NULL;
+static unsigned long start_offset;
+static int start_offset_looked_up;
+
+
+static int callback(struct dl_phdr_info *info, size_t size, void *data)
+{
+ /*
+ * dl_iterate_phdr(3):
+ * "The first object visited by callback is the main program."
+ */
+ start_offset = info->dlpi_addr;
+
+ /*
+ * dl_iterate_phdr(3):
+ * "The dl_iterate_phdr() function walks through the list of an
+ * application's shared objects and calls the function callback
+ * once for each object, until either all shared objects have
+ * been processed or callback returns a nonzero value."
+ */
+ return 1;
+}
+
static void get_prg_fname(void)
{
@@ -160,7 +186,7 @@ static void wpa_trace_bfd_addr(void *pc)
if (abfd == NULL)
return;
- data.pc = (bfd_hostptr_t) pc;
+ data.pc = (bfd_hostptr_t) (pc - start_offset);
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);
@@ -201,7 +227,7 @@ static const char * wpa_trace_bfd_addr2func(void *pc)
if (abfd == NULL)
return NULL;
- data.pc = (bfd_hostptr_t) pc;
+ data.pc = (bfd_hostptr_t) (pc - start_offset);
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);
@@ -233,6 +259,11 @@ static void wpa_trace_bfd_init(void)
wpa_printf(MSG_INFO, "Failed to read symbols");
return;
}
+
+ if (!start_offset_looked_up) {
+ dl_iterate_phdr(callback, NULL);
+ start_offset_looked_up = 1;
+ }
}
@@ -268,7 +299,7 @@ size_t wpa_trace_calling_func(const char *buf[], size_t len)
for (i = 0; i < btrace_num; i++) {
struct bfd_data data;
- data.pc = (bfd_hostptr_t) btrace_res[i];
+ data.pc = (bfd_hostptr_t) (btrace_res[i] - start_offset);
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);