Skip to content

Commit

Permalink
Include vdso in the module list (#2695)
Browse files Browse the repository at this point in the history
Adds vdso to the module list at init time.  Previously, it would be added
upon execution (via the module event trigger), but would otherwise be
absent.

I'd like to also add vsyscall, when it's separate, but it has no ELF header
and that complicates placing it on the module list, so for now we leave it
off.

Adds a release note as this could affect existing clients.

Tweaks drcovlib to handle displaced tags such as for the vsyscall hook.
  • Loading branch information
derekbruening committed Nov 10, 2017
1 parent 0967dbf commit ea84da0
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 25 deletions.
2 changes: 2 additions & 0 deletions api/docs/release.dox
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ Further non-compatibility-affecting changes include:
sec_drcachesim_ops).
- Added a last-level cache miss recording feature to drcachesim.
- Added a delayed tracing feature to drcachesim.
- On Linux, the VDSO module is now included in the module list at program
startup.

**************************************************
<hr>
Expand Down
8 changes: 6 additions & 2 deletions clients/drcov/postprocess/drcov2lcov.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1160,17 +1160,21 @@ enumerate_line_info(void)
hash_entry_t *e;
drsym_error_t res;
for (e = module_htable.table[i]; e != NULL; e = e->next) {
bool has_lines = true;
num_entries++;
PRINT(3, "Enumerate line info for %s\n", (char *)e->key);
if (strcmp((char *)e->key, "<unknown>") == 0)
continue;
if (e->payload == MODULE_TABLE_IGNORE)
continue;
res = drsym_enumerate_lines((const char *)e->key, enum_line_cb, e->payload);
if (res != DRSYM_SUCCESS)
if (res != DRSYM_SUCCESS) {
WARN(1, "Failed to enumerate lines for %s\n", (char *)e->key);
has_lines = false;
}
res = drsym_free_resources((char *)e->key);
if (res != DRSYM_SUCCESS)
/* I'm using has_lines to avoid warning on vdso. */
if (res != DRSYM_SUCCESS && has_lines)
WARN(1, "Failed to free resource for %s\n", (char *)e->key);
}
}
Expand Down
8 changes: 5 additions & 3 deletions core/module_list.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2011-2015 Google, Inc. All rights reserved.
* Copyright (c) 2011-2017 Google, Inc. All rights reserved.
* Copyright (c) 2008-2010 VMware, Inc. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -261,9 +261,11 @@ module_list_add(app_pc base, size_t view_size, bool at_map, const char *filepath
module_area_create(base, view_size, at_map, filepath _IF_UNIX(inode));
ASSERT(ma != NULL);

LOG(GLOBAL, LOG_INTERP|LOG_VMAREAS, 1, "module %s ["PFX","PFX"] added\n",
LOG(GLOBAL, LOG_INTERP|LOG_VMAREAS, 1, "module %s |%s| ["PFX","PFX"] added\n",
(GET_MODULE_NAME(&ma->names) == NULL) ? "<no name>" :
GET_MODULE_NAME(&ma->names), base, base+view_size);
GET_MODULE_NAME(&ma->names),
ma->names.file_name == NULL ? "<no file>" : ma->names.file_name,
base, base+view_size);

/* note that while it would be natural to invoke the client module
* load event since we have the data for it right here, the
Expand Down
33 changes: 19 additions & 14 deletions core/unix/os.c
Original file line number Diff line number Diff line change
Expand Up @@ -7776,25 +7776,22 @@ os_add_new_app_module(dcontext_t *dcontext, bool at_map,
memquery_iterator_start(&iter, base, true /* plan to alloc a module_area_t */);
while (memquery_iterator_next(&iter)) {
if (iter.vm_start == base) {
if (iter.vm_start == vsyscall_page_start) {
ASSERT_CURIOSITY(!at_map);
} else {
ASSERT_CURIOSITY(iter.inode != 0 || base == vdso_page_start);
ASSERT_CURIOSITY(iter.offset == 0); /* first map shouldn't have offset */
/* XREF 307599 on rounding module end to the next PAGE boundary */
ASSERT_CURIOSITY((iter.vm_end - iter.vm_start ==
ALIGN_FORWARD(size, PAGE_SIZE)));
inode = iter.inode;
filename = dr_strdup(iter.comment HEAPACCT(ACCT_OTHER));
found_map = true;
}
ASSERT_CURIOSITY(iter.inode != 0 || base == vdso_page_start ||
base == vsyscall_page_start);
ASSERT_CURIOSITY(iter.offset == 0); /* first map shouldn't have offset */
/* XREF 307599 on rounding module end to the next PAGE boundary */
ASSERT_CURIOSITY((iter.vm_end - iter.vm_start ==
ALIGN_FORWARD(size, PAGE_SIZE)));
inode = iter.inode;
filename = dr_strdup(iter.comment HEAPACCT(ACCT_OTHER));
found_map = true;
break;
}
}
memquery_iterator_stop(&iter);
#ifdef HAVE_MEMINFO
/* barring weird races we should find this map except [vdso] */
ASSERT_CURIOSITY(found_map || base == vsyscall_page_start || base == vdso_page_start);
/* barring weird races we should find this map except */
ASSERT_CURIOSITY(found_map);
#else /* HAVE_MEMINFO */
/* Without /proc/maps or other memory querying interface available at
* library map time, there is no way to find out the name of the file
Expand Down Expand Up @@ -9014,6 +9011,14 @@ find_executable_vm_areas(void)
strlen(VSYSCALL_REGION_MAPS_NAME)) == 0)
vsyscall_page_start = iter.vm_start;
# endif
/* We'd like to add vsyscall to the module list too but when it's
* separate from vdso it has no ELF header which is too complex
* to force into the module list.
*/
if (module_is_header(iter.vm_start, iter.vm_end - iter.vm_start)) {
module_list_add(iter.vm_start, iter.vm_end - iter.vm_start,
false, iter.comment, iter.inode);
}
} else if (mmap_check_for_module_overlap(iter.vm_start, size,
TEST(MEMPROT_READ, iter.prot),
iter.inode, false)) {
Expand Down
12 changes: 8 additions & 4 deletions ext/drcovlib/drcovlib.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* ***************************************************************************
* Copyright (c) 2012-2016 Google, Inc. All rights reserved.
* Copyright (c) 2012-2017 Google, Inc. All rights reserved.
* ***************************************************************************/

/*
Expand Down Expand Up @@ -328,7 +328,7 @@ event_basic_block_analysis(void *drcontext, void *tag, instrlist_t *bb,
{
per_thread_t *data;
instr_t *instr;
app_pc start_pc, end_pc;
app_pc tag_pc, start_pc, end_pc;

/* do nothing for translation */
if (translating)
Expand All @@ -340,7 +340,11 @@ event_basic_block_analysis(void *drcontext, void *tag, instrlist_t *bb,
* transfer instructions, which is true for default options passed
* to DR but not for -opt_speed.
*/
start_pc = dr_fragment_app_pc(tag);
/* We separate the tag from the instr pc ranges to handle displaced code
* such as for the vsyscall hook.
*/
tag_pc = dr_fragment_app_pc(tag);
start_pc = instr_get_app_pc(instrlist_first_app(bb));
end_pc = start_pc; /* for finding the size */
for (instr = instrlist_first_app(bb);
instr != NULL;
Expand All @@ -361,7 +365,7 @@ event_basic_block_analysis(void *drcontext, void *tag, instrlist_t *bb,
* 4. The duplication can be easily handled in a post-processing step,
* which is required anyway.
*/
bb_table_entry_add(drcontext, data, start_pc, (uint)(end_pc - start_pc));
bb_table_entry_add(drcontext, data, tag_pc, (uint)(end_pc - start_pc));

if (go_native)
return DR_EMIT_GO_NATIVE;
Expand Down
5 changes: 3 additions & 2 deletions suite/tests/client-interface/events.dll.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2011-2013 Google, Inc. All rights reserved.
* Copyright (c) 2011-2017 Google, Inc. All rights reserved.
* Copyright (c) 2008-2010 VMware, Inc. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -41,6 +41,7 @@

#ifdef UNIX
# include <signal.h>
# include <string.h>
#endif

#ifdef WINDOWS
Expand Down Expand Up @@ -322,7 +323,7 @@ void module_load_event_perm(void *drcontext, const module_data_t *info, bool loa
else if (info->full_path[0] == '\\' || info->full_path[1] != ':')
dr_fprintf(STDERR, "ERROR: full_path is not in DOS format: %s\n", info->full_path);
#else
else if (info->full_path[0] != '/')
else if (info->full_path[0] != '/' && strcmp(info->full_path, "[vdso]") != 0)
dr_fprintf(STDERR, "ERROR: full_path is not absolute: %s\n", info->full_path);
#endif
}
Expand Down

0 comments on commit ea84da0

Please sign in to comment.