if (log_options) {
LOG(INFO) << "patchoat: option[" << i << "]=" << argv[i];
}
- // TODO: GetInstructionSetFromString shouldn't LOG(FATAL).
if (option.starts_with("--instruction-set=")) {
isa_set = true;
const char* isa_str = option.substr(strlen("--instruction-set=")).data();
- if (!strcmp("arm", isa_str)) {
- isa = kArm;
- } else if (!strcmp("arm64", isa_str)) {
- isa = kArm64;
- } else if (!strcmp("x86", isa_str)) {
- isa = kX86;
- } else if (!strcmp("x86_64", isa_str)) {
- isa = kX86_64;
- } else if (!strcmp("mips", isa_str)) {
- isa = kMips;
- } else {
- Usage("Unknown instruction set %s", isa_str);
+ isa = GetInstructionSetFromString(isa_str);
+ if (isa == kNone) {
+ Usage("Unknown or invalid instruction set %s", isa_str);
}
} else if (option.starts_with("--input-oat-location=")) {
if (have_input_oat) {
InstructionSet GetInstructionSetFromString(const char* isa_str) {
CHECK(isa_str != nullptr);
- if (!strcmp("arm", isa_str)) {
+ if (strcmp("arm", isa_str) == 0) {
return kArm;
- } else if (!strcmp("arm64", isa_str)) {
+ } else if (strcmp("arm64", isa_str) == 0) {
return kArm64;
- } else if (!strcmp("x86", isa_str)) {
+ } else if (strcmp("x86", isa_str) == 0) {
return kX86;
- } else if (!strcmp("x86_64", isa_str)) {
+ } else if (strcmp("x86_64", isa_str) == 0) {
return kX86_64;
- } else if (!strcmp("mips", isa_str)) {
+ } else if (strcmp("mips", isa_str) == 0) {
return kMips;
- } else if (!strcmp("none", isa_str)) {
- return kNone;
}
- LOG(FATAL) << "Unknown ISA " << isa_str;
return kNone;
}
const char* GetInstructionSetString(InstructionSet isa);
+
+// Note: Returns kNone when the string cannot be parsed to a known value.
InstructionSet GetInstructionSetFromString(const char* instruction_set);
static inline size_t GetInstructionSetPointerSize(InstructionSet isa) {
EXPECT_EQ(kX86_64, GetInstructionSetFromString("x86_64"));
EXPECT_EQ(kMips, GetInstructionSetFromString("mips"));
EXPECT_EQ(kNone, GetInstructionSetFromString("none"));
+ EXPECT_EQ(kNone, GetInstructionSetFromString("random-string"));
}
TEST_F(InstructionSetTest, GetInstructionSetString) {
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/stringprintf.h"
#include "class_linker.h"
#include "common_throws.h"
#include "dex_file-inl.h"
}
const InstructionSet target_instruction_set = GetInstructionSetFromString(instruction_set);
+ if (target_instruction_set == kNone) {
+ ScopedLocalRef<jclass> iae(env, env->FindClass("java/lang/IllegalArgumentException"));
+ std::string message(StringPrintf("Instruction set %s is invalid.", instruction_set));
+ env->ThrowNew(iae.get(), message.c_str());
+ return 0;
+ }
// Get the filename for odex file next to the dex file.
std::string odex_filename(DexFilenameToOdexFilename(filename, target_instruction_set));
static jbyte DexFile_isDexOptNeededInternal(JNIEnv* env, jclass, jstring javaFilename,
jstring javaPkgname, jstring javaInstructionSet, jboolean defer) {
ScopedUtfChars filename(env, javaFilename);
+ if (env->ExceptionCheck()) {
+ return 0;
+ }
+
NullableScopedUtfChars pkgname(env, javaPkgname);
+
ScopedUtfChars instruction_set(env, javaInstructionSet);
+ if (env->ExceptionCheck()) {
+ return 0;
+ }
return IsDexOptNeededInternal(env, filename.c_str(), pkgname.c_str(),
instruction_set.c_str(), defer);
compiler_callbacks_ =
reinterpret_cast<CompilerCallbacks*>(const_cast<void*>(options[i].second));
} else if (option == "imageinstructionset") {
- image_isa_ = GetInstructionSetFromString(
- reinterpret_cast<const char*>(options[i].second));
+ const char* isa_str = reinterpret_cast<const char*>(options[i].second);
+ image_isa_ = GetInstructionSetFromString(isa_str);
+ if (image_isa_ == kNone) {
+ Usage("%s is not a valid instruction set.", isa_str);
+ return false;
+ }
} else if (option == "-Xzygote") {
is_zygote_ = true;
} else if (StartsWith(option, "-Xpatchoat:")) {