StdLib遍是可以被关闭的,可以在opt命令中传入选项“disable-dsa-stdlib”来关闭它。如果StdLib遍是激活的,在下面它将为C库函数产生DSGraph对象。
StdLibDataStructures::runOnModule(续)
589 if(!DisableStdLib) {
590
591 //
592 // Scan throughthe function summaries and process functions by summary.
593 //
594 for (int x= 0; recFuncs[x].name; ++x)
595 if (Function* F =M.getFunction(recFuncs[x].name))
596 if (F->isDeclaration()) {
597 processFunction(x, F);
598 }
599
600 std::set<std::string>::iterator ai =AllocWrappersAnalysis->alloc_begin();
601 std::set<std::string>::iterator ae =AllocWrappersAnalysis->alloc_end();
602 int x;
603 for (x = 0;recFuncs[x].name; ++x) {
604 if(recFuncs[x].name ==std::string("malloc"))
605 break;
606 }
607
608 for(;ai !=ae; ++ai) {
609 if(Function* F = M.getFunction(*ai))
610 processFunction(x, F);
611 }
612
613 ai =AllocWrappersAnalysis->dealloc_begin();
614 ae =AllocWrappersAnalysis->dealloc_end();
615 for (x = 0;recFuncs[x].name; ++x) {
616 if(recFuncs[x].name ==std::string("free"))
617 break;
618 }
619
620 for(;ai !=ae; ++ai) {
621 if(Function* F = M.getFunction(*ai))
622 processFunction(x, F);
623 }
具体为哪些库函数创建DSGraph对象呢?这由变量recFuncs来确定。recFuncs是一个匿名类型的struct数组:
91 const struct{
92 const char*name;
93 libAction action;
94 } recFuncs[] = {
95 {"stat", {NRET_YNARGS, NRET_NYARGS,NRET_NARGS, NRET_NARGS, false}},
96 {"fstat", {NRET_YNARGS,NRET_NYARGS, NRET_NARGS, NRET_NARGS, false}},
97 {"lstat", {NRET_YNARGS,NRET_NYARGS, NRET_NARGS, NRET_NARGS, false}},
98
99 {"getenv", {NRET_YNARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
100 {"getrusage", {NRET_YNARGS,YRET_NYARGS, NRET_NARGS, NRET_NARGS, false}},
101 {"getrlimit", {NRET_YNARGS,YRET_NYARGS, NRET_NARGS, NRET_NARGS, false}},
102 {"setrlimit", {NRET_YARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
103 {"getcwd", {NRET_NYARGS,YRET_YNARGS, NRET_NARGS, YRET_YNARGS, false}},
104
105 {"select", NRET_YARGS, YRET_YNARGS,NRET_NARGS, NRET_NARGS, false}},
106 {"_setjmp", NRET_YARGS, YRET_YARGS,NRET_NARGS, NRET_NARGS, false}},
107 {"longjmp", {NRET_YARGS,NRET_YARGS, NRET_NARGS, NRET_NARGS, false}},
108
109 {"remove", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
110 {"rename", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
111 {"unlink", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
112 {"fileno", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
113 {"create", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
114 {"write", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
115 {"read", {NRET_YARGS, YRET_YARGS,NRET_NARGS, NRET_NARGS, false}},
116 {"truncate", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
117 {"open", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
118
119 {"chdir", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
120 {"mkdir", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
121 {"rmdir", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
122
123 {"chmod", {NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
124 {"fchmod", {NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
125
126 {"kill", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
127 {"pipe", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
128
129 {"execl", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
130 {"execlp", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
131 {"execle", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
132 {"execv", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
133 {"execvp", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
134
135 {"time", {NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
136 {"times", {NRET_YARGS, YRET_YARGS,NRET_NARGS, NRET_NARGS, false}},
137 {"ctime", {NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
138 {"asctime", {NRET_YARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
139 {"utime", NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
140 {"localtime", {NRET_YARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
141 {"gmtime", NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
142 {"ftime", {NRET_YARGS, NRET_YARGS,NRET_NARGS, NRET_NARGS, false}},
143
144 // printf notstrictly true, %n could cause a write
145 {"printf", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS,false}},
146 {"fprintf", {NRET_YARGS,NRET_YNARGS, NRET_NARGS, NRET_NARGS, false}},
147 {"fprintf", {NRET_YARGS,NRET_YNARGS, NRET_NARGS, NRET_NARGS, false}},
148 {"sprintf", {NRET_YARGS, NRET_YNARGS,NRET_NARGS, NRET_NARGS, false}},
149 {"snprintf", {NRET_YARGS, NRET_YNARGS,NRET_NARGS, NRET_NARGS, false}},
150 {"vsnprintf", {NRET_YARGS,YRET_YNARGS, NRET_NARGS, NRET_NARGS, false}},
151 {"sscanf", {NRET_YARGS,YRET_NYARGS, NRET_NARGS, NRET_NARGS, false}},
152 {"scanf", {NRET_YARGS, YRET_NYARGS,NRET_NARGS, NRET_NARGS, false}},
153 {"fscanf", {NRET_YARGS, YRET_NYARGS,NRET_NARGS, NRET_NARGS, false}},
154
155 {"calloc", NRET_NARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
156 {"malloc", {NRET_NARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
157 {"valloc", {NRET_NARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
158 {"realloc", {NRET_NARGS,YRET_NARGS, YRET_YNARGS, YRET_YNARGS,false}},
159 {"free", {NRET_NARGS, NRET_NARGS,NRET_YNARGS, NRET_NARGS, false}},
160
161 {"strdup", {NRET_YARGS, YRET_NARGS,YRET_NARGS, YRET_YARGS, false}},
162 {"__strdup", {NRET_YARGS,YRET_NARGS, YRET_NARGS, YRET_YARGS, false}},
163 {"wcsdup", {NRET_YARGS, YRET_NARGS,YRET_NARGS, YRET_YARGS, false}},
164
165 {"strlen", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
166 {"wcslen", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
167
168 {"atoi", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
169 {"atof", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
170 {"atol", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
171 {"atoll", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
172 {"atoq", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
173
174 {"memcmp", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
175 {"strcmp", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
176 {"wcscmp", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
177 {"strncmp", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
178 {"wcsncmp", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
179 {"strcasecmp", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
180 {"wcscasecmp", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
181 {"strncasecmp", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
182 {"wcsncasecmp", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
183
184 {"strcat", {NRET_YARGS, YRET_YARGS,NRET_NARGS, YRET_YARGS, true}},
185 {"strncat", {NRET_YARGS,YRET_YARGS, NRET_NARGS, YRET_YARGS, true}},
186
187 {"strcpy", {NRET_YARGS, YRET_YARGS,NRET_NARGS, YRET_YARGS, true}},
188 {"stpcpy", {NRET_YARGS, YRET_YARGS,NRET_NARGS, YRET_YARGS, true}},
189 {"wcscpy", {NRET_YARGS, YRET_YARGS,NRET_NARGS, YRET_YARGS, true}},
190 {"strncpy", {NRET_YARGS,YRET_YARGS, NRET_NARGS, YRET_YARGS, true}},
191 {"wcsncpy", {NRET_YARGS,YRET_YARGS, NRET_NARGS, YRET_YARGS, true}},
192 {"memcpy", {NRET_YARGS, YRET_YARGS,NRET_NARGS, YRET_YARGS, true}},
193 {"memccpy", {NRET_YARGS,YRET_YARGS, NRET_NARGS, YRET_YARGS, true}},
194 {"wmemccpy", {NRET_YARGS,YRET_YARGS, NRET_NARGS, YRET_YARGS, true}},
195 {"memmove", {NRET_YARGS,YRET_YARGS, NRET_NARGS, YRET_YARGS, true}},
196
197 {"bcopy", {NRET_YARGS, NRET_YARGS,NRET_NARGS, NRET_YARGS, true}},
198 {"bcmp", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, true}},
199
200 {"strerror", {NRET_YARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, true}},
201 {"clearerr", {NRET_YARGS,NRET_YARGS, NRET_NARGS, NRET_NARGS, false}},
202 {"strstr", {NRET_YARGS, YRET_NARGS,NRET_NARGS, YRET_YNARGS, true}},
203 {"wcsstr", {NRET_YARGS, YRET_NARGS,NRET_NARGS, YRET_YNARGS, true}},
204 {"strspn", {NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, true}},
205 {"wcsspn", {NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, true}},
206 {"strcspn", {NRET_YARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, true}},
207 {"wcscspn", {NRET_YARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, true}},
208 {"strtok", {NRET_YARGS, YRET_YARGS,NRET_NARGS, YRET_YNARGS, true}},
209 {"strpbrk", {NRET_YARGS,YRET_NARGS, NRET_NARGS, YRET_YNARGS, true}},
210 {"wcspbrk", {NRET_YARGS,YRET_NARGS, NRET_NARGS, YRET_YNARGS, true}},
211
212 {"strchr", {NRET_YARGS, YRET_NARGS,NRET_NARGS, YRET_YNARGS, true}},
213 {"wcschr", {NRET_YARGS, YRET_NARGS,NRET_NARGS, YRET_YNARGS, true}},
214 {"strrchr", {NRET_YARGS,YRET_NARGS, NRET_NARGS, YRET_YNARGS, true}},
215 {"wcsrchr", {NRET_YARGS,YRET_NARGS, NRET_NARGS, YRET_YNARGS, true}},
216 {"strchrnul", {NRET_YARGS,YRET_NARGS, NRET_NARGS, YRET_YNARGS, true}},
217 {"wcschrnul", {NRET_YARGS,YRET_NARGS, NRET_NARGS, YRET_YNARGS, true}},
218
219 {"memchr", {NRET_YARGS, YRET_NARGS,NRET_NARGS, YRET_YNARGS, true}},
220 {"wmemchr", {NRET_YARGS, YRET_NARGS,NRET_NARGS, YRET_YNARGS, true}},
221 {"memrchr", {NRET_YARGS,YRET_NARGS, NRET_NARGS, YRET_YNARGS, true}},
222
223 {"memalign", {NRET_NARGS,YRET_NARGS, YRET_NARGS, NRET_NARGS, false}},
224 //{"posix_memalign",{NRET_YARGS, YRET_YNARGS, NRET_NARGS, NRET_NARGS, false}},
225
226 {"perror", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
227
228 {"feof", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
229 {"fflush",{NRET_YARGS, NRET_YARGS, NRET_NARGS, NRET_NARGS, false}},
230 {"fpurge",{NRET_YARGS, NRET_YARGS, NRET_NARGS, NRET_NARGS, false}},
231 {"fclose", {NRET_YARGS, NRET_YARGS,NRET_NARGS, NRET_NARGS, false}},
232 {"fopen", {NRET_YARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
233 {"ftell", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
234 {"fseek", {NRET_YARGS, NRET_YARGS,NRET_NARGS, NRET_NARGS, true}},
235 {"rewind", {NRET_YARGS, NRET_YARGS,NRET_NARGS, NRET_NARGS, true}},
236 {"ferror", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
237 {"fwrite", {NRET_YARGS,NRET_NYARGS,NRET_NARGS, NRET_NARGS, false}},
238 {"fread", {NRET_NYARGS, NRET_YARGS,NRET_NARGS, NRET_NARGS, false}},
239 {"fdopen", {NRET_YARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
240
241 {"__errno_location", {NRET_NARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
242
243 {"puts", {NRET_YARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
244 {"gets", {NRET_NARGS, YRET_YARGS,NRET_NARGS, YRET_YNARGS, false}},
245 {"fgets", {NRET_NYARGS,YRET_YNARGS, NRET_NARGS, YRET_YNARGS, false}},
246 {"getc", {NRET_YNARGS, YRET_YNARGS,NRET_NARGS, NRET_NARGS, false}},
247 {"ungetc", {NRET_YNARGS,YRET_YARGS, NRET_NARGS, NRET_NARGS, false}},
248 {"_IO_getc", {NRET_YNARGS,YRET_YNARGS, NRET_NARGS, NRET_NARGS, false}},
249 {"fgetc", {NRET_YNARGS,YRET_YNARGS, NRET_NARGS, NRET_NARGS, false}},
250 {"putc", {NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
251 {"_IO_putc", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
252 {"putchar", {NRET_NARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
253 {"fputs", {NRET_YARGS, NRET_NYARGS,NRET_NARGS, NRET_NARGS, false}},
254 {"fputc", {NRET_YARGS, NRET_NYARGS,NRET_NARGS, NRET_NARGS, false}},
255
256
257 // SAFECodeIntrinsics
258 {"pool_init_logfile",{NRET_YNARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
259 {"poolcheck", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
260 {"poolcheckui", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
261 {"poolcheckstr", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
262 {"poolcheckstrui", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
263 {"fastlscheck", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
264 {"poolcheckalign", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
265 {"poolcheckalignui", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
266 {"poolcheck_free", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
267 {"poolcheck_freeui", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
268 {"funccheck", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
269 {"funccheckui", {NRET_NARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
270
271 {"poolcheck_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
272 {"poolcheckui_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
273 {"poolcheckstr_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
274 {"poolcheckstrui_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
275 {"fastlscheck_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
276 {"poolcheckalign_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
277 {"poolcheckalignui_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
278 {"poolcheck_free_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
279 {"poolcheck_freeui_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
280 {"funccheck_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
281 {"funccheckui_debug",{NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
282
283 {"pool_register_stack",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
284 {"pool_unregister_stack",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
285 {"pool_register_global",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
286 {"pool_unregister_global",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
287 {"pool_register", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
288 {"pool_unregister", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
289 {"pool_argvregister", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
290
291 {"pool_register_stack_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
292 {"pool_unregister_stack_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
293 {"pool_register_global_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
294 {"pool_unregister_global_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
295 {"pool_register_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
296 {"pool_unregister_debug",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
297
298 // CIF Intrinsics
299 {"__if_pool_get_label",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
300 {"__if_pool_set_label",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
301 // CStdLibRuntime Wrapper Functions
302 {"pool_strncpy", {NRET_NNYARGS,YRET_NNYARGS, NRET_NARGS, YRET_NNYARGS, true}},
303 {"pool_strcpy", {NRET_NNYARGS, YRET_NNYARGS,NRET_NARGS, YRET_NNYARGS, true}},
304 {"pool_stpcpy", {NRET_NNYARGS,YRET_NNYARGS, NRET_NARGS, YRET_NNYARGS, true}},
305 // strchr andindex have same functionality
306 {"pool_strchr", {NRET_NYARGS,YRET_NARGS, NRET_NARGS, YRET_NYARGS, true}},
307 {"pool_index", {NRET_NYARGS,YRET_NARGS, NRET_NARGS, YRET_NYARGS, true}},
308 // strrchr andrindex have same functionality
309 {"pool_strrchr", {NRET_NYARGS,YRET_NARGS, NRET_NARGS, YRET_NYARGS, true}},
310 {"pool_rindex", {NRET_NYARGS, YRET_NARGS,NRET_NARGS, YRET_NYARGS, true}},
311 {"pool_strcat", {NRET_NNYARGS,YRET_NNYARGS, NRET_NARGS, YRET_NNYARGS, true}},
312 {"pool_strncat", {NRET_NNYARGS,YRET_NNYARGS, NRET_NARGS, YRET_NNYARGS, true}},
313 {"pool_strstr", {NRET_NNYARGS, YRET_NARGS,NRET_NARGS, YRET_NNYNARGS, true}},
314 {"pool_strcasestr", {NRET_NNYARGS,YRET_NARGS, NRET_NARGS, YRET_NNYNARGS, true}},
315 {"pool_strpbrk", {NRET_NNYARGS,YRET_NARGS, NRET_NARGS, YRET_NNYNARGS, true}},
316 {"pool_strspn", {NRET_NYARGS, YRET_NARGS,NRET_NARGS, NRET_NARGS, true}},
317 {"pool_strcspn", {NRET_NYARGS,YRET_NARGS, NRET_NARGS, NRET_NARGS, true}},
318 {"pool_memccpy", {NRET_NNYARGS,YRET_NNYARGS, NRET_NARGS, YRET_NNYARGS, true}},
319 {"pool_memchr", {NRET_NYARGS,YRET_NARGS, NRET_NARGS, YRET_NYARGS, true}},
320 {"pool_strcmp", {NRET_NNYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
321 {"pool_strncmp", {NRET_NNYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
322 {"pool_strlen", {NRET_NYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
323 {"pool_strnlen", {NRET_NYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
324 {"pool_memcmp", {NRET_NNYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
325 {"pool_strcasecmp", {NRET_NNYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
326 {"pool_strncasecmp", {NRET_NNYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
327 {"pool_bcopy", {NRET_NNYARGS,NRET_NNNYARGS, NRET_NARGS, NRET_NNYARGS, true}},
328 {"pool_bcmp", {NRET_NNYARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
329 {"pool_read", {NRET_NARGS,NRET_YARGS, NRET_NARGS, NRET_NARGS, false}},
330 {"pool_recv", {NRET_NARGS, NRET_YARGS,NRET_NARGS, NRET_NARGS, false}},
331 {"pool_write", {NRET_YARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
332 {"pool_send", {NRET_YARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
333 {"pool_readlink", {NRET_YNARGS,NRET_NYARGS, NRET_NARGS, NRET_NARGS, true}},
334 {"pool_realpath", {NRET_YNARGS,NRET_NYARGS, NRET_NARGS, NRET_NARGS, true}},
335 {"pool_getcwd", {NRET_YARGS,NRET_NYARGS, NRET_NARGS, YRET_NYARGS, false}},
336
337 // format stringintrinsics and functions
338 {"sc.fsparameter", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
339 {"sc.fscallinfo", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
340 {"sc.fscallinfo_debug", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
341 {"pool_printf", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
342 {"pool_fprintf", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
343 {"pool_sprintf", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
344 {"pool_snprintf", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
345 {"pool_err", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
346 {"pool_errx", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
347 {"pool_warn", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
348 {"pool_warnx", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
349 {"pool_syslog", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
350 {"pool_scanf", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
351 {"pool_fscanf", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
352 {"pool_sscanf", {NRET_NARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
353 {"pool___printf_chk", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
354 {"pool___fprintf_chk", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
355 {"pool___sprintf_chk", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
356 {"pool___snprintf_chk",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
357
358 // Important CI/O functions
359 {"pool_fgets", {NRET_NNYARGS,YRET_YNYARGS, NRET_NARGS,YRET_YNARGS, true}},
360 {"pool_fgets_debug",{NRET_NNYARGS,YRET_YNYARGS, NRET_NARGS, YRET_YNARGS,true}},
361
362 // Type Checks
363 {"trackArgvType", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
364 {"trackEnvpType", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
365 {"trackGlobal", {NRET_NARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
366 {"trackArray", {NRET_NARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
367 {"trackStoreInst", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
368 {"trackStringInput", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
369 {"compareTypeAndNumber", NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
370 {"compareVAArgType", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
371 {"getTypeTag", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
372 {"checkType", {NRET_NARGS, NRET_NARGS,NRET_NARGS, NRET_NARGS, false}},
373 {"trackInitInst", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
374 {"trackUnInitInst", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
375 {"copyTypeInfo", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
376 {"setTypeInfo", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
377 {"setVAInfo", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
378 {"copyVAInfo", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
379 {"trackctype", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
380 {"trackctype_32", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
381 {"trackStrcpyInst", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
382 {"trackStrcnpyInst", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
383 {"trackStrcatInst", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
384 {"trackgetcwd", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
385 {"trackgetpwuid", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
386 {"trackgethostname", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
387 {"trackgethostbyname", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
388 {"trackgetservbyname", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
389 {"trackgetaddrinfo", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
390 {"trackgetsockname", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
391 {"trackaccept", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
392 {"trackpoll", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
393 {"trackpipe", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
394 {"trackReadLink", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
395
396 #if 0
397 {"wait", {false, false, false, false, true, false, false, false, false}},
398 #endif
399
400 // C++ functions,as mangled on linux gcc 4.2
401 // operatornew(unsigned long)
402 {"_Znwm", {NRET_NARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
403 // operatornew[](unsigned long)
404 {"_Znam", {NRET_NARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
405 // operatornew(unsigned int)
406 {"_Znwj", {NRET_NARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
407 // operatornew[](unsigned int)
408 {"_Znaj", {NRET_NARGS, YRET_NARGS,YRET_NARGS, NRET_NARGS, false}},
409 // operatordelete(void*)
410 {"_ZdlPv", {NRET_NARGS, NRET_NARGS,NRET_YNARGS, RET_NARGS, false}},
411 // operator delete[](void*)
412 {"_ZdaPv", {NRET_NARGS, NRET_NARGS,NRET_YNARGS, NRET_NARGS, false}},
413 // flush
414 {"_ZNSo5flushEv", {NRET_NARGS,NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
415 // <<operator
416 {"_ZNSolsEd", {NRET_YARGS,NRET_YNARGS, NRET_NARGS, NRET_NARGS, false}},
417 // <<operator
418 {"_ZNSolsEPFRSoS_E", {NRET_YARGS, NRET_YNARGS,NRET_NARGS, NRET_NARGS, false}},
419 //endl
420 {"_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_",{NRET_NARGS, NRET_NARGS, NRET_NARGS, NRET_NARGS, false}},
421 // Added byJingyue
422 {"strtoll", {NRET_YARGS,NRET_NYARGS, NRET_NYARGS, NRET_YARGS, false}},
423 // Terminate thelist of special functions recognized by this pass
424 {0, {NRET_NARGS, NRET_NARGS, NRET_NARGS,NRET_NARGS, false}},
425 };
426
427 /*
428 Functions to add
429 freopen
430 strftime
431 strtoul
432 strtol
433 strtoll
434 ctype family
435 setbuf
436 setvbuf
437 __strpbrk_c3
438 open64/fopen64/lseek64
439 */
这是一个很大的数组,几乎把所有的C库函数都一网打尽了,428~439行还列出了遗留的函数。在这个结构体中类型libAction的定义是:
60 struct libAction {
61 // The return value/argumentsthat should be marked read.
62 bool read[numOps];
63
64 // The returnvalue/arguments that should be marked modified.
65 bool write[numOps];
66
67 // The returnvalue/arguments that should be marked as heap.
68 bool heap[numOps];
69
70 // Flags whether the return value should bemerged with all arguments.
71 bool mergeNodes[numOps];
72
73 // Flags whetherthe return value and arguments should be folded.
74 bool collapse;
75 };
其中numOps被定义为10。为了初始化libAction,还定义了若干宏:
77 #define NRET_NARGS {0,0,0,0,0,0,0,0,0,0}
78 #define YRET_NARGS {1,0,0,0,0,0,0,0,0,0}
79 #define NRET_YARGS {0,1,1,1,1,1,1,1,1,1}
80 #define YRET_YARGS {1,1,1,1,1,1,1,1,1,1}
81 #define NRET_NYARGS {0,0,1,1,1,1,1,1,1,1}
82 #define YRET_NYARGS {1,0,1,1,1,1,1,1,1,1}
83 #define NRET_YNARGS {0,1,0,0,0,0,0,0,0,0}
84 #define YRET_YNARGS {1,1,0,0,0,0,0,0,0,0}
85 #define YRET_NNYARGS {1,0,0,1,1,1,1,1,1,1}
86 #define YRET_YNYARGS {1,1,0,1,1,1,1,1,1,1}
87 #define NRET_NNYARGS {0,0,0,1,1,1,1,1,1,1}
88 #define YRET_NNYNARGS{1,0,0,1,0,0,0,0,0,0}
89 #define NRET_NNNYARGS{0,0,0,0,1,1,1,1,1,1}
这些宏的名字泄露了其内容,在10个元素中第一个对应返回值,其他对应函数参数,因此宏都以[N\Y]RET开头,N是0,Y是1;参数则这样命名,NARGS表示9个都是0,NYARGS表示第一个参数是0,其他都是1,以此类推。
在调用processFunction时,参数x是参数F在recFuncs中的索引。
679 void StdLibDataStructures::processFunction(intx, Function *F) {
680 for(Value::use_iterator ii = F->use_begin(), ee = F->use_end();
681 ii != ee; ++ii)
682 if (CallInst* CI =dyn_cast<CallInst>(*ii)){
683 if (CI->getCalledValue() == F) {
684 DSGraph* Graph =getDSGraph(*CI->getParent()->getParent());
685
686 //
687 // Set theread, write, and heap markers on the return value
688 // asappropriate.
689 //
690 if(isa<PointerType>((CI)->getType())){
691 if(Graph->hasNodeForValue(CI)){
692 if (recFuncs[x].action.read[0])
693 Graph->getNodeForValue(CI).getNode()->setReadMarker();
694 if (recFuncs[x].action.write[0])
695 Graph->getNodeForValue(CI).getNode()->setModifiedMarker();
696 if (recFuncs[x].action.heap[0])
697 Graph->getNodeForValue(CI).getNode()->setHeapMarker();
698 }
699 }
700
701 //
702 // Set theread, write, and heap markers on the actual arguments
703 // asappropriate.
704 //
705 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y)
706 if(isa<PointerType>(CI->getArgOperand(y)->getType())){
707 if(Graph->hasNodeForValue(CI->getArgOperand(y))){
708 if (recFuncs[x].action.read[y +1])
709 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker();
710 if (recFuncs[x].action.write[y +1])
711 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker();
712 if (recFuncs[x].action.heap[y +1])
713 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setHeapMarker();
714 }
715 }
716
717 //
718 // Mergethe DSNoes for return values and parameters as
719 // appropriate.
720 //
721 std::vector<DSNodeHandle>toMerge;
722 if (recFuncs[x].action.mergeNodes[0])
723 if(isa<PointerType>(CI->getType()))
724 if (Graph->hasNodeForValue(CI))
725 toMerge.push_back(Graph->getNodeForValue(CI));
726 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y)
727 if (recFuncs[x].action.mergeNodes[y +1])
728 if(isa<PointerType>(CI->getArgOperand(y)->getType()))
729 if (Graph->hasNodeForValue(CI->getArgOperand(y)))
730 toMerge.push_back(Graph->getNodeForValue(CI->getArgOperand(y)));
731 for(unsigned y = 1; y < toMerge.size(); ++y)
732 toMerge[0].mergeWith(toMerge[y]);
733
734 //
735 // Collapse(fold) the DSNode of the return value and the actual
736 //arguments if directed to do so.
737 //
738 if (!noStdLibFold &&recFuncs[x].action.collapse) {
739 if(isa<PointerType>(CI->getType())){
740 if (Graph->hasNodeForValue(CI))
741 Graph->getNodeForValue(CI).getNode()->foldNodeCompletely();
742 NumNodesFoldedInStdLib++;
743 }
744 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y){
745 if(isa<PointerType>(CI->getArgOperand(y)->getType())){
746 if(Graph->hasNodeForValue(CI->getArgOperand(y))){
747 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->foldNodeCompletely();
748 NumNodesFoldedInStdLib++;
749 }
750 }
751 }
752 }
753 }
754 } else if (InvokeInst* CI =dyn_cast<InvokeInst>(*ii)){
755 if (CI->getCalledValue() == F) {
756 DSGraph* Graph =getDSGraph(*CI->getParent()->getParent());
757
758 //
759 // Set theread, write, and heap markers on the return value
760 // asappropriate.
761 //
762 if(isa<PointerType>((CI)->getType())){
763 if(Graph->hasNodeForValue(CI)){
764 if (recFuncs[x].action.read[0])
765 Graph->getNodeForValue(CI).getNode()->setReadMarker();
766 if (recFuncs[x].action.write[0])
767 Graph->getNodeForValue(CI).getNode()->setModifiedMarker();
768 if (recFuncs[x].action.heap[0])
769 Graph->getNodeForValue(CI).getNode()->setHeapMarker();
770 }
771 }
772
773 //
774 // Set theread, write, and heap markers on the actual arguments
775 // asappropriate.
776 //
777 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y)
778 if(isa<PointerType>(CI->getArgOperand(y)->getType())){
779 if (Graph->hasNodeForValue(CI->getArgOperand(y))){
780 if (recFuncs[x].action.read[y +1])
781 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker();
782 if (recFuncs[x].action.write[y +1])
783 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker();
784 if (recFuncs[x].action.heap[y +1])
785 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setHeapMarker();
786 }
787 }
788
789 //
790 // Mergethe DSNoes for return values and parameters as
791 //appropriate.
792 //
793 std::vector<DSNodeHandle>toMerge;
794 if (recFuncs[x].action.mergeNodes[0])
795 if (isa<PointerType>(CI->getType()))
796 if (Graph->hasNodeForValue(CI))
797 toMerge.push_back(Graph->getNodeForValue(CI));
798 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y)
799 if (recFuncs[x].action.mergeNodes[y +1])
800 if(isa<PointerType>(CI->getArgOperand(y)->getType()))
801 if(Graph->hasNodeForValue(CI->getArgOperand(y)))
802 toMerge.push_back(Graph->getNodeForValue(CI->getArgOperand(y)));
803 for(unsigned y = 1; y < toMerge.size(); ++y)
804 toMerge[0].mergeWith(toMerge[y]);
805
806 //
807 // Collapse(fold) the DSNode of the return value and the actual
808 //arguments if directed to do so.
809 //
810 if (!noStdLibFold &&recFuncs[x].action.collapse) {
811 if(isa<PointerType>(CI->getType())){
812 if (Graph->hasNodeForValue(CI))
813 Graph->getNodeForValue(CI).getNode()->foldNodeCompletely();
814 NumNodesFoldedInStdLib++;
815 }
816 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y){
817 if(isa<PointerType>(CI->getArgOperand(y)->getType())){
818 if(Graph->hasNodeForValue(CI->getArgOperand(y))){
819 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->foldNodeCompletely();
820 NumNodesFoldedInStdLib++;
821 }
822 }
823 }
824 }
825 }
826 } else if(ConstantExpr *CE =dyn_cast<ConstantExpr>(*ii)) {
827 if(CE->isCast())
828 for(Value::use_iterator ci = CE->use_begin(), ce = CE->use_end();
829 ci != ce; ++ci) {
830
831 if (CallInst* CI =dyn_cast<CallInst>(*ci)){
832 if (CI->getCalledValue() == CE){
833 DSGraph* Graph =getDSGraph(*CI->getParent()->getParent());
834
835 //
836 //Set the read, write, and heap markers on the return value
837 // as appropriate.
838 //
839 if(isa<PointerType>((CI)->getType())){
840 if(Graph->hasNodeForValue(CI)){
841 if(recFuncs[x].action.read[0])
842 Graph->getNodeForValue(CI).getNode()->setReadMarker();
843 if(recFuncs[x].action.write[0])
844 Graph->getNodeForValue(CI).getNode()->setModifiedMarker();
845 if(recFuncs[x].action.heap[0])
846 Graph->getNodeForValue(CI).getNode()->setHeapMarker();
847 }
848 }
849
850 //
851 //Set the read, write, and heap markers on the actual arguments
852 // asappropriate.
853 //
854 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y)
855 if (recFuncs[x].action.read[y +1]){
856 if(isa<PointerType>(CI->getArgOperand(y)->getType())){
857 if(Graph->hasNodeForValue(CI->getArgOperand(y)))
858 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker();
859 if(Graph->hasNodeForValue(CI->getArgOperand(y)))
860 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker();
861 if(Graph->hasNodeForValue(CI->getArgOperand(y)))
862 Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setHeapMarker();
863 }
864 }
865
866 //
867 //Merge the DSNoes for return values and parameters as
868 //appropriate.
869 //
870 std::vector<DSNodeHandle>toMerge;
871 if (recFuncs[x].action.mergeNodes[0])
872 if(isa<PointerType>(CI->getType()))
873 if(Graph->hasNodeForValue(CI))
874 toMerge.push_back(Graph->getNodeForValue(CI));
875 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y)
876 if(recFuncs[x].action.mergeNodes[y + 1])
877 if(isa<PointerType>(CI->getArgOperand(y)->getType()))
878 if(Graph->hasNodeForValue(CI->getArgOperand(y)))
879 toMerge.push_back(Graph->getNodeForValue(CI->getArgOperand(y)));
880 for(unsigned y = 1; y < toMerge.size(); ++y)
881 toMerge[0].mergeWith(toMerge[y]);
882
883 //
884 //Collapse (fold) the DSNode of the return value and the actual
885 //arguments if directed to do so.
886 //
887 if (!noStdLibFold &&recFuncs[x].action.collapse) {
888 if (isa<PointerType>(CI->getType())){
889 if(Graph->hasNodeForValue(CI))
890 Graph->getNodeForValue(CI).getNode()->foldNodeCompletely();
891 NumNodesFoldedInStdLib++;
892 }
893 for(unsigned y = 0; y < CI->getNumArgOperands(); ++y)
894 if(isa<PointerType>(CI->getArgOperand(y)->getType())){
895 if(Graph->hasNodeForValue(CI->getArgOperand(y))){
896 DSNode * Node=Graph->getNodeForValue(CI->getArgOperand(y)).getNode();
897 Node->foldNodeCompletely();
898 NumNodesFoldedInStdLib++;
899 }
900 }
901 }
902 }
903 }
904 }
905 }
906
907 //
908 // Pretend thatthis call site does not call this function anymore.
909 //
910 eraseCallsTo(F);
911 }
虽然很长,但StdLibDataStructures::processFunction并不复杂,recFuncs已经告诉它函数调用时的返回值及各个参数该如何设置,照方抓药就是了。
SAFECode是一个使用LLVM及Clang构建的内存安全编译器。内存安全编译器在编译期向程序插入运行时检查来捕捉运行时内存安全错误。这些错误包括缓存越界,无效删除,解引用悬空指针。SAFECode是依赖于poolalloc的J。
StdLibDataStructures::runOnModule(续)
626 // Merge returnvalues and checked pointer values for SAFECode run-time
627 // checks.
628 //
629 processRuntimeCheck (M,"boundscheck", 2);
630 processRuntimeCheck (M,"boundscheckui", 2);
631 processRuntimeCheck (M,"exactcheck2", 1);
632
633 processRuntimeCheck (M,"boundscheck_debug", 2);
634 processRuntimeCheck (M,"boundscheckui_debug", 2);
635 processRuntimeCheck (M,"exactcheck2_debug", 1);
636
637 processRuntimeCheck (M,"pchk_getActualValue", 1);
638 }
上面针对SAFECode的函数调用StdLibDataStructures::processRuntimeCheck。这个函数定义如下,其参数已经指出了处理的方向,即考虑函数的第几个参数。
507 void
508 StdLibDataStructures::processRuntimeCheck (Module & M,
509 std::string name,
510 unsigned arg) {
511 //
512 // Get a pointerto the function.
513 //
514 Function* F = M.getFunction (name);
515
516 //
517 // If thefunction doesn't exist, then there is no work to do.
518 //
519 if (!F) return;
520
521 //
522 // Scan throughall direct calls to the function (there should only be direct
523 // calls) andprocess each one.
524 //
525 for(Value::use_iterator ii = F->use_begin(), ee = F->use_end();
526 ii != ee; ++ii) {
527 if (CallInst* CI =dyn_cast<CallInst>(*ii)) {
528 if (CI->getCalledValue() == F) {
529 DSGraph* Graph =getDSGraph(*CI->getParent()->getParent());
530 DSNodeHandle & RetNode =Graph->getNodeForValue(CI);
531 DSNodeHandle & ArgNode = Graph->getNodeForValue(CI->getArgOperand(arg));
532 RetNode.mergeWith(ArgNode);
533 }
534 }
535 }
536
537 //
538 // Erase theDSCallSites for this function. Thisshould prevent other DSA
539 // passes frommaking the DSNodes passed to/returned from the function
540 // from becomingIncomplete or External.
541 //
542 eraseCallsTo(F);
543 return;
544 }
这个函数把name指定的函数调用的返回值与指定的实参简并起来。并最后在函数图中删除这些调用的记录。
因为在前面LocalDataStructures的处理中,传递给C库函数以及从C库函数返回的节点,我们都标记成了外部的(因为C库函数只是看到声明)(参考1.3.3.4.1.4.外部标记一节)。但现在我们已经(保守地)为它们创建了DSGraph对象,传递给C库函数以及从C库函数返回的节点不再需要标记为外部。
StdLibDataStructures::runOnModule(续)
640 //
641 // In the LocalDSA Pass, we marked nodes passed to/returned from 'StdLib'
642 // functions asExternal because, at that point, they were. However, they no
643 // longer arenecessarily External, and we need to update accordingly.
644 //
645 GlobalsGraph->maskIncompleteMarkers();
646
647 GlobalsGraph->computeExternalFlags(DSGraph::ResetExternal);
648 for(Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
649 if (!I->isDeclaration()) {
650 DSGraph * G = getDSGraph(*I);
651 unsigned EFlags = 0
652 | DSGraph::ResetExternal
653 | DSGraph::DontMarkFormalsExternal
654 | DSGraph::ProcessCallSites;
655 G->maskIncompleteMarkers();
656 G->markIncompleteNodes(DSGraph::MarkFormalArgs
657 |DSGraph::IgnoreGlobals);
658 G->computeExternalFlags(EFlags);
659 DEBUG(G->AssertGraphOK());
660 }
661 GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs
662 |DSGraph::IgnoreGlobals);
663 GlobalsGraph->computeExternalFlags(DSGraph::ProcessCallSites);
664 DEBUG(GlobalsGraph->AssertGraphOK());
665 for(Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
666 if (!I->isDeclaration()) {
667 DSGraph *Graph = getOrCreateGraph(I);
668 Graph->maskIncompleteMarkers();
669 cloneGlobalsInto(Graph,DSGraph::DontCloneCallNodes |
670 DSGraph::DontCloneAuxCallNodes);
671 Graph->markIncompleteNodes(DSGraph::MarkFormalArgs
672 |DSGraph::IgnoreGlobals);
673 }
674
675 return false;
676 }
因为在前面我们已经从相应的DSGraph中的FunctionCalls以及AuxFunctionCalls里删除了对C库函数的调用指令,上面的处理,会把涉及到这些C库函数的节点的外部标记取消。至此,我们完成了需要的处理。