diff --git a/src/bin/debug/ltrace/arch/x86_64/Jamfile b/src/bin/debug/ltrace/arch/x86_64/Jamfile index f2844ebb89..3d30ffd8dc 100644 --- a/src/bin/debug/ltrace/arch/x86_64/Jamfile +++ b/src/bin/debug/ltrace/arch/x86_64/Jamfile @@ -1,3 +1,8 @@ SubDir HAIKU_TOP src bin debug ltrace arch x86_64 ; -# TODO: Implement! +UsePrivateSystemHeaders ; + +StaticLibrary arch_ltrace_stub.a + : + arch_ltrace_stub.S +; diff --git a/src/bin/debug/ltrace/arch/x86_64/arch_ltrace_stub.S b/src/bin/debug/ltrace/arch/x86_64/arch_ltrace_stub.S new file mode 100644 index 0000000000..056b9f4c14 --- /dev/null +++ b/src/bin/debug/ltrace/arch/x86_64/arch_ltrace_stub.S @@ -0,0 +1,72 @@ +/* + * Copyright 2019, Jérôme Duval, jerome.duval@gmail.com. + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include + + +call_stub: + // push arguments on the stack + push %r9 + push %r8 + push %rcx + push %rdx + push %rsi + push %rdi + // pointer to ourself + lea call_stub(%rip), %rdi + // pointer to first argument + mov %rsp, %rsi + + // call the wrapper function + movq (call_stub_callback_address - call_stub)(%rdi), %rax + call *%rax + // returns a pointer to the actual function + // restore arguments before calling + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %r8 + pop %r9 + jmp *%rax + +.align 8 +call_stub_callback_address: + .long 0 +call_stub_end: + + +// size_t arch_call_stub_size(); +FUNCTION(arch_call_stub_size): + movq $(call_stub_end - call_stub), %rax + ret +FUNCTION_END(arch_call_stub_size) + + +// void arch_init_call_stub(void* stub, +// void* (*callback)(const void* stub, const void* args), +// void* function); +FUNCTION(arch_init_call_stub): + push %rbp + movq %rsp, %rbp + + push %rsi + push %rdi + + // copy the stub + movq $(call_stub_end - call_stub), %rdx + lea call_stub(%rip), %rsi + call memcpy@plt + + // set the callback address in the stub + pop %rdi + pop %rsi + movq %rsi, (call_stub_callback_address - call_stub)(%rdi) + + movq %rbp, %rsp + pop %rbp + ret +FUNCTION_END(arch_init_call_stub) diff --git a/src/bin/debug/ltrace/ltrace_stub.cpp b/src/bin/debug/ltrace/ltrace_stub.cpp index f34949092b..28958da4ca 100644 --- a/src/bin/debug/ltrace/ltrace_stub.cpp +++ b/src/bin/debug/ltrace/ltrace_stub.cpp @@ -33,6 +33,7 @@ struct PatchEntry { static PatchEntry* Create(const char* name, void* function) { + // TODO memory should be executable, use mmap with PROT_EXEC void* memory = malloc(_ALIGN(sizeof(PatchEntry)) + arch_call_stub_size()); if (memory == NULL) @@ -125,7 +126,7 @@ TRACE_PRINTF("function_call_callback(): CALLED FOR UNKNOWN FUNCTION!\n"); size_t bufferSize = sizeof(buffer); size_t written = 0; - const uint32* args = (const uint32*)_args; + const ulong* args = (const ulong*)_args; written += snprintf(buffer, bufferSize, "ltrace: %s(", entry->functionName); for (int32 i = 0; i < 5; i++) { @@ -143,7 +144,7 @@ static void symbol_patcher(void* cookie, image_t* rootImage, image_t* image, const char* name, image_t** foundInImage, void** symbol, int32* type) { - TRACE_PRINTF("symbol_patcher(%p, %p, %p, \"%s\", %p, %p, %ld)\n", + TRACE_PRINTF("symbol_patcher(%p, %p, %p, \"%s\", %p, %p, %" B_PRId32 ")\n", cookie, rootImage, image, name, *foundInImage, *symbol, *type); // patch functions only @@ -188,8 +189,8 @@ ltrace_stub_init(rld_export* standardInterface, static void ltrace_stub_image_loaded(image_t* image) { - TRACE_PRINTF("ltrace_stub_image_loaded(%p): \"%s\" (%ld)\n", image, image->path, - image->id); + TRACE_PRINTF("ltrace_stub_image_loaded(%p): \"%s\" (%" B_PRId32 ")\n", + image, image->path, image->id); if (sRuntimeLoaderAddOnInterface->register_undefined_symbol_patcher(image, symbol_patcher, (void*)(addr_t)0xc0011eaf) != B_OK) { @@ -201,32 +202,32 @@ ltrace_stub_image_loaded(image_t* image) static void ltrace_stub_image_relocated(image_t* image) { - TRACE_PRINTF("ltrace_stub_image_relocated(%p): \"%s\" (%ld)\n", image, - image->path, image->id); + TRACE_PRINTF("ltrace_stub_image_relocated(%p): \"%s\" (%" B_PRId32 ")\n", + image, image->path, image->id); } static void ltrace_stub_image_initialized(image_t* image) { - TRACE_PRINTF("ltrace_stub_image_initialized(%p): \"%s\" (%ld)\n", image, - image->path, image->id); + TRACE_PRINTF("ltrace_stub_image_initialized(%p): \"%s\" (%" B_PRId32 ")\n", + image, image->path, image->id); } static void ltrace_stub_image_uninitializing(image_t* image) { - TRACE_PRINTF("ltrace_stub_image_uninitializing(%p): \"%s\" (%ld)\n", image, - image->path, image->id); + TRACE_PRINTF("ltrace_stub_image_uninitializing(%p): \"%s\" (%" B_PRId32 + ")\n",image, image->path, image->id); } static void ltrace_stub_image_unloading(image_t* image) { - TRACE_PRINTF("ltrace_stub_image_unloading(%p): \"%s\" (%ld)\n", image, - image->path, image->id); + TRACE_PRINTF("ltrace_stub_image_unloading(%p): \"%s\" (%" B_PRId32 ")\n", + image, image->path, image->id); }