GitHub - openscenegraph/OpenSceneGraph at OpenSceneGraph-3.6.5
上一篇博客中已经把基础的WALA切片方法讲述,本篇博客将基于上一篇做进一步的讲解。
上一篇中提到,使用util类构建call graph,util类下不同函数构建call graph的精确度不同,导致构建call graph时间不同,按精确度来说是N<zero<zeroone<zeroonecontainer,构建时间则按相反顺序(使用不同的函数构建call graph也会影响切片结果)。
构建SDG图时(这里控制流和数据流值的选择会影响之后切片结果的精细度),可用的数据流项:
FULL:跟踪所有的数据依赖
NO_BASE_PTRS:与FULL类似,但忽略定义用于间接内存访问的基本指针的数据依赖边
NO_BASE_NO_HEAP:与NO_BASE_PTS类似,并且另外忽略所有与堆位置有关的数据依赖边
NO_HEAP:像FULL一样,另外忽略所有的数据依赖边缘到堆的位置
NONE:忽略所有的数据依赖
REFLECTION :与NO_BASE_NO_HEAP一样,但也忽略源自checkcast语句的数据依赖边缘。 这是依赖算法,用于从newInstance强制转换为强制转换。
可用的控制流项:
FULL:跟踪全部控制流依赖
NONE:忽略所有控制流依赖
NO_EXCEPTIONAL_EDGES:忽略异常处理的依赖关系
NO_INTERPROC_EDGES:忽略所有跨程序的依赖边,只分析程序内
NO_INTERPROC_NO_EXCEPTION:NO_EXCEPTIONAL_EDGES和NO_INTERPROC_EDGES综合
根据自己的需求选择相应的值即可。
下面讲解如何处理WALA切片得到的结果。
上一篇提到切片结果是Collection<Statement>,collection中每一个Statement可以获得对应的node,method,class,以及当前statement对应再源码中的位置,二进制指令的位置等信息。
对每个Statement s,获得cg图中node:
Node node = s.getNode();
对应的method:
IMethod method= node.getMethod();
对应的class:
IClass klass = s.getNode().getMethod().getDeclaringClass();
获得s的在代码中的行数:
首先需要将获得method从IMethod类型转换为ShrikeBTMethod(这个类主要处理二进制指令)
ShrikeBTMethod temp = (ShrikeBTMethod) ((NormalStatement) s).getNode().getMethod();
然后,声明一个变量用来存储s的所在的ShrikeBTMethod中指令位置(ShrikeBTMethod中的指令跟字节码指令略有不同,具体参考ShrikeBTMethod相关文档和源码即可)
int instructionIndex = ((NormalStatement) s).getInstructionIndex();
获取字节码中指令所在行号
int bcIndex = 0;
bcIndex = temp.getBytecodeIndex(instructionIndex);
最后,直接调用getLineNumber函数即可获得当前statement s所在源文件行数
int lineNumber = temp.getLineNumber(bcIndex);
还有另外一种方式,可以参考wala的例子。
http://wala.sourceforge.net/wiki/index.php/UserGuide:MappingToSourceCode#From_Slices_to_source_line_numbers