packaing: switch off build_html
[platform/upstream/glibc.git] / gcc-wrapper.cc
1 #include <regex>
2 #include <string>
3 #include <unistd.h>
4
5 #ifdef DEBUG
6 #include <errno.h>
7 #include <iostream>
8 #endif
9
10 const char *GCC = "/usr/bin/gcc";
11 static const int ASAN_OPTIONS_MIN = 3;
12 #ifndef HWASAN_BUILD
13 static const int ASAN_OPTIONS_MAX = 7;
14 #else
15 static const int ASAN_OPTIONS_MAX = 5;
16 #endif
17
18 static std::string blacklist[] = {
19     "rtld", "/dl-", "elf", "string/mem", "time/time", "time/gettimeofday",
20     "time/timegm", "time/timespec_get", "nptl/libc_pthread_init",
21     "nptl/register-atfork",
22 #ifndef HWASAN_BUILD
23     // In Tizen, ASan tries to write error log to procfs, in case procfs is not
24     // mounted,  this action will generate a kernel panic. So, just disable
25     // errors which happens because  of dword-aligned reading by glibc.
26     "string",
27 #else
28     "/init-", "ctype-info", "setjmp/",
29 #endif
30 };
31
32 #ifndef HWASAN_BUILD
33 static const char *asan_options[ASAN_OPTIONS_MAX] = {
34     "-fno-omit-frame-pointer",    "-Wno-error",         "-DSKIP_IFUNC",
35     "-fsanitize-recover=address", "-fsanitize=address", "--param",
36     "asan-use-after-return=0",
37 };
38 #else
39 static const char *asan_options[ASAN_OPTIONS_MAX] = {
40     "-fno-omit-frame-pointer",    "-Wno-error",         "-DSKIP_IFUNC",
41     "-fsanitize=hwaddress", "-fsanitize-recover=hwaddress",
42 };
43 #endif
44
45 static const char *defs_option = "-Wl,-z,defs";
46 static const size_t defs_option_length = 11;
47
48 static bool AllowAsan(const char *output) {
49   if (!output)
50     return false;
51
52   std::string search_string(output);
53   if (!std::regex_match(search_string, std::regex(R"(/.*build/(.*).os$)")))
54     return false;
55
56   for (auto &b : blacklist) {
57     size_t found = search_string.find(b);
58     if (found != std::string::npos)
59       return false;
60   }
61   return true;
62 }
63
64 static const char *o(const int argc, const char **argv) {
65   for (int i = 1; i < argc; ++i) {
66     if (!argv[i])
67       break;
68     if (argv[i][0] == '-' && argv[i][1] == 'o')
69       return argv[i + 1];
70   }
71   return nullptr;
72 }
73
74 static void InitASanCommandLine(const int argc, const char **argv,
75                                 int &asan_argc, const char **&asan_argv) {
76   asan_argv = new const char *[asan_argc + 1];
77   if (!asan_argv) {
78 #ifdef DEBUG
79     std::cerr << "Can't allocate memory " << std::endl;
80 #endif
81     abort();
82   }
83   asan_argv[0] = GCC;
84   int index, asan_index;
85
86   for (asan_index = index = 1; index < argc; ++index) {
87     // Look for -Wl,-z,defs, because we don't need it
88     if (__builtin_strncmp(argv[index], defs_option, defs_option_length) == 0)
89       continue;
90     asan_argv[asan_index] = argv[index];
91     ++asan_index;
92   }
93   asan_argc = asan_index;
94 }
95
96 int main(int argc, const char **argv) {
97   if (argc == 1)
98     return 0;
99
100   const bool allow_asan = AllowAsan(o(argc, argv));
101   int options_count = allow_asan ? ASAN_OPTIONS_MAX : ASAN_OPTIONS_MIN;
102   int asan_argc = argc + options_count;
103
104   const char **asan_argv = NULL;
105   InitASanCommandLine(argc, argv, asan_argc, asan_argv);
106
107   // copy ASan options
108   __builtin_memcpy(asan_argv + asan_argc, asan_options,
109                    sizeof(char *) * options_count);
110
111   asan_argv[asan_argc + options_count] = NULL;
112   execv(GCC, (char **)asan_argv);
113 #ifdef DEBUG
114   std::cerr << "Errno: " << errno;
115 #endif
116 }