Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Revert (#2940)" #2973

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/docs/release.dox
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ Further non-compatibility-affecting changes include:
and drreg_is_instr_spill_or_restore().
- Added dr_app_stop_and_cleanup_with_stats() to obtain stats values right before
cleanup.
- drmodtrack now allocates an entry per segment for each loaded module.
Added a file offset field to module_segment_data_t for UNIX platforms.
drcachesim saves file offset information in modules.log on UNIX platforms.

**************************************************
<hr>
Expand Down
1 change: 1 addition & 0 deletions core/lib/instrument.c
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,7 @@ create_and_initialize_module_data(app_pc start, app_pc end, app_pc entry_point,
copy->segments[i].start = os_segments[i].start;
copy->segments[i].end = os_segments[i].end;
copy->segments[i].prot = os_segments[i].prot;
copy->segments[i].offset = os_segments[i].offset;
}
} else {
ASSERT(segments != NULL);
Expand Down
1 change: 1 addition & 0 deletions core/lib/instrument_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -2918,6 +2918,7 @@ typedef struct _module_segment_data_t {
app_pc start; /**< Start address of the segment, page-aligned backward. */
app_pc end; /**< End address of the segment, page-aligned forward. */
uint prot; /**< Protection attributes of the segment */
uint64 offset; /**< Offset of the segment from the beginning of the backing file */
} module_segment_data_t;
#endif

Expand Down
4 changes: 3 additions & 1 deletion core/unix/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ module_add_segment_data(OUT os_module_data_t *out_data,
size_t segment_size,
uint segment_prot, /* MEMPROT_ */
size_t alignment,
bool shared)
bool shared,
uint64 offset)
{
uint seg, i;
if (out_data->alignment == 0) {
Expand Down Expand Up @@ -522,6 +523,7 @@ module_add_segment_data(OUT os_module_data_t *out_data,
ALIGN_FORWARD(segment_start + segment_size, PAGE_SIZE);
out_data->segments[seg].prot = segment_prot;
out_data->segments[seg].shared = shared;
out_data->segments[seg].offset = offset;
if (seg > 0) {
ASSERT(out_data->segments[seg].start >= out_data->segments[seg - 1].end);
if (out_data->segments[seg].start > out_data->segments[seg - 1].end)
Expand Down
4 changes: 3 additions & 1 deletion core/unix/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ typedef struct _module_segment_t {
app_pc end;
uint prot;
bool shared; /* not unique to this module */
uint64 offset;
} module_segment_t;

typedef struct _os_module_data_t {
Expand Down Expand Up @@ -151,7 +152,8 @@ module_add_segment_data(OUT os_module_data_t *out_data,
size_t segment_size,
uint segment_prot,
size_t alignment,
bool shared);
bool shared,
uint64 offset);

/* Redirected functions for loaded module,
* they are also used by __wrap_* functions in instrument.c
Expand Down
3 changes: 2 additions & 1 deletion core/unix/module_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,8 @@ module_walk_program_headers(app_pc base, size_t view_size, bool at_map, bool dyn
(app_pc) prog_hdr->p_vaddr + load_delta,
prog_hdr->p_memsz,
module_segment_prot_to_osprot(prog_hdr),
prog_hdr->p_align, false/*!shared*/);
prog_hdr->p_align, false/*!shared*/,
prog_hdr->p_offset);
}
found_load = true;
}
Expand Down
3 changes: 2 additions & 1 deletion core/unix/module_macho.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ module_walk_program_headers(app_pc base, size_t view_size, bool at_map, bool dyn
* ignoring for now
*/
PAGE_SIZE,
shared);
shared,
seg->fileoff);
}
} else if (cmd->cmd == LC_SYMTAB) {
/* even if stripped, dynamic symbols are in this table */
Expand Down
4 changes: 4 additions & 0 deletions ext/drcovlib/drcovlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ typedef struct _drmodtrack_info_t {
* passed to drmodtrack_offline_lookup().
*/
uint index;
/**
* The offset of this segment from the beginning of this backing file.
*/
uint64 offset;
} drmodtrack_info_t;

DR_EXPORT
Expand Down
96 changes: 57 additions & 39 deletions ext/drcovlib/modules.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#include <stdio.h>
#include <stddef.h>

#define MODULE_FILE_VERSION 3
#define MODULE_FILE_VERSION 4

#define NUM_GLOBAL_MODULE_CACHE 8
#define NUM_THREAD_MODULE_CACHE 4
Expand All @@ -55,6 +55,10 @@ typedef struct _module_entry_t {
*/
module_data_t *data;
void *custom;
#ifndef WINDOWS
/* The file offset of the segment */
uint64 offset;
#endif
} module_entry_t;

typedef struct _module_table_t {
Expand Down Expand Up @@ -195,29 +199,27 @@ event_module_load(void *drcontext, const module_data_t *data, bool loaded)
entry->custom = module_load_cb(entry->data);
drvector_append(&module_table.vector, entry);
#ifndef WINDOWS
if (!data->contiguous) {
uint j;
module_entry_t *sub_entry;
ASSERT(entry->start == data->segments[0].start, "illegal segments");
entry->end = data->segments[0].end;
for (j = 1/*we did 1st*/; j < data->num_segments; j++) {
if (data->segments[j].start == data->segments[j-1].end)
continue; /* contiguous */
/* Add an entry for each separate piece. On unload we assume
* that these entries are consecutive following the main entry.
*/
sub_entry = dr_global_alloc(sizeof(*sub_entry));
sub_entry->id = module_table.vector.entries;
sub_entry->containing_id = entry->id;
sub_entry->start = data->segments[j].start;
sub_entry->end = data->segments[j].end;
sub_entry->unload = false;
/* These fields are shared. */
sub_entry->data = entry->data;
sub_entry->custom = entry->custom;
drvector_append(&module_table.vector, sub_entry);
global_module_cache_add(module_table.cache, sub_entry);
}
entry->offset = data->segments[0].offset;
uint j;
module_entry_t *sub_entry;
ASSERT(entry->start == data->segments[0].start, "illegal segments");
entry->end = data->segments[0].end;
for (j = 1/*we did 1st*/; j < data->num_segments; j++) {
/* Add an entry for each separate piece. On unload we assume
* that these entries are consecutive following the main entry.
*/
sub_entry = dr_global_alloc(sizeof(*sub_entry));
sub_entry->id = module_table.vector.entries;
sub_entry->containing_id = entry->id;
sub_entry->start = data->segments[j].start;
sub_entry->end = data->segments[j].end;
sub_entry->unload = false;
/* These fields are shared. */
sub_entry->data = entry->data;
sub_entry->custom = entry->custom;
sub_entry->offset = data->segments[j].offset;
drvector_append(&module_table.vector, sub_entry);
global_module_cache_add(module_table.cache, sub_entry);
}
#endif
}
Expand Down Expand Up @@ -312,17 +314,15 @@ event_module_unload(void *drcontext, const module_data_t *data)
if (entry != NULL) {
entry->unload = true;
#ifndef WINDOWS
if (!data->contiguous) {
int j;
/* Find non-contiguous entries, which are consecutive and after the main. */
for (j = i + 1; j < module_table.vector.entries; j++) {
module_entry_t *sub_entry = drvector_get_entry(&module_table.vector, j);
ASSERT(sub_entry != NULL, "fail to get module entry");
if (sub_entry->containing_id == entry->id)
sub_entry->unload = true;
else
break;
}
int j;
/* Find non-contiguous entries, which are consecutive and after the main. */
for (j = i + 1; j < module_table.vector.entries; j++) {
module_entry_t *sub_entry = drvector_get_entry(&module_table.vector, j);
ASSERT(sub_entry != NULL, "fail to get module entry");
if (sub_entry->containing_id == entry->id)
sub_entry->unload = true;
else
break;
}
#endif
} else
Expand Down Expand Up @@ -399,6 +399,7 @@ typedef struct _module_read_entry_t {
char *path; /* may or may not point to path_buf */
char path_buf[MAXIMUM_PATH];
void *custom;
uint64 offset;
} module_read_entry_t;

typedef struct _module_read_info_t {
Expand All @@ -413,9 +414,10 @@ static int
module_read_entry_print(module_read_entry_t *entry, uint idx, char *buf, size_t size)
{
int len, total_len = 0;
len = dr_snprintf(buf, size, "%3u, %3u, " PFX ", " PFX ", " PFX ", ",
len = dr_snprintf(buf, size, "%3u, %3u, " PFX ", " PFX ", " PFX ", "
ZHEX64_FORMAT_STRING ", ",
idx, entry->containing_id, entry->base,
entry->base+entry->size, entry->entry);
entry->base+entry->size, entry->entry, entry->offset);
if (len == -1)
return -1;
buf += len;
Expand Down Expand Up @@ -466,6 +468,10 @@ module_table_entry_print(module_entry_t *entry, char *buf, size_t size)
#endif
read_entry.path = full_path;
read_entry.custom = entry->custom;
#ifndef WINDOWS
// For unices we record the physical offset from the backing file.
read_entry.offset = entry->offset;
#endif
return module_read_entry_print(&read_entry, entry->id, buf, size);
}

Expand All @@ -484,7 +490,7 @@ drmodtrack_dump_buf_headers(char *buf_in, size_t size, uint count, OUT int *len_
buf += len;
size -= len;

len = dr_snprintf(buf, size, "Columns: id, containing_id, start, end, entry");
len = dr_snprintf(buf, size, "Columns: id, containing_id, start, end, entry, offset");
if (len == -1)
return DRCOVLIB_ERROR_BUF_TOO_SMALL;
buf += len;
Expand Down Expand Up @@ -663,13 +669,23 @@ drmodtrack_offline_read(file_t file, const char *map, OUT const char **next_line
goto read_error;
info->mod[i].containing_id = mod_id;
buf = skip_commas_and_spaces(buf, 4);
} else {
} else
if (version == 3) {
if (dr_sscanf(buf, "%u, %u, "PIFX", "PIFX", "PIFX", ",
&mod_id, &info->mod[i].containing_id,
&info->mod[i].base, &end, &info->mod[i].entry) != 5 ||
mod_id != i)
goto read_error;
buf = skip_commas_and_spaces(buf, 5);
} else { // version == 4
if (dr_sscanf(buf, "%u, %u, "PIFX", "PIFX", "
PIFX", "HEX64_FORMAT_STRING", ",
&mod_id, &info->mod[i].containing_id,
&info->mod[i].base, &end, &info->mod[i].entry,
&info->mod[i].offset) != 6 ||
mod_id != i)
goto read_error;
buf = skip_commas_and_spaces(buf, 6);
}
if (buf == NULL)
goto read_error;
Expand Down Expand Up @@ -727,6 +743,8 @@ drmodtrack_offline_lookup(void *handle, uint index, OUT drmodtrack_info_t *out)
out->custom = info->mod[index].custom;
if (out->struct_size > offsetof(drmodtrack_info_t, index))
out->index = index;
if (out->struct_size > offsetof(drmodtrack_info_t, offset))
out->offset = info->mod[index].offset;
return DRCOVLIB_SUCCESS;
}

Expand Down
14 changes: 14 additions & 0 deletions suite/tests/client-interface/drmodtrack-test.dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "drx.h"
#include "client_tools.h"
#include "string.h"
#include "stddef.h"

#ifdef WINDOWS
# pragma warning( disable : 4100) /* unreferenced formal parameter */
Expand Down Expand Up @@ -132,6 +133,19 @@ event_exit(void)
CHECK(((app_pc)info.custom) == info.start ||
info.containing_index != i, "custom field doesn't match");
CHECK(info.index == i, "index field doesn't match");
#ifndef WINDOWS
if (info.struct_size > offsetof(drmodtrack_info_t, offset)) {
module_data_t * data = dr_lookup_module(info.start);
for (uint j = 0; j < data->num_segments; j++) {
module_segment_data_t *seg = data->segments + j;
if (seg->start == info.start) {
CHECK(seg->offset == info.offset,
"Module data offset and drmodtrack offset don't match");
}
}
dr_free_module_data(data);
}
#endif
}

char *buf_offline;
Expand Down