diff --git a/bindings/gumjs/gumv8sampler.cpp b/bindings/gumjs/gumv8sampler.cpp new file mode 100644 index 000000000..8c5384f65 --- /dev/null +++ b/bindings/gumjs/gumv8sampler.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2013-2023 Ole André Vadla Ravnås + * + * Licence: wxWindows Library Licence, Version 3.1 + */ + +#include "gumv8sampler.h" +#include "gumsampler.h" +#include "gumwallclocksampler.h" + +#include "gumv8macros.h" +#include "gumv8scope.h" + +#define GUMJS_MODULE_NAME Sampler + +using namespace v8; + +GUMJS_DECLARE_CONSTRUCTOR (gumjs_sampler_construct) +GUMJS_DECLARE_FUNCTION (gumjs_sampler_sample) +GUMJS_DECLARE_CONSTRUCTOR (gumjs_wallclock_sampler_construct) + +static const GumV8Function gumjs_sampler_functions[] = +{ + { "sample", gumjs_sampler_sample }, + + { NULL, NULL } +}; + +void +_gum_v8_sampler_init (GumV8Sampler * self, + GumV8Core * core, + Local scope) +{ + auto isolate = core->isolate; + + self->core = core; + + auto module = External::New (isolate, self); + + auto sampler = _gum_v8_create_class ("Sampler", + gumjs_sampler_construct, scope, module, isolate); + _gum_v8_class_add (sampler, gumjs_sampler_functions, module, isolate); + self->sampler = new Global (isolate, sampler); + + auto wallclock_sampler = _gum_v8_create_class ("WallClockSampler", + gumjs_wallclock_sampler_construct, scope, module, isolate); + wallclock_sampler->Inherit (sampler); +} + +void +_gum_v8_sampler_realize (GumV8Sampler * self) +{ + gum_v8_object_manager_init (&self->objects); +} + +void +_gum_v8_sampler_flush (GumV8Sampler * self) +{ + gum_v8_object_manager_flush (&self->objects); +} + +void +_gum_v8_sampler_dispose (GumV8Sampler * self) +{ + gum_v8_object_manager_free (&self->objects); +} + +void +_gum_v8_sampler_finalize (GumV8Sampler * self) +{ +} + +GUMJS_DEFINE_CONSTRUCTOR (gumjs_sampler_construct) +{ + GumV8Sampler * sampler; + if (!_gum_v8_args_parse (args, "X", &sampler)) + return; + + gum_v8_object_manager_add (&module->objects, wrapper, sampler, module); +} + +GUMJS_DEFINE_CLASS_METHOD (gumjs_sampler_sample, GumSampler) +{ + GumSample sample; + + sample = gum_sampler_sample (self); + + info.GetReturnValue ().Set (_gum_v8_uint64_new (sample, core)); +} + +GUMJS_DEFINE_CONSTRUCTOR (gumjs_wallclock_sampler_construct) +{ + if (!info.IsConstructCall ()) + { + _gum_v8_throw_ascii_literal (isolate, + "use `new WallClockSampler()` to create a new instance"); + return; + } + + auto sampler = gum_wallclock_sampler_new (); + + gum_v8_object_manager_add (&module->objects, wrapper, sampler, module); + + wrapper->SetAlignedPointerInInternalField (0, sampler); +} \ No newline at end of file diff --git a/bindings/gumjs/gumv8sampler.h b/bindings/gumjs/gumv8sampler.h new file mode 100644 index 000000000..de968e6ca --- /dev/null +++ b/bindings/gumjs/gumv8sampler.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013-2020 Ole André Vadla Ravnås + * + * Licence: wxWindows Library Licence, Version 3.1 + */ + +#ifndef __GUM_V8_SAMPLER_H__ +#define __GUM_V8_SAMPLER_H__ + +#include "gumv8object.h" + +struct GumV8Sampler +{ + GumV8Core * core; + + GumV8ObjectManager objects; + + v8::Global * sampler; + v8::Global * wallclock_sampler; +}; + +G_GNUC_INTERNAL void _gum_v8_sampler_init (GumV8Sampler * self, + GumV8Core * core, v8::Local scope); +G_GNUC_INTERNAL void _gum_v8_sampler_realize (GumV8Sampler * self); +G_GNUC_INTERNAL void _gum_v8_sampler_flush (GumV8Sampler * self); +G_GNUC_INTERNAL void _gum_v8_sampler_dispose (GumV8Sampler * self); +G_GNUC_INTERNAL void _gum_v8_sampler_finalize (GumV8Sampler * self); + +#endif diff --git a/bindings/gumjs/gumv8script-priv.h b/bindings/gumjs/gumv8script-priv.h index 037859811..24d8f56a9 100644 --- a/bindings/gumjs/gumv8script-priv.h +++ b/bindings/gumjs/gumv8script-priv.h @@ -26,6 +26,7 @@ #include "gumv8script.h" #include "gumv8scriptbackend.h" #include "gumv8socket.h" +#include "gumv8sampler.h" #include "gumv8stalker.h" #include "gumv8stream.h" #include "gumv8symbol.h" @@ -95,6 +96,7 @@ struct _GumV8Script GumV8Instruction instruction; GumV8CodeWriter code_writer; GumV8CodeRelocator code_relocator; + GumV8Sampler sampler; GumV8Stalker stalker; GumV8Cloak cloak; diff --git a/bindings/gumjs/gumv8script.cpp b/bindings/gumjs/gumv8script.cpp index 4554235d2..6495804dd 100644 --- a/bindings/gumjs/gumv8script.cpp +++ b/bindings/gumjs/gumv8script.cpp @@ -536,6 +536,7 @@ gum_v8_script_create_context (GumV8Script * self, _gum_v8_code_writer_init (&self->code_writer, &self->core, global_templ); _gum_v8_code_relocator_init (&self->code_relocator, &self->code_writer, &self->instruction, &self->core, global_templ); + _gum_v8_sampler_init (&self->sampler, &self->core, global_templ); _gum_v8_stalker_init (&self->stalker, &self->code_writer, &self->instruction, &self->core, global_templ); _gum_v8_cloak_init (&self->cloak, &self->core, global_templ); @@ -570,6 +571,7 @@ gum_v8_script_create_context (GumV8Script * self, _gum_v8_instruction_realize (&self->instruction); _gum_v8_code_writer_realize (&self->code_writer); _gum_v8_code_relocator_realize (&self->code_relocator); + _gum_v8_sampler_realize (&self->sampler); _gum_v8_stalker_realize (&self->stalker); _gum_v8_cloak_realize (&self->cloak); @@ -1103,6 +1105,7 @@ gum_v8_script_destroy_context (GumV8Script * self) ScriptScope scope (self); _gum_v8_cloak_dispose (&self->cloak); + _gum_v8_sampler_dispose (&self->sampler); _gum_v8_stalker_dispose (&self->stalker); _gum_v8_code_relocator_dispose (&self->code_relocator); _gum_v8_code_writer_dispose (&self->code_writer); @@ -1136,6 +1139,7 @@ gum_v8_script_destroy_context (GumV8Script * self) self->context = nullptr; _gum_v8_cloak_finalize (&self->cloak); + _gum_v8_sampler_finalize (&self->sampler); _gum_v8_stalker_finalize (&self->stalker); _gum_v8_code_relocator_finalize (&self->code_relocator); _gum_v8_code_writer_finalize (&self->code_writer); @@ -1422,6 +1426,7 @@ gum_v8_script_try_unload (GumV8Script * self) { ScriptScope scope (self); + _gum_v8_sampler_flush (&self->sampler); _gum_v8_stalker_flush (&self->stalker); _gum_v8_interceptor_flush (&self->interceptor); _gum_v8_socket_flush (&self->socket); diff --git a/bindings/gumjs/meson.build b/bindings/gumjs/meson.build index e06848eeb..74d2d7332 100644 --- a/bindings/gumjs/meson.build +++ b/bindings/gumjs/meson.build @@ -90,6 +90,7 @@ if v8_dep.found() 'gumv8codewriter.cpp', 'gumv8coderelocator.cpp', 'gumv8cloak.cpp', + 'gumv8sampler.cpp', ] if sqlite_dep.found() gumjs_sources += 'gumv8database.cpp'