1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "tools/v8windbg/src/cur-isolate.h"
6 
GetIsolateKey(WRL::ComPtr<IDebugHostContext> & sp_ctx,int * isolate_key)7 HRESULT GetIsolateKey(WRL::ComPtr<IDebugHostContext>& sp_ctx,
8                       int* isolate_key) {
9   auto sp_v8_module = Extension::Current()->GetV8Module(sp_ctx);
10   if (sp_v8_module == nullptr) return E_FAIL;
11 
12   WRL::ComPtr<IDebugHostSymbol> sp_isolate_sym;
13   RETURN_IF_FAIL(sp_v8_module->FindSymbolByName(kIsolateKey, &sp_isolate_sym));
14   SymbolKind kind;
15   RETURN_IF_FAIL(sp_isolate_sym->GetSymbolKind(&kind));
16   if (kind != SymbolData) return E_FAIL;
17   WRL::ComPtr<IDebugHostData> sp_isolate_key_data;
18   RETURN_IF_FAIL(sp_isolate_sym.As(&sp_isolate_key_data));
19   Location loc;
20   RETURN_IF_FAIL(sp_isolate_key_data->GetLocation(&loc));
21   ULONG64 bytes_read;
22   RETURN_IF_FAIL(sp_debug_host_memory->ReadBytes(
23       sp_ctx.Get(), loc, isolate_key, sizeof(isolate_key), &bytes_read));
24   return S_OK;
25 }
26 
GetCurrentIsolate(WRL::ComPtr<IModelObject> & sp_result)27 HRESULT GetCurrentIsolate(WRL::ComPtr<IModelObject>& sp_result) {
28   sp_result = nullptr;
29 
30   // Get the current context
31   WRL::ComPtr<IDebugHostContext> sp_host_context;
32   RETURN_IF_FAIL(sp_debug_host->GetCurrentContext(&sp_host_context));
33 
34   WRL::ComPtr<IModelObject> sp_curr_thread;
35   RETURN_IF_FAIL(GetCurrentThread(sp_host_context, &sp_curr_thread));
36 
37   WRL::ComPtr<IModelObject> sp_environment, sp_environment_block;
38   WRL::ComPtr<IModelObject> sp_tls_slots, sp_slot_index, sp_isolate_ptr;
39   RETURN_IF_FAIL(
40       sp_curr_thread->GetKeyValue(L"Environment", &sp_environment, nullptr));
41 
42   RETURN_IF_FAIL(sp_environment->GetKeyValue(L"EnvironmentBlock",
43                                              &sp_environment_block, nullptr));
44 
45   // EnvironmentBlock and TlsSlots are native types (TypeUDT) and thus
46   // GetRawValue rather than GetKeyValue should be used to get field (member)
47   // values.
48   ModelObjectKind kind;
49   RETURN_IF_FAIL(sp_environment_block->GetKind(&kind));
50   if (kind != ModelObjectKind::ObjectTargetObject) return E_FAIL;
51 
52   RETURN_IF_FAIL(sp_environment_block->GetRawValue(SymbolField, L"TlsSlots", 0,
53                                                    &sp_tls_slots));
54 
55   int isolate_key = -1;
56   RETURN_IF_FAIL(GetIsolateKey(sp_host_context, &isolate_key));
57   RETURN_IF_FAIL(CreateInt32(isolate_key, &sp_slot_index));
58 
59   RETURN_IF_FAIL(GetModelAtIndex(sp_tls_slots, sp_slot_index, &sp_isolate_ptr));
60 
61   // Need to dereference the slot and then get the address held in it
62   WRL::ComPtr<IModelObject> sp_dereferenced_slot;
63   RETURN_IF_FAIL(sp_isolate_ptr->Dereference(&sp_dereferenced_slot));
64 
65   uint64_t isolate_ptr;
66   RETURN_IF_FAIL(UnboxULong64(sp_dereferenced_slot.Get(), &isolate_ptr));
67   Location isolate_addr{isolate_ptr};
68 
69   // If we got the isolate_key OK, then must have the V8 module loaded
70   // Get the internal Isolate type from it
71   WRL::ComPtr<IDebugHostType> sp_isolate_type, sp_isolate_ptr_type;
72   RETURN_IF_FAIL(Extension::Current()
73                      ->GetV8Module(sp_host_context)
74                      ->FindTypeByName(kIsolate, &sp_isolate_type));
75   RETURN_IF_FAIL(
76       sp_isolate_type->CreatePointerTo(PointerStandard, &sp_isolate_ptr_type));
77 
78   RETURN_IF_FAIL(sp_data_model_manager->CreateTypedObject(
79       sp_host_context.Get(), isolate_addr, sp_isolate_type.Get(), &sp_result));
80 
81   return S_OK;
82 }
83 
Call(IModelObject * p_context_object,ULONG64 arg_count,IModelObject ** pp_arguments,IModelObject ** pp_result,IKeyStore ** pp_metadata)84 IFACEMETHODIMP CurrIsolateAlias::Call(IModelObject* p_context_object,
85                                       ULONG64 arg_count,
86                                       IModelObject** pp_arguments,
87                                       IModelObject** pp_result,
88                                       IKeyStore** pp_metadata) noexcept {
89   *pp_result = nullptr;
90   WRL::ComPtr<IModelObject> sp_result;
91   RETURN_IF_FAIL(GetCurrentIsolate(sp_result));
92   *pp_result = sp_result.Detach();
93   return S_OK;
94 }
95