1. A computer-implemented method of verifying software, the method comprising: receiving a portion of a software program that includes a plurality of functions; clustering the functions into two or more first clusters of functions; generating a symbolic driver for each of the first clusters of functions such that multiple symbolic drivers are generated; symbolically executing the first clusters of functions using the symbolic drivers to generate concrete test cases for the functions in the first clusters; and in response to coverage of the symbolic execution of the first clusters of functions being less than a particular coverage and a number of the concrete test cases being less than a particular number of concrete test cases, re-clustering the plurality of functions by clustering the plurality of functions into two or more second clusters of functions where the second clusters of functions include more clusters of functions than the first clusters of functions.