Android(安卓)ART运行环境下Image文件格式简析
可以通过阅读代码来帮助分析Image文件的格式。
首先,在art\runtime\Image.h文件中,有相关的定义:
byte magic_[4];byte version_[4];// Required base address for mapping the image.uint32_t image_begin_;// Image size, not page aligned.uint32_t image_size_;// Image bitmap offset in the file.uint32_t image_bitmap_offset_;// Size of the image bitmap.uint32_t image_bitmap_size_;// Checksum of the oat file we link to for load time sanity check.uint32_t oat_checksum_;// Start address for oat file. Will be before oat_data_begin_ for .so files.uint32_t oat_file_begin_;// Required oat address expected by image Method::GetCode() pointers.uint32_t oat_data_begin_;// End of oat data address range for this image file.uint32_t oat_data_end_;// End of oat file address range. will be after oat_data_end_ for// .so files. Used for positioning a following alloc spaces.uint32_t oat_file_end_;// Absolute address of an Object[] of objects needed to reinitialize from an image.uint32_t image_roots_;
下面一一说明:
1) 最先的4个字节是Image文件的magic code,其值在对应的art\runtime\Image.cc文件中有定义:
const byte ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
2) 接下来的4个字节是Image文件的版本号,同样在Image.cc文件中有指定:
const byte ImageHeader::kImageVersion[] = { '0', '0', '5', '\0' };3) 再下来的4个字节指定了Image文件映射到内存中的起始地址;
4) 再下来的4个字节说明了Image文件的大小,这是没有根据页4K对齐后的大小;
5) 再下来的8个字节用来指定Image的bitmap,先4个字节说明bitmap相对文件头所在内存地址的偏移,后4个地址说明bitmap的具体大小,至于bitmap的具体作用,以后再说;
6) 再下来的4个字节指定了所要链接的oat文件的checksum,方便以后在运行时检查;
7) 再下来的4个字节是Boot Oat文件在内存中的起始地址,该地址同时也在包含Oat的Elf文件中指定,从而保证在dlopen后加载到这个特定的地址;
8) 再下来的4个字节是Boot Oat文件中数据段的起始地址,该地址和Boot Oat文件中符号oatdata指定的地址一样;
9) 再下来的4个字节是Boot Oat文件中数据段的结束地址,该值等于Boot Oat文件中符号oatlastword+4;
10)再下来的4个字节是Boot Oat文件在内存中的结束地址,该值可以定位用于动态内存分配的内存段;
11)最后的4个字节很关键,它是一个地址,指向了一个ObjectArray,里面包含了非常重要的对象。具体来说,一共有7个:
enum ImageRoot { kResolutionMethod, kCalleeSaveMethod, kRefsOnlySaveMethod, kRefsAndArgsSaveMethod, kOatLocation, kDexCaches, kClassRoots, kImageRootsMax,};就先说这么多,具体每个的作用稍后再分析。
目前为止,罗列了那么多概念,估计大家头也晕了,下面举个例子吧。笔者有一台Google Nexus 7二代设备,打开开发者选项,切换到ART运行环境,并且root过后,可以把Image文件(system@framework@boot.art)和Boot Oat文件(system@framework@boot.oat)拿出来。首先,用二进制编辑工具打开.art文件,一探究竟:
所以.art文件实际就是由Image加上其Bitmap组成。好,我们继续,接下来的0xE566C279是要加载的oat文件的checksum,.oat文件的起始地址是0x60A9C000,结束地址是0x64618000,.oat文件的数据段起始地址是0x60A9D000,结束地址是0x646161A8。所有这些绝对地址在.oat文件中也有记录,让我们用readelf打开.oat文件看看,Program Headers如下:
可以看到,映射到的物理地址强制写到0x60A9C000。再看看oatdata和oatlastword:
可以看到,.oat文件中记录的这些值和.art文件中所记录的是一致的。最后的4个字节为0x60A9BCC0,让我们移步到这个地址,看看有些什么东西:
这块应该就是一个ObjectArray,里面记录了7个Object,可以很轻易的看到,其中记录了oat文件的位置(kOatLocation,第5个对象)。
更多相关文章
- Coco2d-x从Win32移植到Android
- Android(安卓)Studio 编译不通过,报错“找不到org.apache.http。
- android技术选型(持续更新中...)
- Android项目build.gradle多渠道&完整版
- Android(安卓)自定义CheckBox样式
- Android(安卓)不使用布局文件,动态地生产布局显示
- Android(安卓)Studio技巧 之 自动命名APK文件
- Android下载文件提示文件不存在。。。 java.io.FileNotFoundExce
- Android中String.xml: The reference to entity "timestamp" mus