Check the machine type of an ELF file when loading.
This ensures that we reject wrong target ELF files,
and should result in a recompile for the right
target.
Change-Id: I898dddc4f2bb9b1607a7436083d0ba7619b6007b
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index f665f5c..c6e448e 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -743,19 +743,7 @@
InstructionSetFeatures instruction_set_features =
ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
-#if defined(__arm__)
- InstructionSet instruction_set = kThumb2;
-#elif defined(__aarch64__)
- InstructionSet instruction_set = kArm64;
-#elif defined(__i386__)
- InstructionSet instruction_set = kX86;
-#elif defined(__x86_64__)
- InstructionSet instruction_set = kX86_64;
-#elif defined(__mips__)
- InstructionSet instruction_set = kMips;
-#else
- InstructionSet instruction_set = kNone;
-#endif
+ InstructionSet instruction_set = kRuntimeISA;
// Profile file to use
std::string profile_file;
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc
index 0c8a4f0..01ca60f 100644
--- a/runtime/elf_file.cc
+++ b/runtime/elf_file.cc
@@ -22,6 +22,7 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "utils.h"
+#include "instruction_set.h"
namespace art {
@@ -773,6 +774,40 @@
bool ElfFile::Load(bool executable, std::string* error_msg) {
CHECK(program_header_only_) << file_->GetPath();
+
+ if (executable) {
+ InstructionSet elf_ISA = kNone;
+ switch (GetHeader().e_machine) {
+ case EM_ARM: {
+ elf_ISA = kArm;
+ break;
+ }
+ case EM_AARCH64: {
+ elf_ISA = kArm64;
+ break;
+ }
+ case EM_386: {
+ elf_ISA = kX86;
+ break;
+ }
+ case EM_X86_64: {
+ elf_ISA = kX86_64;
+ break;
+ }
+ case EM_MIPS: {
+ elf_ISA = kMips;
+ break;
+ }
+ }
+
+ if (elf_ISA != kRuntimeISA) {
+ std::ostringstream oss;
+ oss << "Expected ISA " << kRuntimeISA << " but found " << elf_ISA;
+ *error_msg = oss.str();
+ return false;
+ }
+ }
+
for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
Elf32_Phdr& program_header = GetProgramHeader(i);
diff --git a/runtime/instruction_set.h b/runtime/instruction_set.h
index c5a4ec8..f4eecfc 100644
--- a/runtime/instruction_set.h
+++ b/runtime/instruction_set.h
@@ -35,6 +35,20 @@
};
std::ostream& operator<<(std::ostream& os, const InstructionSet& rhs);
+#if defined(__arm__)
+static constexpr InstructionSet kRuntimeISA = kArm;
+#elif defined(__aarch64__)
+static constexpr InstructionSet kRuntimeISA = kArm64;
+#elif defined(__mips__)
+static constexpr InstructionSet kRuntimeISA = kMips;
+#elif defined(__i386__)
+static constexpr InstructionSet kRuntimeISA = kX86;
+#elif defined(__x86_64__)
+static constexpr InstructionSet kRuntimeISA = kX86_64;
+#else
+static constexpr InstructionSet kRuntimeISA = kNone;
+#endif
+
enum InstructionFeatures {
kHwDiv = 1 // Supports hardware divide.
};