Add oatdump support for app images
Example usage on host:
oatdumpd --app-oat=art/plus32.odex --app-image=art/plus32.art
--image=art/oats/system@framework@boot.art --instruction-set=arm
TODO: Add to oatdump test.
Bug: 27408512
Bug: 22858531
(cherry picked from commit bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0)
Change-Id: I9d1aa7eaa16795e5fbabc6974d245849e16b1d03
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 7155c79..033ea56 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -89,6 +89,7 @@
uint8_t* oat_file_begin,
bool writable,
bool executable,
+ bool low_4gb,
const char* abs_dex_location,
std::string* error_msg);
@@ -102,6 +103,7 @@
uint8_t* oat_file_begin,
bool writable,
bool executable,
+ bool low_4gb,
std::string* error_msg) = 0;
bool ComputeFields(uint8_t* requested_base,
@@ -133,6 +135,7 @@
uint8_t* oat_file_begin,
bool writable,
bool executable,
+ bool low_4gb,
const char* abs_dex_location,
std::string* error_msg) {
std::unique_ptr<OatFileBase> ret(new kOatFileBaseSubType(location, executable));
@@ -140,6 +143,7 @@
oat_file_begin,
writable,
executable,
+ low_4gb,
error_msg)) {
return nullptr;
}
@@ -147,7 +151,6 @@
if (!ret->ComputeFields(requested_base, elf_filename, error_msg)) {
return nullptr;
}
-
ret->PreSetup(elf_filename);
if (!ret->Setup(abs_dex_location, error_msg)) {
@@ -532,6 +535,7 @@
uint8_t* oat_file_begin,
bool writable,
bool executable,
+ bool low_4gb,
std::string* error_msg) OVERRIDE;
// Ask the linker where it mmaped the file and notify our mmap wrapper of the regions.
@@ -558,6 +562,7 @@
uint8_t* oat_file_begin,
bool writable,
bool executable,
+ bool low_4gb,
std::string* error_msg) {
// Use dlopen only when flagged to do so, and when it's OK to load things executable.
// TODO: Also try when not executable? The issue here could be re-mapping as writable (as
@@ -567,6 +572,10 @@
*error_msg = "DlOpen is disabled.";
return false;
}
+ if (low_4gb) {
+ *error_msg = "DlOpen does not support low 4gb loading.";
+ return false;
+ }
if (writable) {
*error_msg = "DlOpen does not support writable loading.";
return false;
@@ -702,6 +711,7 @@
uint8_t* oat_file_begin, // Override base if not null
bool writable,
bool executable,
+ bool low_4gb,
const char* abs_dex_location,
std::string* error_msg);
@@ -723,6 +733,7 @@
uint8_t* oat_file_begin, // Override where the file is loaded to if not null
bool writable,
bool executable,
+ bool low_4gb,
std::string* error_msg) OVERRIDE;
void PreSetup(const std::string& elf_filename ATTRIBUTE_UNUSED) OVERRIDE {
@@ -733,6 +744,7 @@
uint8_t* oat_file_begin, // Override where the file is loaded to if not null
bool writable,
bool executable,
+ bool low_4gb,
std::string* error_msg);
private:
@@ -748,11 +760,17 @@
uint8_t* oat_file_begin, // Override base if not null
bool writable,
bool executable,
+ bool low_4gb,
const char* abs_dex_location,
std::string* error_msg) {
ScopedTrace trace("Open elf file " + location);
std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, executable));
- bool success = oat_file->ElfFileOpen(file, oat_file_begin, writable, executable, error_msg);
+ bool success = oat_file->ElfFileOpen(file,
+ oat_file_begin,
+ writable,
+ low_4gb,
+ executable,
+ error_msg);
if (!success) {
CHECK(!error_msg->empty());
return nullptr;
@@ -792,6 +810,7 @@
uint8_t* oat_file_begin, // Override where the file is loaded to if not null
bool writable,
bool executable,
+ bool low_4gb,
std::string* error_msg) {
ScopedTrace trace(__PRETTY_FUNCTION__);
std::unique_ptr<File> file(OS::OpenFileForReading(elf_filename.c_str()));
@@ -803,6 +822,7 @@
oat_file_begin,
writable,
executable,
+ low_4gb,
error_msg);
}
@@ -810,19 +830,21 @@
uint8_t* oat_file_begin,
bool writable,
bool executable,
+ bool low_4gb,
std::string* error_msg) {
ScopedTrace trace(__PRETTY_FUNCTION__);
// TODO: rename requested_base to oat_data_begin
elf_file_.reset(ElfFile::Open(file,
writable,
/*program_header_only*/true,
+ low_4gb,
error_msg,
oat_file_begin));
if (elf_file_ == nullptr) {
DCHECK(!error_msg->empty());
return false;
}
- bool loaded = elf_file_->Load(executable, error_msg);
+ bool loaded = elf_file_->Load(executable, low_4gb, error_msg);
DCHECK(loaded || !error_msg->empty());
return loaded;
}
@@ -870,6 +892,7 @@
uint8_t* requested_base,
uint8_t* oat_file_begin,
bool executable,
+ bool low_4gb,
const char* abs_dex_location,
std::string* error_msg) {
ScopedTrace trace("Open oat file " + location);
@@ -885,15 +908,15 @@
oat_file_begin,
false,
executable,
+ low_4gb,
abs_dex_location,
error_msg);
if (with_dlopen != nullptr) {
return with_dlopen;
}
if (kPrintDlOpenErrorMessage) {
- LOG(ERROR) << "Failed to dlopen: " << *error_msg;
+ LOG(ERROR) << "Failed to dlopen: " << filename << " with error " << *error_msg;
}
-
// If we aren't trying to execute, we just use our own ElfFile loader for a couple reasons:
//
// On target, dlopen may fail when compiling due to selinux restrictions on installd.
@@ -913,6 +936,7 @@
oat_file_begin,
false,
executable,
+ low_4gb,
abs_dex_location,
error_msg);
return with_internal;
@@ -929,6 +953,7 @@
nullptr,
true,
false,
+ /*low_4gb*/false,
abs_dex_location,
error_msg);
}
@@ -944,6 +969,7 @@
nullptr,
false,
false,
+ /*low_4gb*/false,
abs_dex_location,
error_msg);
}