From 1a4a1345c93d716d50cf10e4717f4cc895e313c6 Mon Sep 17 00:00:00 2001 From: Antoine Busque Date: Fri, 15 Apr 2016 16:54:18 -0400 Subject: [PATCH 1/1] Use is_pic field instead of reading ELF header MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Antoine Busque Signed-off-by: Jérémie Galarneau --- include/babeltrace/so-info.h | 4 ++- lib/debuginfo.c | 51 +++++++++++++++++++++++++++++++----- lib/so-info.c | 5 ++-- tests/lib/test_so_info.c | 8 +++--- 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/include/babeltrace/so-info.h b/include/babeltrace/so-info.h index 453aa8a7..7badeb2f 100644 --- a/include/babeltrace/so-info.h +++ b/include/babeltrace/so-info.h @@ -87,12 +87,14 @@ int so_info_init(void); * @param path Path to the ELF file * @param low_addr Base address of the executable * @param memsz In-memory size of the executable + * @param is_pic Whether the executable is position independent + * code (PIC) * @returns Pointer to the new so_info on success, * NULL on failure. */ BT_HIDDEN struct so_info *so_info_create(const char *path, uint64_t low_addr, - uint64_t memsz); + uint64_t memsz, bool is_pic); /** * Destroy the given so_info instance diff --git a/lib/debuginfo.c b/lib/debuginfo.c index 3d033b9a..2b59ff93 100644 --- a/lib/debuginfo.c +++ b/lib/debuginfo.c @@ -548,12 +548,13 @@ end: } static -void handle_statedump_soinfo_event(struct debug_info *debug_info, - struct ctf_event_definition *event_def) +void handle_bin_info_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def, bool has_pic_field) { struct bt_definition *baddr_def = NULL; struct bt_definition *memsz_def = NULL; struct bt_definition *sopath_def = NULL; + struct bt_definition *is_pic_def = NULL; struct bt_definition *vpid_def = NULL; struct bt_definition *event_fields_def = NULL; struct bt_definition *sec_def = NULL; @@ -563,6 +564,7 @@ void handle_statedump_soinfo_event(struct debug_info *debug_info, int64_t vpid; const char *sopath; gpointer key = NULL; + bool is_pic; event_fields_def = (struct bt_definition *) event_def->event_fields; sec_def = (struct bt_definition *) @@ -587,6 +589,25 @@ void handle_statedump_soinfo_event(struct debug_info *debug_info, goto end; } + if (has_pic_field) { + is_pic_def = bt_lookup_definition(event_fields_def, "_is_pic"); + if (!is_pic_def) { + goto end; + } + + if (is_pic_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + is_pic = (bt_get_unsigned_int(is_pic_def) == 1); + } else { + /* + * dlopen has no is_pic field, because the shared + * object is always PIC. + */ + is_pic = true; + } + vpid_def = bt_lookup_definition(sec_def, "_vpid"); if (!vpid_def) { goto end; @@ -641,7 +662,7 @@ void handle_statedump_soinfo_event(struct debug_info *debug_info, goto end; } - so = so_info_create(sopath, baddr, memsz); + so = so_info_create(sopath, baddr, memsz, is_pic); if (!so) { goto end; } @@ -656,6 +677,21 @@ end: return; } +static inline +void handle_soinfo_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def) +{ + handle_bin_info_event(debug_info, event_def, true); +} + +static inline +void handle_dlopen_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def) +{ + handle_bin_info_event(debug_info, event_def, false); +} + + static void handle_statedump_start(struct debug_info *debug_info, struct ctf_event_definition *event_def) @@ -741,10 +777,11 @@ void debug_info_handle_event(struct debug_info *debug_info, event_class = g_ptr_array_index(stream_class->events_by_id, event->stream->event_id); - if (event_class->name == debug_info->q_statedump_soinfo || - event_class->name == debug_info->q_dl_open) { - /* State dump/dlopen() */ - handle_statedump_soinfo_event(debug_info, event); + if (event_class->name == debug_info->q_statedump_soinfo) { + /* State dump */ + handle_soinfo_event(debug_info, event); + } else if (event_class->name == debug_info->q_dl_open) { + handle_dlopen_event(debug_info, event); } else if (event_class->name == debug_info->q_statedump_start) { /* Start state dump */ handle_statedump_start(debug_info, event); diff --git a/lib/so-info.c b/lib/so-info.c index 83ddccc8..a5ddfe51 100644 --- a/lib/so-info.c +++ b/lib/so-info.c @@ -65,7 +65,7 @@ int so_info_init(void) BT_HIDDEN struct so_info *so_info_create(const char *path, uint64_t low_addr, - uint64_t memsz) + uint64_t memsz, bool is_pic) { struct so_info *so = NULL; GElf_Ehdr *ehdr = NULL; @@ -113,8 +113,7 @@ struct so_info *so_info_create(const char *path, uint64_t low_addr, goto error; } - /* Position independent code has an e_type value of ET_DYN. */ - so->is_pic = ehdr->e_type == ET_DYN; + so->is_pic = is_pic; so->memsz = memsz; so->low_addr = low_addr; so->high_addr = so->low_addr + so->memsz; diff --git a/tests/lib/test_so_info.c b/tests/lib/test_so_info.c index 3738cb43..58d02180 100644 --- a/tests/lib/test_so_info.c +++ b/tests/lib/test_so_info.c @@ -64,7 +64,7 @@ void test_so_info_build_id(const char *data_dir) snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_BUILD_ID); - so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ); + so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true); ok(so != NULL, "so_info_create succesful"); /* Test setting build_id */ @@ -105,7 +105,7 @@ void test_so_info_debug_link(const char *data_dir) snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_DEBUG_LINK); - so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ); + so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true); ok(so != NULL, "so_info_create succesful"); /* Test setting debug link */ @@ -146,7 +146,7 @@ void test_so_info_elf(const char *data_dir) snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_ELF); - so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ); + so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true); ok(so != NULL, "so_info_create succesful"); /* Test function name lookup (with ELF) */ @@ -183,7 +183,7 @@ void test_so_info(const char *data_dir) snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME); - so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ); + so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true); ok(so != NULL, "so_info_create succesful"); /* Test so_info_has_address */ -- 2.34.1