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

Side by Side Diff: runtime/vm/precompiler.cc

Issue 3003583002: [VM, Precompiler] PoC Obfuscator (Closed)
Patch Set: Discard obfuscation map 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/precompiler.h" 5 #include "vm/precompiler.h"
6 6
7 #include "vm/aot_optimizer.h" 7 #include "vm/aot_optimizer.h"
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/branch_optimizer.h" 10 #include "vm/branch_optimizer.h"
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 I->object_store()->set_async_star_move_next_helper(null_function); 482 I->object_store()->set_async_star_move_next_helper(null_function);
483 I->object_store()->set_complete_on_async_return(null_function); 483 I->object_store()->set_complete_on_async_return(null_function);
484 I->object_store()->set_async_star_stream_controller(null_class); 484 I->object_store()->set_async_star_stream_controller(null_class);
485 DropLibraryEntries(); 485 DropLibraryEntries();
486 } 486 }
487 DropClasses(); 487 DropClasses();
488 DropLibraries(); 488 DropLibraries();
489 489
490 BindStaticCalls(); 490 BindStaticCalls();
491 SwitchICCalls(); 491 SwitchICCalls();
492 Obfuscate();
492 493
rmacnak 2017/08/23 01:16:50 We should clear the obfuscation table from the obj
Vyacheslav Egorov (Google) 2017/08/23 15:54:52 This is done at the end of Obfuscate()
493 ProgramVisitor::Dedup(); 494 ProgramVisitor::Dedup();
494 495
495 zone_ = NULL; 496 zone_ = NULL;
496 } 497 }
497 498
498 intptr_t symbols_before = -1; 499 intptr_t symbols_before = -1;
499 intptr_t symbols_after = -1; 500 intptr_t symbols_after = -1;
500 intptr_t capacity = -1; 501 intptr_t capacity = -1;
501 if (FLAG_trace_precompiler) { 502 if (FLAG_trace_precompiler) {
502 Symbols::GetStats(I, &symbols_before, &capacity); 503 Symbols::GetStats(I, &symbols_before, &capacity);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 current->field_->set_guarded_cid(cid); 604 current->field_->set_guarded_cid(cid);
604 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid); 605 current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid);
605 if (FLAG_trace_precompiler) { 606 if (FLAG_trace_precompiler) {
606 THR_Print( 607 THR_Print(
607 "Field %s <- Type %s\n", current->field_->ToCString(), 608 "Field %s <- Type %s\n", current->field_->ToCString(),
608 Class::Handle(T->isolate()->class_table()->At(cid)).ToCString()); 609 Class::Handle(T->isolate()->class_table()->At(cid)).ToCString());
609 } 610 }
610 } 611 }
611 } 612 }
612 613
613 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { 614 static Dart_QualifiedFunctionName vm_entry_points[] = {
614 // Note that <rootlibrary>.main is not a root. The appropriate main will be
615 // discovered through _getMainClosure.
616
617 AddSelector(Symbols::NoSuchMethod());
618
619 AddSelector(Symbols::Call()); // For speed, not correctness.
620
621 // Allocated from C++.
622 Class& cls = Class::Handle(Z);
623 for (intptr_t cid = kInstanceCid; cid < kNumPredefinedCids; cid++) {
624 ASSERT(isolate()->class_table()->IsValidIndex(cid));
625 if (!isolate()->class_table()->HasValidClassAt(cid)) {
626 continue;
627 }
628 if ((cid == kDynamicCid) || (cid == kVoidCid) ||
629 (cid == kFreeListElement) || (cid == kForwardingCorpse)) {
630 continue;
631 }
632 cls = isolate()->class_table()->At(cid);
633 AddInstantiatedClass(cls);
634 }
635
636 Dart_QualifiedFunctionName vm_entry_points[] = {
637 // Functions 615 // Functions
638 {"dart:core", "::", "_completeDeferredLoads"}, 616 {"dart:core", "::", "_completeDeferredLoads"},
639 {"dart:core", "::", "identityHashCode"}, 617 {"dart:core", "::", "identityHashCode"},
640 {"dart:core", "AbstractClassInstantiationError", 618 {"dart:core", "AbstractClassInstantiationError",
641 "AbstractClassInstantiationError._create"}, 619 "AbstractClassInstantiationError._create"},
642 {"dart:core", "ArgumentError", "ArgumentError."}, 620 {"dart:core", "ArgumentError", "ArgumentError."},
643 {"dart:core", "ArgumentError", "ArgumentError.value"}, 621 {"dart:core", "ArgumentError", "ArgumentError.value"},
644 {"dart:core", "CyclicInitializationError", "CyclicInitializationError."}, 622 {"dart:core", "CyclicInitializationError", "CyclicInitializationError."},
645 {"dart:core", "FallThroughError", "FallThroughError._create"}, 623 {"dart:core", "FallThroughError", "FallThroughError._create"},
646 {"dart:core", "FormatException", "FormatException."}, 624 {"dart:core", "FormatException", "FormatException."},
(...skipping 21 matching lines...) Expand all
668 #if !defined(PRODUCT) 646 #if !defined(PRODUCT)
669 {"dart:_vmservice", "::", "_registerIsolate"}, 647 {"dart:_vmservice", "::", "_registerIsolate"},
670 {"dart:developer", "Metrics", "_printMetrics"}, 648 {"dart:developer", "Metrics", "_printMetrics"},
671 {"dart:developer", "::", "_runExtension"}, 649 {"dart:developer", "::", "_runExtension"},
672 {"dart:isolate", "::", "_runPendingImmediateCallback"}, 650 {"dart:isolate", "::", "_runPendingImmediateCallback"},
673 #endif // !PRODUCT 651 #endif // !PRODUCT
674 // Fields 652 // Fields
675 {"dart:core", "Error", "_stackTrace"}, 653 {"dart:core", "Error", "_stackTrace"},
676 {"dart:math", "_Random", "_state"}, 654 {"dart:math", "_Random", "_state"},
677 {NULL, NULL, NULL} // Must be terminated with NULL entries. 655 {NULL, NULL, NULL} // Must be terminated with NULL entries.
678 }; 656 };
657
658 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) {
659 // Note that <rootlibrary>.main is not a root. The appropriate main will be
660 // discovered through _getMainClosure.
661
662 AddSelector(Symbols::NoSuchMethod());
663
664 AddSelector(Symbols::Call()); // For speed, not correctness.
665
666 // Allocated from C++.
667 Class& cls = Class::Handle(Z);
668 for (intptr_t cid = kInstanceCid; cid < kNumPredefinedCids; cid++) {
669 ASSERT(isolate()->class_table()->IsValidIndex(cid));
670 if (!isolate()->class_table()->HasValidClassAt(cid)) {
671 continue;
672 }
673 if ((cid == kDynamicCid) || (cid == kVoidCid) ||
674 (cid == kFreeListElement) || (cid == kForwardingCorpse)) {
675 continue;
676 }
677 cls = isolate()->class_table()->At(cid);
678 AddInstantiatedClass(cls);
679 }
679 680
680 AddEntryPoints(vm_entry_points); 681 AddEntryPoints(vm_entry_points);
681 AddEntryPoints(embedder_entry_points); 682 AddEntryPoints(embedder_entry_points);
682 const Library& lib = Library::Handle(I->object_store()->root_library()); 683 const Library& lib = Library::Handle(I->object_store()->root_library());
683 const String& name = String::Handle(String::New("main")); 684 const String& name = String::Handle(String::New("main"));
684 const Object& main_closure = Object::Handle(lib.GetFunctionClosure(name)); 685 const Object& main_closure = Object::Handle(lib.GetFunctionClosure(name));
685 if (main_closure.IsClosure()) { 686 if (main_closure.IsClosure()) {
686 if (lib.LookupLocalFunction(name) == Function::null()) { 687 if (lib.LookupLocalFunction(name) == Function::null()) {
687 // Check whether the function is in exported namespace of library, in 688 // Check whether the function is in exported namespace of library, in
688 // this case we have to retain the root library caches. 689 // this case we have to retain the root library caches.
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
2271 Code& target_code_; 2272 Code& target_code_;
2272 UnlinkedCallSet canonical_unlinked_calls_; 2273 UnlinkedCallSet canonical_unlinked_calls_;
2273 }; 2274 };
2274 2275
2275 ASSERT(!I->compilation_allowed()); 2276 ASSERT(!I->compilation_allowed());
2276 SwitchICCallsVisitor visitor(Z); 2277 SwitchICCallsVisitor visitor(Z);
2277 ProgramVisitor::VisitFunctions(&visitor); 2278 ProgramVisitor::VisitFunctions(&visitor);
2278 #endif 2279 #endif
2279 } 2280 }
2280 2281
2282 void Precompiler::Obfuscate() {
2283 // TODO(dartbug.com/XXX) remove URIs from Scripts and Libraries.
2284
2285 // Discard obfuscation mappings to avoid including them into snapshot.
2286 I->object_store()->set_obfuscation_map(Array::Handle(Z));
2287 }
2288
2281 void Precompiler::FinalizeAllClasses() { 2289 void Precompiler::FinalizeAllClasses() {
2282 Library& lib = Library::Handle(Z); 2290 Library& lib = Library::Handle(Z);
2283 Class& cls = Class::Handle(Z); 2291 Class& cls = Class::Handle(Z);
2284 2292
2285 for (intptr_t i = 0; i < libraries_.Length(); i++) { 2293 for (intptr_t i = 0; i < libraries_.Length(); i++) {
2286 lib ^= libraries_.At(i); 2294 lib ^= libraries_.At(i);
2287 if (!lib.Loaded()) { 2295 if (!lib.Loaded()) {
2288 String& uri = String::Handle(Z, lib.url()); 2296 String& uri = String::Handle(Z, lib.url());
2289 String& msg = String::Handle( 2297 String& msg = String::Handle(
2290 Z, 2298 Z,
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
3323 FieldTypeMap* field_type_map) { 3331 FieldTypeMap* field_type_map) {
3324 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); 3332 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
3325 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function); 3333 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function);
3326 3334
3327 ASSERT(FLAG_precompiled_mode); 3335 ASSERT(FLAG_precompiled_mode);
3328 const bool optimized = function.IsOptimizable(); // False for natives. 3336 const bool optimized = function.IsOptimizable(); // False for natives.
3329 DartPrecompilationPipeline pipeline(zone, field_type_map); 3337 DartPrecompilationPipeline pipeline(zone, field_type_map);
3330 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); 3338 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized);
3331 } 3339 }
3332 3340
3341 Obfuscator::Obfuscator(Thread* thread, const String& private_key)
3342 : state_(NULL) {
3343 Isolate* isolate = thread->isolate();
3344 Zone* zone = thread->zone();
3345
3346 if (isolate->obfuscate()) {
3347 ObjectStore* store = thread->isolate()->object_store();
3348 Array& obfuscation_state = Array::Handle(zone, store->obfuscation_map());
3349
3350 if (store->obfuscation_map() == Array::null()) {
3351 const int kInitialPrivateCapacity = 256;
3352 obfuscation_state = Array::New(kSavedStateSize);
3353 obfuscation_state.SetAt(
3354 1, Array::Handle(zone, HashTables::New<ObfuscationMap>(
3355 kInitialPrivateCapacity, Heap::kOld)));
3356 }
3357
3358 state_ =
3359 new (zone) ObfuscationState(thread, obfuscation_state, private_key);
3360
3361 if (store->obfuscation_map() == Array::null()) {
3362 InitializeRenamingMap(isolate);
3363 }
3364 }
3365 }
3366
3367 Obfuscator::~Obfuscator() {
3368 if (state_ != NULL) {
3369 state_->SaveState();
3370 }
3371 }
3372
3373 void Obfuscator::InitializeRenamingMap(Isolate* isolate) {
3374 // Prevent renaming of classes and method names mentioned in the
3375 // entry points lists.
3376 PreventRenaming(vm_entry_points);
3377 PreventRenaming(isolate->embedder_entry_points());
3378
3379 // Prevent renaming of all pseudo-keywords and operators.
3380 // Note: not all pseudo-keywords are mentioned in DART_KEYWORD_LIST
3381 // (for example 'hide', 'show' and async related keywords are omitted).
3382 // Those are protected from renaming as part of all symbols.
3383 #define PREVENT_RENAMING(name, value, priority, attr) \
3384 do { \
3385 if (Token::CanBeOverloaded(Token::name) || \
3386 ((Token::attr & Token::kPseudoKeyword) != 0)) { \
3387 PreventRenaming(value); \
3388 } \
3389 } while (0);
3390
3391 DART_TOKEN_LIST(PREVENT_RENAMING)
3392 DART_KEYWORD_LIST(PREVENT_RENAMING)
3393 #undef PREVENT_RENAMING
3394
3395 // Protect all symbols from renaming.
3396 #define PREVENT_RENAMING(name, value) PreventRenaming(value);
3397 PREDEFINED_SYMBOLS_LIST(PREVENT_RENAMING)
3398 #undef PREVENT_RENAMING
3399
3400 // Protect NativeFieldWrapperClassX names from being obfuscated. Those
3401 // classes are created manually by the runtime system.
3402 // TODO(dartbug.com/XXX) instead call to Obfuscator::Rename from a place
3403 // where these are created.
3404 PreventRenaming("NativeFieldWrapperClass1");
3405 PreventRenaming("NativeFieldWrapperClass2");
3406 PreventRenaming("NativeFieldWrapperClass3");
3407 PreventRenaming("NativeFieldWrapperClass4");
3408
3409 // Prevent renaming of ClassID.cid* fields. These fields are injected by
3410 // runtime.
3411 // TODO(dartbug.com/XXX) instead call to Obfuscator::Rename from a place
3412 // where these are created.
3413 #define CLASS_LIST_WITH_NULL(V) \
3414 V(Null) \
3415 CLASS_LIST_NO_OBJECT(V)
3416 #define PREVENT_RENAMING(clazz) PreventRenaming("cid" #clazz);
3417 CLASS_LIST_WITH_NULL(PREVENT_RENAMING)
3418 #undef PREVENT_RENAMING
3419 #undef CLASS_LIST_WITH_NULL
3420
3421 // Prevent renaming of methods that are looked up by method recognizer.
3422 // TODO(dartbug.com/XXX) instead call to Obfuscator::Rename from a place
3423 // where these are looked up.
3424 #define PREVENT_RENAMING(class_name, function_name, recognized_enum, \
3425 result_type, fingerprint) \
3426 do { \
3427 PreventRenaming(#class_name); \
3428 PreventRenaming(#function_name); \
3429 } while (0);
3430 RECOGNIZED_LIST(PREVENT_RENAMING)
3431 #undef PREVENT_RENAMING
3432
3433 // Prevent renaming of methods that are looked up by method recognizer.
3434 // TODO(dartbug.com/XXX) instead call to Obfuscator::Rename from a place
3435 // where these are looked up.
3436 #define PREVENT_RENAMING(class_name, function_name, recognized_enum, \
3437 fingerprint) \
3438 do { \
3439 PreventRenaming(#class_name); \
3440 PreventRenaming(#function_name); \
3441 } while (0);
3442 INLINE_WHITE_LIST(PREVENT_RENAMING)
3443 INLINE_BLACK_LIST(PREVENT_RENAMING)
3444 POLYMORPHIC_TARGET_LIST(PREVENT_RENAMING)
3445 #undef PREVENT_RENAMING
3446
3447 // These are not mentioned by entry points but are still looked up by name.
rmacnak 2017/08/23 01:16:50 They should be mentioned by the entry points. We'r
Vyacheslav Egorov (Google) 2017/08/23 15:54:52 Done.
3448 PreventRenaming("_resolveScriptUri");
3449 PreventRenaming("_printClosure");
3450 PreventRenaming("_uriBaseClosure");
3451 PreventRenaming("_isolateId");
3452 PreventRenaming("_loadPort");
3453 PreventRenaming("_ip");
3454 PreventRenaming("_port");
3455 PreventRenaming("_autoStart");
3456 PreventRenaming("_originCheckDisabled");
3457 PreventRenaming("_isWindows");
3458 PreventRenaming("_isFuchsia");
3459 PreventRenaming("_traceLoading");
3460 PreventRenaming("_getWatchSignalInternal");
3461 PreventRenaming("_signalWatch");
3462 PreventRenaming("main");
3463
3464 // Fast path for common conditional import. See Deobfuscate method.
3465 PreventRenaming("dart");
3466 PreventRenaming("library");
3467 PreventRenaming("io");
3468 PreventRenaming("html");
3469 }
3470
3471 RawString* Obfuscator::ObfuscationState::RenameImpl(const String& name,
3472 bool atomic) {
3473 ASSERT(name.IsSymbol());
3474
3475 renamed_ ^= renames_.GetOrNull(name);
3476 if (renamed_.IsNull()) {
3477 renamed_ = BuildRename(name, atomic);
3478 renames_.UpdateOrInsert(name, renamed_);
3479 }
3480 return renamed_.raw();
3481 }
3482
3483 void Obfuscator::PreventRenaming(Dart_QualifiedFunctionName entry_points[]) {
3484 for (intptr_t i = 0; entry_points[i].function_name != NULL; i++) {
3485 const char* class_name = entry_points[i].class_name;
3486 const char* function_name = entry_points[i].function_name;
3487
3488 const size_t class_name_len = strlen(class_name);
3489 if (strncmp(function_name, class_name, class_name_len) == 0 &&
3490 function_name[class_name_len] == '.') {
3491 const char* ctor_name = function_name + class_name_len + 1;
3492 if (ctor_name[0] != '\0') {
3493 PreventRenaming(ctor_name);
3494 }
3495 } else {
3496 PreventRenaming(function_name);
3497 }
3498 PreventRenaming(class_name);
3499 }
3500 }
3501
3502 static const char* const kGetterPrefix = "get:";
3503 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix);
3504 static const char* const kSetterPrefix = "set:";
3505 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix);
3506
3507 void Obfuscator::PreventRenaming(const char* name) {
3508 const char* dot = strchr(name, '.');
3509 if (dot != NULL) {
3510 name = dot + 1;
3511 }
3512
3513 if (name[0] == '\0') {
3514 return;
3515 }
3516
3517 if (strncmp(name, kGetterPrefix, kGetterPrefixLength) == 0) {
3518 name = name + kGetterPrefixLength;
3519 } else if (strncmp(name, kSetterPrefix, kSetterPrefixLength) == 0) {
3520 name = name + kSetterPrefixLength;
3521 }
3522
3523 state_->PreventRenaming(name);
3524 }
3525
3526 void Obfuscator::ObfuscationState::SaveState() {
3527 saved_state_.SetAt(kSavedStateNameIndex, String::Handle(String::New(name_)));
3528 saved_state_.SetAt(kSavedStateRenamesIndex, renames_.Release());
3529 thread_->isolate()->object_store()->set_obfuscation_map(saved_state_);
3530 }
3531
3532 void Obfuscator::ObfuscationState::PreventRenaming(const char* name) {
3533 string_ = Symbols::New(thread_, name);
3534 PreventRenaming(string_);
3535 }
3536
3537 void Obfuscator::ObfuscationState::PreventRenaming(const String& name) {
3538 renames_.UpdateOrInsert(name, name);
3539 }
3540
3541 void Obfuscator::ObfuscationState::NextName() {
3542 for (intptr_t i = 0;; i++) {
3543 const char digit = name_[i];
3544 if (digit == '\0') {
3545 name_[i] = 'a';
3546 } else if (digit < 'Z') {
3547 name_[i]++;
3548 } else if (digit == 'Z') {
3549 name_[i] = 'a';
3550 continue;
3551 } else if (digit < 'z') {
3552 name_[i]++;
3553 } else {
3554 name_[i] = 'A';
3555 }
3556 break;
3557 }
3558 }
3559
3560 RawString* Obfuscator::ObfuscationState::NewAtomicRename(
3561 bool should_be_private) {
3562 do {
3563 NextName();
3564 renamed_ = Symbols::NewFormatted(thread_, "%s%s",
3565 should_be_private ? "_" : "", name_);
3566 } while (renames_.ContainsKey(renamed_));
3567 return renamed_.raw();
3568 }
3569
3570 RawString* Obfuscator::ObfuscationState::BuildRename(const String& name,
3571 bool atomic) {
3572 const bool is_private = name.CharAt(0) == '_';
3573 if (!atomic && is_private) {
3574 intptr_t i = 0;
3575 while (i < name.Length() && name.CharAt(i) != '@') {
3576 i++;
3577 }
3578 const intptr_t end = i;
3579
3580 string_ = Symbols::New(thread_, name, 0, end);
3581
3582 string_ = RenameImpl(string_, /*atomic=*/true);
3583 return Symbols::FromConcat(thread_, string_, private_key_);
3584 } else {
3585 return NewAtomicRename(is_private);
3586 }
3587 }
3588
3589 void Obfuscator::ObfuscateSymbolInstance(Thread* thread,
3590 const Instance& symbol) {
3591 const intptr_t kSymbolNameOffset = kWordSize;
3592
3593 Object& name_value = String::Handle();
3594 name_value = symbol.RawGetFieldAtOffset(kSymbolNameOffset);
3595 if (!name_value.IsString()) {
3596 // dart.internal.Symbol constructor does not validate its input.
3597 return;
3598 }
3599
3600 String& name = String::Handle();
3601 name ^= name_value.raw();
3602
3603 // TODO(vegorov) it is quite wasteful to create an obfuscator per-symbol.
3604 Obfuscator obfuscator(thread, /*private_key=*/String::Handle());
3605
3606 String& component = String::Handle();
3607 GrowableHandlePtrArray<const String> renamed(thread->zone(), 2);
3608
3609 const intptr_t length = name.Length();
3610 intptr_t i = 0, start = 0;
3611 while (i < length) {
3612 // First look for a '.' in the symbol.
3613 start = i;
3614 while (i < length && name.CharAt(i) != '.') {
3615 i++;
3616 }
3617 const intptr_t end = i;
3618 if (end == length) {
3619 break;
3620 }
3621
3622 if (start != end) {
3623 component = Symbols::New(thread, name, start, end - start);
3624 component = obfuscator.Rename(component, /*atomic=*/true);
3625 renamed.Add(component);
3626 }
3627
3628 renamed.Add(Symbols::Dot());
3629 i++; // Skip '.'
3630 }
3631
3632 // Handle the last component [start, length).
3633 // If symbol ends up at = and it is not one of '[]=', '==', '<=' or
3634 // '>=' then we treat it as a setter symbol of form 'name=' and
3635 // obfuscate to rename('name') + '='.
3636 const bool is_setter = (length - start) > 1 &&
3637 name.CharAt(length - 1) == '=' &&
3638 !(name.Equals(Symbols::AssignIndexToken()) ||
3639 name.Equals(Symbols::EqualOperator()) ||
3640 name.Equals(Symbols::GreaterEqualOperator()) ||
3641 name.Equals(Symbols::LessEqualOperator()));
3642 const intptr_t end = length - (is_setter ? 1 : 0);
3643
3644 if ((start == 0) && (end == length) && name.IsSymbol()) {
3645 component = name.raw();
3646 } else {
3647 component = Symbols::New(thread, name, start, end - start);
3648 }
3649 component = obfuscator.Rename(component, /*atomic=*/true);
3650 renamed.Add(component);
3651
3652 if (is_setter) {
3653 renamed.Add(Symbols::Equals());
3654 }
3655
3656 name = Symbols::FromConcatAll(thread, renamed);
3657 symbol.RawSetFieldAtOffset(kSymbolNameOffset, name);
3658 }
3659
3660 void Obfuscator::Deobfuscate(Thread* thread,
3661 const GrowableObjectArray& pieces) {
3662 const Array& obfuscation_state = Array::Handle(
3663 thread->zone(), thread->isolate()->object_store()->obfuscation_map());
3664 if (obfuscation_state.IsNull()) {
3665 return;
3666 }
3667
3668 const Array& renames = Array::Handle(
3669 thread->zone(), GetRenamesFromSavedState(obfuscation_state));
3670
3671 ObfuscationMap renames_map(renames.raw());
3672 String& piece = String::Handle();
3673 for (intptr_t i = 0; i < pieces.Length(); i++) {
3674 piece ^= pieces.At(i);
3675 ASSERT(piece.IsSymbol());
3676
3677 // Fast path: skip '.'
3678 if (piece.raw() == Symbols::Dot().raw()) {
3679 continue;
3680 }
3681
3682 // Fast path: check if piece has an identity obfuscation.
3683 if (renames_map.GetOrNull(piece) == piece.raw()) {
3684 continue;
3685 }
3686
3687 ObfuscationMap::Iterator it(&renames_map);
3688 while (it.MoveNext()) {
3689 const intptr_t entry = it.Current();
3690 if (renames_map.GetPayload(entry, 0) == piece.raw()) {
3691 piece ^= renames_map.GetKey(entry);
3692 pieces.SetAt(i, piece);
3693 break;
3694 }
3695 }
3696 }
3697 renames_map.Release();
3698 }
3699
3333 #endif // DART_PRECOMPILER 3700 #endif // DART_PRECOMPILER
3334 3701
3335 } // namespace dart 3702 } // namespace dart
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/precompiler.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698