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