android虚拟机文件查看,Android虚拟机art流程:查看JNI_CreateJavaVM 对运行时 oat文件的加载...

我们从

startVm————》JNI_CreateJavaVM---》Runtime::Create---》Runtime::Init

一路走来的,然后我们看下Init 里面如何建立heap和oat文件的加载。

bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {

heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),

.

.

}

这里新建这个heap。 /art/runtime/gc/heap.cc

Heap::Heap(size_t initial_size,

size_t growth_limit,

....

{

uint8_t* const original_requested_alloc_space_begin = requested_alloc_space_begin;

for (size_t index = 0; index < image_file_names.size(); ++index) {

std::string& image_name = image_file_names[index];

std::string error_msg;

space::ImageSpace* boot_image_space = space::ImageSpace::CreateBootImage(

image_name.c_str(),

image_instruction_set,

index > 0,

&error_msg);

if (boot_image_space != nullptr) {

AddSpace(boot_image_space);

...

if (index == 0) {

...

const OatFile* boot_oat_file = boot_image_space->GetOatFile();

if (boot_oat_file == nullptr) {

continue;

}

const OatHeader& boot_oat_header = boot_oat_file->GetOatHeader();

const char* boot_classpath =

boot_oat_header.GetStoreValueByKey(OatHeader::kBootClassPathKey);

if (boot_classpath == nullptr) {

continue;

}

space::ImageSpace::CreateMultiImageLocations(image_file_name,

boot_classpath,

&image_file_names);

}

} else {

....

}

}

}

}

目前我只关注这个

CreateBootImage

ImageSpace* ImageSpace::CreateBootImage(const char* image_location,

const InstructionSet image_isa,

bool secondary_image,

std::string* error_msg) {

ScopedTrace trace(__FUNCTION__);

std::string system_filename;

bool has_system = false;

std::string cache_filename;

bool has_cache = false;

bool dalvik_cache_exists = false;

bool is_global_cache = true;

bool found_image = FindImageFilename(image_location, image_isa, &system_filename,

&has_system, &cache_filename, &dalvik_cache_exists,

&has_cache, &is_global_cache);

先找到 boot.art 文件。怎么找可以看这个函数具体的。

ImageSpace* space;

space = ImageSpace::Init(image_filename->c_str(),

image_location,

!(is_system || relocated_version_used),

/* oat_file */nullptr,

error_msg);

ImageSpace* ImageSpace::Init(const char* image_filename,

const char* image_location,{

ImageHeader temp_image_header;

ImageHeader* image_header = &temp_image_header;

{

TimingLogger::ScopedTiming timing("ReadImageHeader", &logger);

bool success = file->ReadFully(image_header, sizeof(*image_header));

if (!success || !image_header->IsValid()) {

*error_msg = StringPrintf("Invalid image header in '%s'", image_filename);

return nullptr;

}

}

这个Init 里面先拿到这个boot.art文件的头。里面标记了oat的起止地址和oatdata段和oatexe。就是数据段的执行代码的位置。

std::unique_ptr space(new ImageSpace(image_filename,

image_location,

map.release(),

bitmap.release(),

image_end));

if (oat_file == nullptr) {

TimingLogger::ScopedTiming timing("OpenOatFile", &logger);

space->oat_file_.reset(space->OpenOatFile(image_filename, error_msg));

然后 新建一个ImageSpace 然后 OpenOatFile。

OatFile* ImageSpace::OpenOatFile(const char* image_path, std::string* error_msg) const {

const ImageHeader& image_header = GetImageHeader();

std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(image_path);

CHECK(image_header.GetOatDataBegin() != nullptr);

OatFile* oat_file = OatFile::Open(oat_filename,

oat_filename,

image_header.GetOatDataBegin(),

image_header.GetOatFileBegin(),

....

error_msg);

...

...

return oat_file;

}

这里就会用到我们刚才的image_header的信息。

OatFile* OatFile::Open(const std::string& filename,

const std::string& location,

uint8_t* requested_base,

uint8_t* oat_file_begin,

bool executable,

bool low_4gb,

const char* abs_dex_location,

std::string* error_msg) {

...

OatFile* with_dlopen = OatFileBase::OpenOatFile(filename,

location,

requested_base,

oat_file_begin,

.....

if (with_dlopen != nullptr) {

return with_dlopen;

}

这里的OpenOatFile 是个模版,有点绕。

template

OatFileBase* OatFileBase::OpenOatFile(const std::string& elf_filename,

const std::string& location,

uint8_t* requested_base,

uint8_t* oat_file_begin,

bool writable,

bool executable,

bool low_4gb,

const char* abs_dex_location,

std::string* error_msg) {

std::unique_ptr ret(new kOatFileBaseSubType(location, executable));

if (!ret->Load(elf_filename,

oat_file_begin,

writable,

executable,

low_4gb,

error_msg)) {

return nullptr;

}

return ret.release();

}

bool DlOpenOatFile::Load(const std::string& elf_filename,

uint8_t* oat_file_begin,

....

bool success = Dlopen(elf_filename, oat_file_begin, error_msg);

DCHECK(dlopen_handle_ != nullptr || !success);

return success;

}

bool DlOpenOatFile::Dlopen(const std::string& elf_filename,

uint8_t* oat_file_begin,}

if (oat_file_begin != nullptr) { //

extinfo.flags |= ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS; // Use the requested addr if

extinfo.reserved_addr = oat_file_begin; // vaddr = 0.

} // (pic boot image).

dlopen_handle_ = android_dlopen_ext(absolute_path.get(), RTLD_NOW, &extinfo);

}

最终它加载的位置在oatdatabegin的位置。 整个就加载完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值