入门ART虚拟机(4)——加载类和方法续

Android安全交流群:478084054

接上篇笔记。

入门ART虚拟机(4)——加载类和方法续_第1张图片

在ClassLinker的LoadClass方法中,先调用DexFile的GetClassData方法从对应的DEX文件中得到class数据。

入门ART虚拟机(4)——加载类和方法续_第2张图片

然后不管是否具有对应的oat_class,都是调用LoadClassMembers加载类的成员。前面笔记中做过一种假设,就是DEX加固壳阻止了指定DEX生成OAT文件的过程,这种情况下传给LoadClassMembers方法的oat_class参数为nullptr。

入门ART虚拟机(4)——加载类和方法续_第3张图片

LoadClassMembers方法的前半部分用于加载class的静态域和实例域,主要看后面加载方法的部分。

入门ART虚拟机(4)——加载类和方法续_第4张图片

先加载direct方法,再加载virtual方法。先调用LoadMethod方法初始化ArtMethod对象。

入门ART虚拟机(4)——加载类和方法续_第5张图片

回到LoadClassMembers,再继续调用LinkCode链接类方法。先来看LinkCode的前半部分。

入门ART虚拟机(4)——加载类和方法续_第6张图片

如果oat_class不为空,则调用其GetOatMethod方法得到相应的oat_method,再调用LinkMethod方法对method进行设置。

实际上就是设置ArtMethod对象的entry_point_from_quick_compiled_code_成员,作为编译代码入口点。

继续看LinkCode,调用NeedsInterpreter,看看是否需要解释执行。

入门ART虚拟机(4)——加载类和方法续_第7张图片

第2个参数quick_code传入的是method->GetEntryPointFromQuickCompiledCode(),也就是LinkMethod里面设置的entry_point_from_quick_compiled_code_。如果前面oat_class为空,没有设置entry_point_from_quick_compiled_code_,那我觉得NeedsInterpreter传入的参数quick_code应该为空,不管ART是否运行在解释模式中,NeedsInterpreter都会返回true。

之所以说这些,是因为我发现有些DEX壳代码,在运行时想方设法的强制将ART设置为interpret-only,但单从加载类方法这块代码来看,如果壳代码之前阻止了指定DEX生成OAT的过程,这块在找不到方法对应的机器代码入口点的情况下,即使不设置interpret-only,也会以解释运行的方式设置各个Entry Point。(我对ART的了解还太少,后面随着学习的不断深入,再回过头来想想这个问题)

贴出LinkCode的后半部分代码。

入门ART虚拟机(4)——加载类和方法续_第8张图片

主要就是根据各种情况,设置method的解释执行入口点,或者执行编译代码的入口点。

你可能感兴趣的:(入门ART虚拟机(4)——加载类和方法续)