[sanitizer] Track which modules are instrumented in LoadedModule objects

This patch adds tracking which modules are instrumented and which are not. On macOS, instrumented modules link against the ASan/TSan/... dylib, so we can just check if such a load command exists or not.

Differential Revision: https://reviews.llvm.org/D28263

llvm-svn: 291268
This commit is contained in:
Kuba Mracek 2017-01-06 19:34:54 +00:00
parent fb96e04efb
commit 43d287e04e
4 changed files with 43 additions and 18 deletions

View File

@ -260,10 +260,12 @@ void LoadedModule::set(const char *module_name, uptr base_address) {
}
void LoadedModule::set(const char *module_name, uptr base_address,
ModuleArch arch, u8 uuid[kModuleUUIDSize]) {
ModuleArch arch, u8 uuid[kModuleUUIDSize],
bool instrumented) {
set(module_name, base_address);
arch_ = arch;
internal_memcpy(uuid_, uuid, sizeof(uuid_));
instrumented_ = instrumented;
}
void LoadedModule::clear() {
@ -271,6 +273,7 @@ void LoadedModule::clear() {
full_name_ = nullptr;
arch_ = kModuleArchUnknown;
internal_memset(uuid_, 0, kModuleUUIDSize);
instrumented_ = false;
while (!ranges_.empty()) {
AddressRange *r = ranges_.front();
ranges_.pop_front();

View File

@ -672,13 +672,16 @@ const uptr kModuleUUIDSize = 16;
class LoadedModule {
public:
LoadedModule()
: full_name_(nullptr), base_address_(0), arch_(kModuleArchUnknown) {
: full_name_(nullptr),
base_address_(0),
arch_(kModuleArchUnknown),
instrumented_(false) {
internal_memset(uuid_, 0, kModuleUUIDSize);
ranges_.clear();
}
void set(const char *module_name, uptr base_address);
void set(const char *module_name, uptr base_address, ModuleArch arch,
u8 uuid[kModuleUUIDSize]);
u8 uuid[kModuleUUIDSize], bool instrumented);
void clear();
void addAddressRange(uptr beg, uptr end, bool executable);
bool containsAddress(uptr address) const;
@ -687,6 +690,7 @@ class LoadedModule {
uptr base_address() const { return base_address_; }
ModuleArch arch() const { return arch_; }
const u8 *uuid() const { return uuid_; }
bool instrumented() const { return instrumented_; }
struct AddressRange {
AddressRange *next;
@ -705,6 +709,7 @@ class LoadedModule {
uptr base_address_;
ModuleArch arch_;
u8 uuid_[kModuleUUIDSize];
bool instrumented_;
IntrusiveList<AddressRange> ranges_;
};

View File

@ -77,6 +77,7 @@ class MemoryMappingLayout {
u8 current_uuid_[kModuleUUIDSize];
int current_load_cmd_count_;
char *current_load_cmd_addr_;
bool current_instrumented_;
# endif
};

View File

@ -150,22 +150,36 @@ ModuleArch ModuleArchFromCpuType(cpu_type_t cputype, cpu_subtype_t cpusubtype) {
}
}
static void FindUUID(const load_command *first_lc, u8 *uuid_output) {
const load_command *current_lc = first_lc;
while (1) {
if (current_lc->cmd == 0) return;
if (current_lc->cmd == LC_UUID) {
const uuid_command *uuid_lc = (const uuid_command *)current_lc;
const uint8_t *uuid = &uuid_lc->uuid[0];
internal_memcpy(uuid_output, uuid, kModuleUUIDSize);
return;
}
static const load_command *NextCommand(const load_command *lc) {
return (const load_command *)((char *)lc + lc->cmdsize);
}
current_lc =
(const load_command *)(((char *)current_lc) + current_lc->cmdsize);
static void FindUUID(const load_command *first_lc, u8 *uuid_output) {
for (const load_command *lc = first_lc; lc->cmd != 0; lc = NextCommand(lc)) {
if (lc->cmd != LC_UUID) continue;
const uuid_command *uuid_lc = (const uuid_command *)lc;
const uint8_t *uuid = &uuid_lc->uuid[0];
internal_memcpy(uuid_output, uuid, kModuleUUIDSize);
return;
}
}
static bool IsModuleInstrumented(const load_command *first_lc) {
for (const load_command *lc = first_lc; lc->cmd != 0; lc = NextCommand(lc)) {
if (lc->cmd != LC_LOAD_DYLIB) continue;
const dylib_command *dylib_lc = (const dylib_command *)lc;
uint32_t dylib_name_offset = dylib_lc->dylib.name.offset;
const char *dylib_name = ((const char *)dylib_lc) + dylib_name_offset;
dylib_name = StripModuleName(dylib_name);
if (dylib_name != 0 && (internal_strstr(dylib_name, "libclang_rt."))) {
return true;
}
}
return false;
}
bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,
char filename[], uptr filename_size,
uptr *protection, ModuleArch *arch, u8 *uuid) {
@ -193,10 +207,11 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,
continue;
}
}
FindUUID((const load_command *)current_load_cmd_addr_, &current_uuid_[0]);
current_instrumented_ =
IsModuleInstrumented((const load_command *)current_load_cmd_addr_);
}
FindUUID((const load_command *)current_load_cmd_addr_, &current_uuid_[0]);
for (; current_load_cmd_count_ >= 0; current_load_cmd_count_--) {
switch (current_magic_) {
// current_magic_ may be only one of MH_MAGIC, MH_MAGIC_64.
@ -244,7 +259,8 @@ void MemoryMappingLayout::DumpListOfModules(
} else {
modules->push_back(LoadedModule());
cur_module = &modules->back();
cur_module->set(cur_name, cur_beg, cur_arch, cur_uuid);
cur_module->set(cur_name, cur_beg, cur_arch, cur_uuid,
current_instrumented_);
}
cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute);
}