#define _LGPL_SOURCE
#define _GNU_SOURCE
-#include <link.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#include <link.h>
#include <limits.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stddef.h>
#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
-#include <usterr-signal-safe.h>
+#include <lttng/ust-elf.h>
#include "lttng-tracer-core.h"
#include "lttng-ust-statedump.h"
void *owner;
void *base_addr_ptr;
const char *resolved_path;
+ char *dbg_file;
+ uint8_t *build_id;
+ uint64_t memsz;
+ size_t build_id_len;
int vdso;
- off_t size;
- time_t mtime;
+ uint32_t crc;
};
typedef void (*tracepoint_cb)(struct lttng_session *session, void *priv);
struct soinfo_data *so_data = (struct soinfo_data *) priv;
tracepoint(lttng_ust_statedump, soinfo,
- session, so_data->base_addr_ptr,
- so_data->resolved_path, so_data->size,
- so_data->mtime);
+ session, so_data->base_addr_ptr,
+ so_data->resolved_path, so_data->memsz);
+}
+
+static
+void trace_build_id_cb(struct lttng_session *session, void *priv)
+{
+ struct soinfo_data *so_data = (struct soinfo_data *) priv;
+
+ tracepoint(lttng_ust_statedump, build_id,
+ session, so_data->base_addr_ptr,
+ so_data->build_id, so_data->build_id_len);
+}
+
+static
+void trace_debug_link_cb(struct lttng_session *session, void *priv)
+{
+ struct soinfo_data *so_data = (struct soinfo_data *) priv;
+
+ tracepoint(lttng_ust_statedump, debug_link,
+ session, so_data->base_addr_ptr,
+ so_data->dbg_file, so_data->crc);
}
static
tracepoint(lttng_ust_statedump, end, session);
}
+static
+int get_elf_info(struct soinfo_data *so_data, int *has_build_id,
+ int *has_debug_link) {
+ struct lttng_ust_elf *elf;
+ int ret = 0;
+
+ elf = lttng_ust_elf_create(so_data->resolved_path);
+ if (!elf) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = lttng_ust_elf_get_memsz(elf, &so_data->memsz);
+ if (ret) {
+ goto end;
+ }
+
+ ret = lttng_ust_elf_get_build_id(elf, &so_data->build_id,
+ &so_data->build_id_len, has_build_id);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_ust_elf_get_debug_link(elf, &so_data->dbg_file,
+ &so_data->crc, has_debug_link);
+ if (ret) {
+ goto end;
+ }
+
+end:
+ lttng_ust_elf_destroy(elf);
+ return ret;
+}
+
static
int trace_baddr(struct soinfo_data *so_data)
{
- struct stat sostat;
+ int ret = 0, has_build_id = 0, has_debug_link = 0;
- if (so_data->vdso || stat(so_data->resolved_path, &sostat)) {
- sostat.st_size = 0;
- sostat.st_mtime = -1;
+ if (!so_data->vdso) {
+ ret = get_elf_info(so_data, &has_build_id, &has_debug_link);
+ if (ret) {
+ goto end;
+ }
+ } else {
+ so_data->memsz = 0;
+ }
+
+ ret = trace_statedump_event(trace_soinfo_cb, so_data->owner, so_data);
+ if (ret) {
+ goto end;
+ }
+
+ if (has_build_id) {
+ ret = trace_statedump_event(
+ trace_build_id_cb, so_data->owner, so_data);
+ free(so_data->build_id);
+ if (ret) {
+ goto end;
+ }
}
- so_data->size = sostat.st_size;
- so_data->mtime = sostat.st_mtime;
+ if (has_debug_link) {
+ ret = trace_statedump_event(
+ trace_debug_link_cb, so_data->owner, so_data);
+ free(so_data->dbg_file);
+ if (ret) {
+ goto end;
+ }
+ }
- return trace_statedump_event(trace_soinfo_cb, so_data->owner, so_data);
+end:
+ return ret;
}
static
snprintf(resolved_path, PATH_MAX - 1, "[%s]",
info->dlpi_name);
so_data.vdso = 1;
+ } else {
+ so_data.vdso = 0;
}
}