f35db108b9
This patch imports the runtime library in the GCC tree, ensures that -lasan is passed to the linker when -faddress-sanitizer is used and sets up the build system accordingly. ChangeLog: * configure.ac: Add libsanitizer to target_libraries. * Makefile.def: Ditto. * configure: Regenerate. * Makefile.in: Regenerate. * libsanitizer: New directory for asan runtime. Contains an empty tsan directory. gcc/ChangeLog: * gcc.c (LINK_COMMAND_SPEC): Add -laddress-sanitizer to link command if -faddress-sanitizer is on. libsanitizer: Initial checkin: migrate asan runtime from llvm. From-SVN: r193441
96 lines
2.7 KiB
C++
96 lines
2.7 KiB
C++
//===-- sanitizer_flags.cc ------------------------------------------------===//
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "sanitizer_flags.h"
|
|
|
|
#include "sanitizer_common.h"
|
|
#include "sanitizer_libc.h"
|
|
|
|
namespace __sanitizer {
|
|
|
|
static bool GetFlagValue(const char *env, const char *name,
|
|
const char **value, int *value_length) {
|
|
if (env == 0)
|
|
return false;
|
|
const char *pos = internal_strstr(env, name);
|
|
const char *end;
|
|
if (pos == 0)
|
|
return false;
|
|
pos += internal_strlen(name);
|
|
if (pos[0] != '=') {
|
|
end = pos;
|
|
} else {
|
|
pos += 1;
|
|
if (pos[0] == '"') {
|
|
pos += 1;
|
|
end = internal_strchr(pos, '"');
|
|
} else if (pos[0] == '\'') {
|
|
pos += 1;
|
|
end = internal_strchr(pos, '\'');
|
|
} else {
|
|
end = internal_strchr(pos, ' ');
|
|
}
|
|
if (end == 0)
|
|
end = pos + internal_strlen(pos);
|
|
}
|
|
*value = pos;
|
|
*value_length = end - pos;
|
|
return true;
|
|
}
|
|
|
|
static bool StartsWith(const char *flag, int flag_length, const char *value) {
|
|
if (!flag || !value)
|
|
return false;
|
|
int value_length = internal_strlen(value);
|
|
return (flag_length >= value_length) &&
|
|
(0 == internal_strncmp(flag, value, value_length));
|
|
}
|
|
|
|
void ParseFlag(const char *env, bool *flag, const char *name) {
|
|
const char *value;
|
|
int value_length;
|
|
if (!GetFlagValue(env, name, &value, &value_length))
|
|
return;
|
|
if (StartsWith(value, value_length, "0") ||
|
|
StartsWith(value, value_length, "no") ||
|
|
StartsWith(value, value_length, "false"))
|
|
*flag = false;
|
|
if (StartsWith(value, value_length, "1") ||
|
|
StartsWith(value, value_length, "yes") ||
|
|
StartsWith(value, value_length, "true"))
|
|
*flag = true;
|
|
}
|
|
|
|
void ParseFlag(const char *env, int *flag, const char *name) {
|
|
const char *value;
|
|
int value_length;
|
|
if (!GetFlagValue(env, name, &value, &value_length))
|
|
return;
|
|
*flag = internal_atoll(value);
|
|
}
|
|
|
|
static LowLevelAllocator allocator_for_flags;
|
|
|
|
void ParseFlag(const char *env, const char **flag, const char *name) {
|
|
const char *value;
|
|
int value_length;
|
|
if (!GetFlagValue(env, name, &value, &value_length))
|
|
return;
|
|
// Copy the flag value. Don't use locks here, as flags are parsed at
|
|
// tool startup.
|
|
char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1));
|
|
internal_memcpy(value_copy, value, value_length);
|
|
value_copy[value_length] = '\0';
|
|
*flag = value_copy;
|
|
}
|
|
|
|
} // namespace __sanitizer
|