1f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//===-- sanitizer_flags.cc ------------------------------------------------===// 2f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// 3f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// The LLVM Compiler Infrastructure 4f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// 5f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// This file is distributed under the University of Illinois Open Source 6f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// License. See LICENSE.TXT for details. 7f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// 8f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//===----------------------------------------------------------------------===// 9f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// 10f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// This file is a part of ThreadSanitizer/AddressSanitizer runtime. 11f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// 12f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//===----------------------------------------------------------------------===// 13f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 14f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov#include "sanitizer_flags.h" 15f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 16f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov#include "sanitizer_common.h" 17f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov#include "sanitizer_libc.h" 18f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 19f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovnamespace __sanitizer { 20f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 21947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonovstatic bool GetFlagValue(const char *env, const char *name, 22947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov const char **value, int *value_length) { 23f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov if (env == 0) 24947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov return false; 25f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov const char *pos = internal_strstr(env, name); 26f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov const char *end; 27f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov if (pos == 0) 28947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov return false; 29f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov pos += internal_strlen(name); 30f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov if (pos[0] != '=') { 31f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov end = pos; 32f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov } else { 33f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov pos += 1; 34f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov if (pos[0] == '"') { 35f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov pos += 1; 36f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov end = internal_strchr(pos, '"'); 37f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov } else if (pos[0] == '\'') { 38f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov pos += 1; 39f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov end = internal_strchr(pos, '\''); 40f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov } else { 41f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov end = internal_strchr(pos, ' '); 42f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov } 43f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov if (end == 0) 44f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov end = pos + internal_strlen(pos); 45f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov } 46947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov *value = pos; 47947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov *value_length = end - pos; 48947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov return true; 49947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov} 50947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov 51947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonovstatic bool StartsWith(const char *flag, int flag_length, const char *value) { 52947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov if (!flag || !value) 53947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov return false; 54947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov int value_length = internal_strlen(value); 55947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov return (flag_length >= value_length) && 56947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov (0 == internal_strncmp(flag, value, value_length)); 57f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov} 58f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 59f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovvoid ParseFlag(const char *env, bool *flag, const char *name) { 60947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov const char *value; 61947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov int value_length; 62947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov if (!GetFlagValue(env, name, &value, &value_length)) 63f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov return; 64947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov if (StartsWith(value, value_length, "0") || 65947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov StartsWith(value, value_length, "no") || 66947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov StartsWith(value, value_length, "false")) 67f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov *flag = false; 68947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov if (StartsWith(value, value_length, "1") || 69947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov StartsWith(value, value_length, "yes") || 70947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov StartsWith(value, value_length, "true")) 71f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov *flag = true; 72f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov} 73f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 74f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovvoid ParseFlag(const char *env, int *flag, const char *name) { 75947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov const char *value; 76947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov int value_length; 77947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov if (!GetFlagValue(env, name, &value, &value_length)) 78f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov return; 79947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov *flag = internal_atoll(value); 80f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov} 81f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 82947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonovstatic LowLevelAllocator allocator_for_flags; 83947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov 84f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovvoid ParseFlag(const char *env, const char **flag, const char *name) { 85947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov const char *value; 86947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov int value_length; 87947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov if (!GetFlagValue(env, name, &value, &value_length)) 88f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov return; 89d883c8007ea8b5ffad10d82a66b1bb262e109705Alexey Samsonov // Copy the flag value. Don't use locks here, as flags are parsed at 90d883c8007ea8b5ffad10d82a66b1bb262e109705Alexey Samsonov // tool startup. 91947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1)); 92947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov internal_memcpy(value_copy, value, value_length); 93947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov value_copy[value_length] = '\0'; 94947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov *flag = value_copy; 95f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov} 96f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov 97f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov} // namespace __sanitizer 98