Showing the changes to src/include (4 of 14 files). Show all
Unified · Split
| @@ -39,6 +39,8 @@ namespace disvm · 38 unmodified lines | |||
| 39 | class loaded_vm_module_t final | 39 | class loaded_vm_module_t final |
| 40 | { | 40 | { |
| 41 | public: | 41 | public: |
| 42 | std::size_t load_id; | ||
| 43 | |||
| 42 | // Origin of module | 44 | // Origin of module |
| 43 | std::unique_ptr<runtime::vm_string_t> origin; | 45 | std::unique_ptr<runtime::vm_string_t> origin; |
| 44 | 46 | ||
| @@ -46,7 +48,8 @@ namespace disvm · 1 unmodified line | |||
| 46 | std::weak_ptr<runtime::vm_module_t> module; | 48 | std::weak_ptr<runtime::vm_module_t> module; |
| 47 | }; | 49 | }; |
| 48 | 50 | ||
| 49 | using loaded_vm_module_callback_t = std::function<void(const loaded_vm_module_t&)>; | 51 | // Callback for enumerating loaded modules - return 'false' to stop enumeration, otherwise 'true' |
| 52 | using loaded_vm_module_callback_t = std::function<bool(const loaded_vm_module_t&)>; | ||
| 50 | 53 | ||
| 51 | // Virtual machine | 54 | // Virtual machine |
| 52 | class vm_t final | 55 | class vm_t final |
| @@ -824,13 +824,12 @@ namespace disvm · 823 unmodified lines | |||
| 824 | virtual void set_tool_dispatch_on_all_threads(vm_tool_dispatch_t *dispatch) = 0; | 824 | virtual void set_tool_dispatch_on_all_threads(vm_tool_dispatch_t *dispatch) = 0; |
| 825 | }; | 825 | }; |
| 826 | 826 | ||
| 827 | // The supplied allocation is guaranteed to be valid for the lifetime of the callback. | ||
| 828 | using vm_alloc_callback_t = std::function<void(const vm_alloc_t *)>; | ||
| 829 | |||
| 827 | // VM garbage collector interface | 830 | // VM garbage collector interface |
| 828 | class vm_garbage_collector_t | 831 | class vm_garbage_collector_t |
| 829 | { | 832 | { |
| 830 | public: | ||
| 831 | // The supplied allocation is guaranteed to be valid for the lifetime of the callback. | ||
| 832 | using vm_alloc_callback_t = std::function<void(const vm_alloc_t *)>; | ||
| 833 | |||
| 834 | public: | 833 | public: |
| 835 | virtual ~vm_garbage_collector_t() = 0; | 834 | virtual ~vm_garbage_collector_t() = 0; |
| 836 | 835 | ||
| @@ -862,7 +861,7 @@ namespace disvm · 25 unmodified lines | |||
| 862 | virtual ~vm_tool_t() = 0; | 861 | virtual ~vm_tool_t() = 0; |
| 863 | 862 | ||
| 864 | // Called when the tool is loaded into the VM | 863 | // Called when the tool is loaded into the VM |
| 865 | virtual void on_load(vm_t &vm, vm_tool_controller_t &controller, std::size_t tool_id) = 0; | 864 | virtual void on_load(vm_tool_controller_t &controller, std::size_t tool_id) = 0; |
| 866 | 865 | ||
| 867 | // Called when the tool is unloaded from the VM. | 866 | // Called when the tool is unloaded from the VM. |
| 868 | // Note once the tool has been unloaded the vm and controller references supplied during load | 867 | // Note once the tool has been unloaded the vm and controller references supplied during load |
| @@ -70,10 +70,11 @@ namespace disvm · 69 unmodified lines | |||
| 70 | // Increment the ref count of all points in the supplied memory allocation | 70 | // Increment the ref count of all points in the supplied memory allocation |
| 71 | void inc_ref_count_in_memory(const type_descriptor_t &type_desc, void *data); | 71 | void inc_ref_count_in_memory(const type_descriptor_t &type_desc, void *data); |
| 72 | 72 | ||
| 73 | // Decrement the ref count and if 0 free the allocation. | 73 | // Decrement the ref count and if 0 free the allocation |
| 74 | void dec_ref_count_and_free(vm_alloc_t *alloc); | 74 | void dec_ref_count_and_free(vm_alloc_t *alloc); |
| 75 | 75 | ||
| 76 | using pointer_field_callback_t = std::function<void(pointer_t)>; | 76 | // Callback for a pointer field supplying the pointer and byte offset |
| 77 | using pointer_field_callback_t = std::function<void(pointer_t, std::size_t)>; | ||
| 77 | 78 | ||
| 78 | // The callback will be called on all non-null pointer fields. | 79 | // The callback will be called on all non-null pointer fields. |
| 79 | inline void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback) | 80 | inline void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback) |
| @@ -82,8 +83,9 @@ namespace disvm · 2 unmodified lines | |||
| 82 | if (type_desc.size_in_bytes == 0) | 83 | if (type_desc.size_in_bytes == 0) |
| 83 | return; | 84 | return; |
| 84 | 85 | ||
| 86 | auto offset_accum = std::size_t{ 0 }; | ||
| 85 | auto memory = reinterpret_cast<word_t *>(data); | 87 | auto memory = reinterpret_cast<word_t *>(data); |
| 86 | for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8) | 88 | for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8, offset_accum += 8) |
| 87 | { | 89 | { |
| 88 | const auto words8 = type_desc.pointer_map[i]; | 90 | const auto words8 = type_desc.pointer_map[i]; |
| 89 | if (words8 != 0) | 91 | if (words8 != 0) |
| @@ -91,14 +93,14 @@ namespace disvm · 1 unmodified line | |||
| 91 | const auto flags = std::bitset<sizeof(words8) * 8>{ words8 }; | 93 | const auto flags = std::bitset<sizeof(words8) * 8>{ words8 }; |
| 92 | 94 | ||
| 93 | // Enumerating the flags in reverse order so memory access is sequential. | 95 | // Enumerating the flags in reverse order so memory access is sequential. |
| 94 | if (flags[7] && (memory[0] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[0])); | 96 | if (flags[7] && (memory[0] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[0]), offset_accum); |
| 95 | if (flags[6] && (memory[1] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[1])); | 97 | if (flags[6] && (memory[1] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[1]), offset_accum + (1 * sizeof(pointer_t))); |
| 96 | if (flags[5] && (memory[2] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[2])); | 98 | if (flags[5] && (memory[2] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[2]), offset_accum + (2 * sizeof(pointer_t))); |
| 97 | if (flags[4] && (memory[3] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[3])); | 99 | if (flags[4] && (memory[3] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[3]), offset_accum + (3 * sizeof(pointer_t))); |
| 98 | if (flags[3] && (memory[4] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[4])); | 100 | if (flags[3] && (memory[4] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[4]), offset_accum + (4 * sizeof(pointer_t))); |
| 99 | if (flags[2] && (memory[5] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[5])); | 101 | if (flags[2] && (memory[5] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[5]), offset_accum + (5 * sizeof(pointer_t))); |
| 100 | if (flags[1] && (memory[6] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[6])); | 102 | if (flags[1] && (memory[6] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[6]), offset_accum + (6 * sizeof(pointer_t))); |
| 101 | if (flags[0] && (memory[7] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[7])); | 103 | if (flags[0] && (memory[7] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[7]), offset_accum + (7 * sizeof(pointer_t))); |
| 102 | } | 104 | } |
| 103 | } | 105 | } |
| 104 | } | 106 | } |
| @@ -17,10 +17,12 @@ namespace disvm · 16 unmodified lines | |||
| 17 | { | 17 | { |
| 18 | namespace runtime | 18 | namespace runtime |
| 19 | { | 19 | { |
| 20 | using cookie_t = std::size_t; | ||
| 21 | |||
| 20 | // Value in event context | 22 | // Value in event context |
| 21 | union vm_context_value_t | 23 | union vm_context_value_t |
| 22 | { | 24 | { |
| 23 | std::size_t i; | 25 | cookie_t cookie; |
| 24 | std::shared_ptr<vm_module_t> *module; // Note this is a pointer to std::shared_ptr<> | 26 | std::shared_ptr<vm_module_t> *module; // Note this is a pointer to std::shared_ptr<> |
| 25 | vm_registers_t *registers; | 27 | vm_registers_t *registers; |
| 26 | const vm_thread_t *thread; | 28 | const vm_thread_t *thread; |
| @@ -39,8 +41,11 @@ namespace disvm · 12 unmodified lines | |||
| 39 | // List of possible events | 41 | // List of possible events |
| 40 | enum class vm_event_t | 42 | enum class vm_event_t |
| 41 | { | 43 | { |
| 42 | module_load, // value1: std::shared_ptr<vm_module_t> | 44 | module_vm_load, // value1: std::shared_ptr<vm_module_t> |
| 43 | // value2: const vm_string_t - path | 45 | // value2: const vm_string_t - path on disk |
| 46 | |||
| 47 | module_thread_load, // value1: vm_registers_t | ||
| 48 | // value2: std::shared_ptr<vm_module_t> | ||
| 44 | 49 | ||
| 45 | thread_begin, // value1: const vm_thread_t | 50 | thread_begin, // value1: const vm_thread_t |
| 46 | thread_end, // value1: const vm_thread_t | 51 | thread_end, // value1: const vm_thread_t |
| @@ -54,22 +59,32 @@ namespace disvm · 7 unmodified lines | |||
| 54 | // value3: const vm_alloc_t - object raised | 59 | // value3: const vm_alloc_t - object raised |
| 55 | 60 | ||
| 56 | breakpoint, // value1: vm_registers_t | 61 | breakpoint, // value1: vm_registers_t |
| 57 | // value2: std::size_t - cookie of breakpoint. '0' indicates the breakpoint was inserted by the VM or compiler. | 62 | // value2: cookie_t - cookie of breakpoint. '0' indicates the breakpoint was inserted by the VM or compiler. |
| 58 | }; | 63 | }; |
| 59 | 64 | ||
| 60 | using vm_event_callback_t = std::function<void(vm_event_t, vm_event_context_t &)>; | 65 | using vm_event_callback_t = std::function<void(vm_event_t, vm_event_context_t &)>; |
| 61 | 66 | ||
| 67 | struct breakpoint_details_t final | ||
| 68 | { | ||
| 69 | std::shared_ptr<vm_module_t> module; | ||
| 70 | vm_pc_t pc; | ||
| 71 | }; | ||
| 72 | |||
| 62 | // VM tool controller | 73 | // VM tool controller |
| 63 | class vm_tool_controller_t | 74 | class vm_tool_controller_t |
| 64 | { | 75 | { |
| 65 | public: | 76 | public: |
| 77 | // The current vm instance | ||
| 78 | virtual vm_t& get_vm_instance() const = 0; | ||
| 79 | |||
| 66 | // Call the supplied callback when the specified event occurs | 80 | // Call the supplied callback when the specified event occurs |
| 67 | virtual std::size_t subscribe_event(vm_event_t, vm_event_callback_t) = 0; | 81 | virtual cookie_t subscribe_event(vm_event_t, vm_event_callback_t) = 0; |
| 68 | virtual void unsubscribe_event(std::size_t) = 0; | 82 | virtual void unsubscribe_event(cookie_t) = 0; |
| 69 | 83 | ||
| 70 | // Set a breakpoint in the supplied module at the specified PC location | 84 | // Set a breakpoint in the supplied module at the specified PC location |
| 71 | virtual std::size_t set_breakpoint(std::shared_ptr<vm_module_t>, vm_pc_t) = 0; | 85 | virtual cookie_t set_breakpoint(std::shared_ptr<vm_module_t>, vm_pc_t) = 0; |
| 72 | virtual void clear_breakpoint(std::size_t) = 0; | 86 | virtual breakpoint_details_t get_breakpoint_details(cookie_t) const = 0; |
| 87 | virtual void clear_breakpoint(cookie_t) = 0; | ||
| 73 | }; | 88 | }; |
| 74 | } | 89 | } |
| 75 | } | 90 | } |