ltrace: implement x86_64 arch specifics.
fix trace build on x86_64 Change-Id: I205bd9eee03efea9e298c2877cc0a6440770caf0 Reviewed-on: https://review.haiku-os.org/c/1148 Reviewed-by: waddlesplash <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
f82b4294d8
commit
29ec639a6d
@@ -1,3 +1,8 @@
|
|||||||
SubDir HAIKU_TOP src bin debug ltrace arch x86_64 ;
|
SubDir HAIKU_TOP src bin debug ltrace arch x86_64 ;
|
||||||
|
|
||||||
# TODO: Implement!
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
|
StaticLibrary arch_ltrace_stub.a
|
||||||
|
:
|
||||||
|
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 <asm_defs.h>
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
@@ -33,6 +33,7 @@ struct PatchEntry {
|
|||||||
|
|
||||||
static PatchEntry* Create(const char* name, void* function)
|
static PatchEntry* Create(const char* name, void* function)
|
||||||
{
|
{
|
||||||
|
// TODO memory should be executable, use mmap with PROT_EXEC
|
||||||
void* memory = malloc(_ALIGN(sizeof(PatchEntry))
|
void* memory = malloc(_ALIGN(sizeof(PatchEntry))
|
||||||
+ arch_call_stub_size());
|
+ arch_call_stub_size());
|
||||||
if (memory == NULL)
|
if (memory == NULL)
|
||||||
@@ -125,7 +126,7 @@ TRACE_PRINTF("function_call_callback(): CALLED FOR UNKNOWN FUNCTION!\n");
|
|||||||
size_t bufferSize = sizeof(buffer);
|
size_t bufferSize = sizeof(buffer);
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
|
||||||
const uint32* args = (const uint32*)_args;
|
const ulong* args = (const ulong*)_args;
|
||||||
written += snprintf(buffer, bufferSize, "ltrace: %s(",
|
written += snprintf(buffer, bufferSize, "ltrace: %s(",
|
||||||
entry->functionName);
|
entry->functionName);
|
||||||
for (int32 i = 0; i < 5; i++) {
|
for (int32 i = 0; i < 5; i++) {
|
||||||
@@ -143,7 +144,7 @@ static void
|
|||||||
symbol_patcher(void* cookie, image_t* rootImage, image_t* image,
|
symbol_patcher(void* cookie, image_t* rootImage, image_t* image,
|
||||||
const char* name, image_t** foundInImage, void** symbol, int32* type)
|
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);
|
cookie, rootImage, image, name, *foundInImage, *symbol, *type);
|
||||||
|
|
||||||
// patch functions only
|
// patch functions only
|
||||||
@@ -188,8 +189,8 @@ ltrace_stub_init(rld_export* standardInterface,
|
|||||||
static void
|
static void
|
||||||
ltrace_stub_image_loaded(image_t* image)
|
ltrace_stub_image_loaded(image_t* image)
|
||||||
{
|
{
|
||||||
TRACE_PRINTF("ltrace_stub_image_loaded(%p): \"%s\" (%ld)\n", image, image->path,
|
TRACE_PRINTF("ltrace_stub_image_loaded(%p): \"%s\" (%" B_PRId32 ")\n",
|
||||||
image->id);
|
image, image->path, image->id);
|
||||||
|
|
||||||
if (sRuntimeLoaderAddOnInterface->register_undefined_symbol_patcher(image,
|
if (sRuntimeLoaderAddOnInterface->register_undefined_symbol_patcher(image,
|
||||||
symbol_patcher, (void*)(addr_t)0xc0011eaf) != B_OK) {
|
symbol_patcher, (void*)(addr_t)0xc0011eaf) != B_OK) {
|
||||||
@@ -201,32 +202,32 @@ ltrace_stub_image_loaded(image_t* image)
|
|||||||
static void
|
static void
|
||||||
ltrace_stub_image_relocated(image_t* image)
|
ltrace_stub_image_relocated(image_t* image)
|
||||||
{
|
{
|
||||||
TRACE_PRINTF("ltrace_stub_image_relocated(%p): \"%s\" (%ld)\n", image,
|
TRACE_PRINTF("ltrace_stub_image_relocated(%p): \"%s\" (%" B_PRId32 ")\n",
|
||||||
image->path, image->id);
|
image, image->path, image->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ltrace_stub_image_initialized(image_t* image)
|
ltrace_stub_image_initialized(image_t* image)
|
||||||
{
|
{
|
||||||
TRACE_PRINTF("ltrace_stub_image_initialized(%p): \"%s\" (%ld)\n", image,
|
TRACE_PRINTF("ltrace_stub_image_initialized(%p): \"%s\" (%" B_PRId32 ")\n",
|
||||||
image->path, image->id);
|
image, image->path, image->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ltrace_stub_image_uninitializing(image_t* image)
|
ltrace_stub_image_uninitializing(image_t* image)
|
||||||
{
|
{
|
||||||
TRACE_PRINTF("ltrace_stub_image_uninitializing(%p): \"%s\" (%ld)\n", image,
|
TRACE_PRINTF("ltrace_stub_image_uninitializing(%p): \"%s\" (%" B_PRId32
|
||||||
image->path, image->id);
|
")\n",image, image->path, image->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ltrace_stub_image_unloading(image_t* image)
|
ltrace_stub_image_unloading(image_t* image)
|
||||||
{
|
{
|
||||||
TRACE_PRINTF("ltrace_stub_image_unloading(%p): \"%s\" (%ld)\n", image,
|
TRACE_PRINTF("ltrace_stub_image_unloading(%p): \"%s\" (%" B_PRId32 ")\n",
|
||||||
image->path, image->id);
|
image, image->path, image->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user