dsa算法(21)

1.3.7.4. 处理调用库函数的DSGraph对象

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已经告诉它函数调用时的返回值及各个参数该如何设置,照方抓药就是了。

1.3.7.5. 处理SAFECode函数

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指定的函数调用的返回值与指定的实参简并起来。并最后在函数图中删除这些调用的记录。

1.3.7.5. 更新相关节点

因为在前面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库函数的节点的外部标记取消。至此,我们完成了需要的处理。

你可能感兴趣的:(算法,DSA,compiler,编译器,llvm)