Index: runtime/vm/precompiler.h |
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h |
index 2aff2a4d0cac1f6ef279bce0da3f815b4a4eb876..2fac04f85cd53f049fba32a9a2185784a18b436a 100644 |
--- a/runtime/vm/precompiler.h |
+++ b/runtime/vm/precompiler.h |
@@ -398,6 +398,8 @@ class Precompiler : public ValueObject { |
void SwitchICCalls(); |
void ResetPrecompilerState(); |
+ void Obfuscate(); |
+ |
void CollectDynamicFunctionNames(); |
void PrecompileStaticInitializers(); |
@@ -476,6 +478,126 @@ class FunctionsTraits { |
typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; |
+#if defined(DART_PRECOMPILER) |
+// ObfuscationMap maps Strings to Strings. |
+class ObfuscationMapTraits { |
+ public: |
+ static const char* Name() { return "ObfuscationMapTraits"; } |
+ static bool ReportStats() { return false; } |
+ |
+ // Only for non-descriptor lookup and table expansion. |
+ static bool IsMatch(const Object& a, const Object& b) { |
+ return a.raw() == b.raw(); |
+ } |
+ |
+ static uword Hash(const Object& key) { return String::Cast(key).Hash(); } |
+}; |
+typedef UnorderedHashMap<ObfuscationMapTraits> ObfuscationMap; |
+ |
+class Obfuscator { |
+ public: |
+ Obfuscator(Thread* thread, const String& private_key); |
+ ~Obfuscator(); |
+ |
+ RawString* Rename(const String& name, bool atomic = false) { |
+ if (state_ == NULL) { |
+ return name.raw(); |
+ } |
+ |
+ return state_->RenameImpl(name, atomic); |
+ } |
+ |
+ static void ObfuscateSymbolInstance(Thread* thread, const Instance& instance); |
+ |
+ static void Deobfuscate(Thread* thread, const GrowableObjectArray& pieces); |
+ |
+ private: |
+ void InitializeRenamingMap(Isolate* isolate); |
+ void PreventRenaming(Dart_QualifiedFunctionName* entry_points); |
+ void PreventRenaming(const char* name); |
+ void PreventRenaming(const String& name) { state_->PreventRenaming(name); } |
+ |
+ static const intptr_t kSavedStateNameIndex = 0; |
+ static const intptr_t kSavedStateRenamesIndex = 1; |
+ static const intptr_t kSavedStateSize = 2; |
+ |
+ static RawArray* GetRenamesFromSavedState(const Array& saved_state) { |
+ Array& renames = Array::Handle(); |
+ renames ^= saved_state.At(kSavedStateRenamesIndex); |
+ return renames.raw(); |
+ } |
+ |
+ static RawString* GetNameFromSavedState(const Array& saved_state) { |
+ String& name = String::Handle(); |
+ name ^= saved_state.At(kSavedStateNameIndex); |
+ return name.raw(); |
+ } |
+ |
+ class ObfuscationState : public ZoneAllocated { |
+ public: |
+ ObfuscationState(Thread* thread, |
+ const Array& saved_state, |
+ const String& private_key) |
+ : thread_(thread), |
+ saved_state_(saved_state), |
+ renames_(GetRenamesFromSavedState(saved_state)), |
+ private_key_(private_key), |
+ string_(String::Handle(thread->zone())), |
+ renamed_(String::Handle(thread->zone())) { |
+ memset(name_, 0, sizeof(name_)); |
+ |
+ string_ = GetNameFromSavedState(saved_state); |
+ if (!string_.IsNull()) { |
+ string_.ToUTF8(reinterpret_cast<uint8_t*>(name_), sizeof(name_)); |
+ } |
+ } |
+ |
+ void SaveState(); |
+ |
+ RawString* RenameImpl(const String& name, bool atomic); |
+ RawString* BuildRename(const String& name, bool atomic); |
+ RawString* NewAtomicRename(bool should_be_private); |
+ |
+ void NextName(); |
+ |
+ void PreventRenaming(const String& name); |
+ void PreventRenaming(const char* name); |
+ |
+ private: |
+ Thread* thread_; |
+ |
+ const Array& saved_state_; |
+ |
+ char name_[100]; |
+ ObfuscationMap renames_; |
+ |
+ const String& private_key_; |
+ |
+ String& string_; |
+ String& renamed_; |
+ }; |
+ |
+ ObfuscationState* state_; |
+}; |
+#else |
+// Minimal do-nothing implementation of an Obfuscator for non-precompiler |
+// builds. |
+class Obfuscator { |
+ public: |
+ Obfuscator(Thread* thread, const String& private_key) {} |
+ ~Obfuscator() {} |
+ |
+ RawString* Rename(const String& name, bool atomic = false) { |
+ return name.raw(); |
+ } |
+ |
+ static void ObfuscateSymbolInstance(Thread* thread, |
+ const Instance& instance) {} |
+ |
+ static void Deobfuscate(Thread* thread, const GrowableObjectArray& pieces) {} |
+}; |
+#endif // DART_PRECOMPILER |
+ |
} // namespace dart |
#endif // RUNTIME_VM_PRECOMPILER_H_ |