Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(839)

Unified Diff: runtime/bin/gen_snapshot.cc

Issue 3003583002: [VM, Precompiler] PoC Obfuscator (Closed)
Patch Set: Fix bad refactoring in NewAtomicRename Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/bin/main.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/gen_snapshot.cc
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index f543f09498c1e13415797cfaf4256097a05d2ef2..9dee908222e2c9d239a1a60f0b87fad2232a2d8b 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -34,6 +34,122 @@ namespace bin {
DFE dfe;
+// Option processing helpers.
+// TODO(dartbug.com/30534) share option processing between main.cc and
+// gen_snapshot.cc
+
+static const char* ProcessOption(const char* option, const char* name) {
+ const intptr_t length = strlen(name);
+ for (intptr_t i = 0; i < length; i++) {
+ if (option[i] != name[i]) {
+ if (name[i] == '_' && option[i] == '-') {
+ continue;
+ }
+ return NULL;
+ }
+ }
+ return option + length;
+}
+
+typedef bool (*OptionProcessorCallback)(const char* arg);
+
+class OptionProcessor {
+ public:
+ OptionProcessor() : next_(first_) { first_ = this; }
+
+ virtual ~OptionProcessor() {}
+
+ virtual bool Process(const char* option) = 0;
+
+ static bool TryProcess(const char* option) {
+ for (OptionProcessor* p = first_; p != NULL; p = p->next_) {
+ if (p->Process(option)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ static OptionProcessor* first_;
+ OptionProcessor* next_;
+};
+
+class CallbackOptionProcessor : public OptionProcessor {
+ public:
+ explicit CallbackOptionProcessor(OptionProcessorCallback cb) : cb_(cb) {}
+ virtual bool Process(const char* option) { return cb_(option); }
+
+ private:
+ OptionProcessorCallback cb_;
+};
+
+OptionProcessor* OptionProcessor::first_ = NULL;
+
+#define DEFINE_CB_OPTION(callback) \
+ static CallbackOptionProcessor option_##callback(&callback);
+
+#define DEFINE_STRING_OPTION_CB(name, callback) \
+ class OptionProcessor_##name : public OptionProcessor { \
+ public: \
+ virtual bool Process(const char* option) { \
+ const char* value = ProcessOption(option, "--" #name "="); \
+ if (value == NULL) { \
+ return false; \
+ } \
+ if (*value == '\0') { \
+ Log::PrintErr("Empty value for option " #name "\n"); \
+ return false; \
+ } \
+ callback; \
+ return true; \
+ } \
+ }; \
+ static OptionProcessor_##name option_##name;
+
+#define DEFINE_ENUM_OPTION(name, enum_name, variable) \
+ DEFINE_STRING_OPTION_CB(name, { \
+ const char** kNames = k##enum_name##Names; \
+ for (intptr_t i = 0; kNames[i] != NULL; i++) { \
+ if (strcmp(value, kNames[i]) == 0) { \
+ variable = static_cast<enum_name>(i); \
+ return true; \
+ } \
+ } \
+ Log::PrintErr( \
+ "Unrecognized value for " #name ": '%s'\nValid values are: ", value); \
+ for (intptr_t i = 0; kNames[i] != NULL; i++) { \
+ Log::PrintErr("%s%s", i > 0 ? ", " : "", kNames[i]); \
+ } \
+ Log::PrintErr("\n"); \
+ })
+
+#define DEFINE_STRING_OPTION(name, variable) \
+ static const char* variable = NULL; \
+ DEFINE_STRING_OPTION_CB(name, { variable = value; })
+
+#define DEFINE_BOOL_OPTION(name, variable) \
+ static bool variable = false; \
+ class OptionProcessor_##name : public OptionProcessor { \
+ public: \
+ virtual bool Process(const char* option) { \
+ const char* value = ProcessOption(option, "--" #name); \
+ if (value == NULL) { \
+ return false; \
+ } \
+ if (*value == '=') { \
+ Log::PrintErr("Non-empty value for option " #name "\n"); \
+ return false; \
+ } \
+ if (*value != '\0') { \
+ return false; \
+ } \
+ variable = true; \
+ return true; \
+ } \
+ }; \
+ static OptionProcessor_##name option_##name;
+
// Exit code indicating an API error.
static const int kApiErrorExitCode = 253;
// Exit code indicating a compilation error.
@@ -72,30 +188,6 @@ enum SnapshotKind {
kAppAOTAssembly,
};
static SnapshotKind snapshot_kind = kCore;
-static const char* vm_snapshot_data_filename = NULL;
-static const char* vm_snapshot_instructions_filename = NULL;
-static const char* isolate_snapshot_data_filename = NULL;
-static const char* isolate_snapshot_instructions_filename = NULL;
-static const char* assembly_filename = NULL;
-static const char* script_snapshot_filename = NULL;
-static bool dependencies_only = false;
-static bool print_dependencies = false;
-static const char* dependencies_filename = NULL;
-
-// Value of the --load-compilation-trace flag.
-// (This pointer points into an argv buffer and does not need to be
-// free'd.)
-static const char* load_compilation_trace_filename = NULL;
-
-// Value of the --package-root flag.
-// (This pointer points into an argv buffer and does not need to be
-// free'd.)
-static const char* commandline_package_root = NULL;
-
-// Value of the --packages flag.
-// (This pointer points into an argv buffer and does not need to be
-// free'd.)
-static const char* commandline_packages_file = NULL;
// Global state which contains a pointer to the script name for which
// a snapshot needs to be created (NULL would result in the creation
@@ -196,203 +288,32 @@ static Dart_Handle EnvironmentCallback(Dart_Handle name) {
return result;
}
-static const char* ProcessOption(const char* option, const char* name) {
- const intptr_t length = strlen(name);
- if (strncmp(option, name, length) == 0) {
- return (option + length);
- }
- return NULL;
-}
-
-static bool ProcessSnapshotKindOption(const char* option) {
- const char* kind = ProcessOption(option, "--snapshot_kind=");
- if (kind == NULL) {
- kind = ProcessOption(option, "--snapshot-kind=");
- }
- if (kind == NULL) {
- return false;
- }
- if (strcmp(kind, "core-jit") == 0) {
- snapshot_kind = kCoreJIT;
- return true;
- } else if (strcmp(kind, "core") == 0) {
- snapshot_kind = kCore;
- return true;
- } else if (strcmp(kind, "script") == 0) {
- snapshot_kind = kScript;
- return true;
- } else if (strcmp(kind, "app-aot-blobs") == 0) {
- snapshot_kind = kAppAOTBlobs;
- return true;
- } else if (strcmp(kind, "app-aot-assembly") == 0) {
- snapshot_kind = kAppAOTAssembly;
- return true;
- }
- Log::PrintErr(
- "Unrecognized snapshot kind: '%s'\nValid kinds are: "
- "core, script, app-aot-blobs, app-aot-assembly\n",
- kind);
- return false;
-}
-
-static bool ProcessVmSnapshotDataOption(const char* option) {
- const char* name = ProcessOption(option, "--vm_snapshot_data=");
- if (name == NULL) {
- name = ProcessOption(option, "--vm-snapshot-data=");
- }
- if (name != NULL) {
- vm_snapshot_data_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessVmSnapshotInstructionsOption(const char* option) {
- const char* name = ProcessOption(option, "--vm_snapshot_instructions=");
- if (name == NULL) {
- name = ProcessOption(option, "--vm-snapshot-instructions=");
- }
- if (name != NULL) {
- vm_snapshot_instructions_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessIsolateSnapshotDataOption(const char* option) {
- const char* name = ProcessOption(option, "--isolate_snapshot_data=");
- if (name == NULL) {
- name = ProcessOption(option, "--isolate-snapshot-data=");
- }
- if (name != NULL) {
- isolate_snapshot_data_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessIsolateSnapshotInstructionsOption(const char* option) {
- const char* name = ProcessOption(option, "--isolate_snapshot_instructions=");
- if (name == NULL) {
- name = ProcessOption(option, "--isolate-snapshot-instructions=");
- }
- if (name != NULL) {
- isolate_snapshot_instructions_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessAssemblyOption(const char* option) {
- const char* name = ProcessOption(option, "--assembly=");
- if (name != NULL) {
- assembly_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessScriptSnapshotOption(const char* option) {
- const char* name = ProcessOption(option, "--script_snapshot=");
- if (name == NULL) {
- name = ProcessOption(option, "--script-snapshot=");
- }
- if (name != NULL) {
- script_snapshot_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessDependenciesOption(const char* option) {
- const char* name = ProcessOption(option, "--dependencies=");
- if (name != NULL) {
- dependencies_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessDependenciesOnlyOption(const char* option) {
- const char* name = ProcessOption(option, "--dependencies_only");
- if (name == NULL) {
- name = ProcessOption(option, "--dependencies-only");
- }
- if (name != NULL) {
- dependencies_only = true;
- return true;
- }
- return false;
-}
-
-static bool ProcessPrintDependenciesOption(const char* option) {
- const char* name = ProcessOption(option, "--print_dependencies");
- if (name == NULL) {
- name = ProcessOption(option, "--print-dependencies");
- }
- if (name != NULL) {
- print_dependencies = true;
- return true;
- }
- return false;
-}
-
-static bool ProcessEmbedderEntryPointsManifestOption(const char* option) {
- const char* name = ProcessOption(option, "--embedder_entry_points_manifest=");
- if (name == NULL) {
- name = ProcessOption(option, "--embedder-entry-points-manifest=");
- }
- if (name != NULL) {
- entry_points_files->AddArgument(name);
- return true;
- }
- return false;
-}
-
-static bool ProcessLoadCompilationTraceOption(const char* option) {
- const char* name = ProcessOption(option, "--load_compilation_trace=");
- if (name == NULL) {
- name = ProcessOption(option, "--load-compilation-trace=");
- }
- if (name != NULL) {
- load_compilation_trace_filename = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessPackageRootOption(const char* option) {
- const char* name = ProcessOption(option, "--package_root=");
- if (name == NULL) {
- name = ProcessOption(option, "--package-root=");
- }
- if (name != NULL) {
- commandline_package_root = name;
- return true;
- }
- return false;
-}
+static const char* kSnapshotKindNames[] = {
+ "core", "core-jit", "script", "app-aot-blobs", "app-aot-assembly", NULL,
+};
-static bool ProcessPackagesOption(const char* option) {
- const char* name = ProcessOption(option, "--packages=");
- if (name != NULL) {
- commandline_packages_file = name;
- return true;
- }
- return false;
-}
-
-static bool ProcessURLmappingOption(const char* option) {
- const char* mapping = ProcessOption(option, "--url_mapping=");
- if (mapping == NULL) {
- mapping = ProcessOption(option, "--url-mapping=");
- }
- if (mapping != NULL) {
- DartUtils::url_mapping->AddArgument(mapping);
- return true;
- }
- return false;
-}
+DEFINE_ENUM_OPTION(snapshot_kind, SnapshotKind, snapshot_kind);
+DEFINE_STRING_OPTION(vm_snapshot_data, vm_snapshot_data_filename);
+DEFINE_STRING_OPTION(vm_snapshot_instructions,
+ vm_snapshot_instructions_filename);
+DEFINE_STRING_OPTION(isolate_snapshot_data, isolate_snapshot_data_filename);
+DEFINE_STRING_OPTION(isolate_snapshot_instructions,
+ isolate_snapshot_instructions_filename);
+DEFINE_STRING_OPTION(assembly, assembly_filename);
+DEFINE_STRING_OPTION(script_snapshot, script_snapshot_filename);
+DEFINE_STRING_OPTION(dependencies, dependencies_filename);
+DEFINE_BOOL_OPTION(dependencies_only, dependencies_only);
+DEFINE_BOOL_OPTION(print_dependencies, print_dependencies);
+DEFINE_STRING_OPTION_CB(embedder_entry_points_manifest,
+ { entry_points_files->AddArgument(value); });
+DEFINE_STRING_OPTION(load_compilation_trace, load_compilation_trace_filename);
+DEFINE_STRING_OPTION(package_root, commandline_package_root);
+DEFINE_STRING_OPTION(packages, commandline_packages_file);
+DEFINE_STRING_OPTION_CB(url_mapping,
+ { DartUtils::url_mapping->AddArgument(value); });
+DEFINE_CB_OPTION(ProcessEnvironmentOption);
+DEFINE_BOOL_OPTION(obfuscate, obfuscate);
+DEFINE_STRING_OPTION(save_obfuscation_map, obfuscation_map_filename);
static bool IsSnapshottingForPrecompilation() {
return (snapshot_kind == kAppAOTBlobs) || (snapshot_kind == kAppAOTAssembly);
@@ -412,21 +333,7 @@ static int ParseArguments(int argc,
// Parse out the vm options.
while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
- if (ProcessSnapshotKindOption(argv[i]) ||
- ProcessVmSnapshotDataOption(argv[i]) ||
- ProcessVmSnapshotInstructionsOption(argv[i]) ||
- ProcessIsolateSnapshotDataOption(argv[i]) ||
- ProcessIsolateSnapshotInstructionsOption(argv[i]) ||
- ProcessAssemblyOption(argv[i]) ||
- ProcessScriptSnapshotOption(argv[i]) ||
- ProcessDependenciesOption(argv[i]) ||
- ProcessDependenciesOnlyOption(argv[i]) ||
- ProcessPrintDependenciesOption(argv[i]) ||
- ProcessEmbedderEntryPointsManifestOption(argv[i]) ||
- ProcessURLmappingOption(argv[i]) ||
- ProcessLoadCompilationTraceOption(argv[i]) ||
- ProcessPackageRootOption(argv[i]) || ProcessPackagesOption(argv[i]) ||
- ProcessEnvironmentOption(argv[i])) {
+ if (OptionProcessor::TryProcess(argv[i])) {
i += 1;
continue;
}
@@ -520,6 +427,19 @@ static int ParseArguments(int argc,
return -1;
}
+ if (!obfuscate && obfuscation_map_filename != NULL) {
+ Log::PrintErr(
+ "--obfuscation_map=<...> should only be specified when obfuscation is "
+ "enabled by --obfuscate flag.\n\n");
+ return -1;
+ }
+
+ if (obfuscate && !IsSnapshottingForPrecompilation()) {
+ Log::PrintErr(
+ "Obfuscation can only be enabled when building AOT snapshot.\n\n");
+ return -1;
+ }
+
return 0;
}
@@ -970,6 +890,8 @@ static void PrintUsage() {
" --isolate_snapshot_data=<output-file> \n"
" --isolate_snapshot_instructions=<output-file> \n"
" {--embedder_entry_points_manifest=<input-file>} \n"
+" [--obfuscate] \n"
+" [--save-obfuscation-map=<map-filename>] \n"
" <dart-script-file> \n"
" \n"
" To create an AOT application snapshot as assembly suitable for compilation \n"
@@ -978,6 +900,8 @@ static void PrintUsage() {
" --snapshot_kind=app-aot-blobs \n"
" --assembly=<output-file> \n"
" {--embedder_entry_points_manifest=<input-file>} \n"
+" [--obfuscate] \n"
+" [--save-obfuscation-map=<map-filename>] \n"
" <dart-script-file> \n"
" \n"
" AOT snapshots require entry points manifest files, which list the places \n"
@@ -990,6 +914,13 @@ static void PrintUsage() {
" \n"
" Example: \n"
" dart:something,SomeClass,doSomething \n"
+" \n"
+" AOT snapshots can be obfuscated: that is all identifiers will be renamed \n"
+" during compilation. This mode is enabled with --obfuscate flag. Mapping \n"
+" between original and obfuscated names can be serialized as a JSON array \n"
+" using --save-obfuscation-map=<filename> option. See dartbug.com/30524 \n"
+" for implementation details and limitations of the obfuscation pass. \n"
+" \n"
"\n");
}
// clang-format on
@@ -1467,6 +1398,16 @@ static void CreateAndWritePrecompiledSnapshot(
isolate_snapshot_instructions_buffer,
isolate_snapshot_instructions_size);
}
+
+ // Serialize obfuscation map if requested.
+ if (obfuscation_map_filename != NULL) {
+ ASSERT(obfuscate);
+ uint8_t* buffer = NULL;
+ intptr_t size = 0;
+ result = Dart_GetObfuscationMap(&buffer, &size);
+ CHECK_RESULT(result);
+ WriteFile(obfuscation_map_filename, buffer, size);
+ }
}
static void SetupForUriResolution() {
@@ -1664,6 +1605,12 @@ int main(int argc, char** argv) {
return kErrorExitCode;
}
+ Dart_IsolateFlags flags;
+ Dart_IsolateFlagsInitialize(&flags);
+
+ Dart_QualifiedFunctionName* entry_points =
+ ParseEntryPointsManifestIfPresent();
+
IsolateData* isolate_data = new IsolateData(NULL, commandline_package_root,
commandline_packages_file, NULL);
Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data,
@@ -1718,6 +1665,11 @@ int main(int argc, char** argv) {
isolate_data->set_dependencies(new MallocGrowableArray<char*>());
}
+ if (IsSnapshottingForPrecompilation()) {
+ flags.obfuscate = obfuscate;
+ flags.entry_points = entry_points;
+ }
+
Dart_Isolate isolate = NULL;
void* kernel_program = dfe.ReadScript(app_script_name);
if (kernel_program != NULL) {
@@ -1725,7 +1677,7 @@ int main(int argc, char** argv) {
isolate_data, &error);
} else {
isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data,
- isolate_snapshot_instructions, NULL,
+ isolate_snapshot_instructions, &flags,
isolate_data, &error);
}
if (isolate == NULL) {
@@ -1746,9 +1698,6 @@ int main(int argc, char** argv) {
AddDependency(commandline_packages_file);
}
- Dart_QualifiedFunctionName* entry_points =
- ParseEntryPointsManifestIfPresent();
-
if (kernel_program != NULL) {
Dart_Handle resolved_uri = ResolveUriInWorkingDirectory(app_script_name);
CHECK_RESULT(resolved_uri);
« no previous file with comments | « no previous file | runtime/bin/main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698