Project

General

Profile

Bug #907 ยป rtld_functrace.diff

corecode, 01/05/2008 11:25 PM

View differences:

rtld.c 31 Dec 2007 17:39:18 -0000
static char *ld_preload; /* Environment variable for libraries to
load first */
static const char *ld_tracing; /* Called from ldd(1) to print libs */
/* Optional function call tracing hook */
static int (*rtld_functrace)(const char *caller_obj,
const char *callee_obj,
const char *callee_func,
void *stack);
static Obj_Entry *rtld_functrace_obj; /* Object thereof */
static Obj_Entry *obj_list; /* Head of linked list of shared objects */
static Obj_Entry **obj_tail; /* Link field of last object in list */
static Obj_Entry **preload_tail;
......
}
Elf_Addr
_rtld_bind(Obj_Entry *obj, Elf_Word reloff)
_rtld_bind(Obj_Entry *obj, Elf_Word reloff, void *stack)
{
const Elf_Rel *rel;
const Elf_Sym *def;
const Obj_Entry *defobj;
Elf_Addr *where;
Elf_Addr target;
int do_reloc = 1;
rlock_acquire();
if (obj->pltrel)
......
dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
defobj->strtab + def->st_name, basename(obj->path),
(void *)target, basename(defobj->path));
reloc_jmpslot(where, target);
rlock_release();
/*
* If we have a function call tracing hook, and the
* hook would like to keep tracing this one function,
* prevent the relocation so we will wind up here
* the next time again.
*
* We don't want to functrace calls from the functracer
* to avoid recursive loops.
*/
if (rtld_functrace != NULL && obj != rtld_functrace_obj) {
if (rtld_functrace(obj->path,
defobj->path,
defobj->strtab + def->st_name,
stack))
do_reloc = 0;
}
if (do_reloc)
reloc_jmpslot(where, target);
return target;
}
......
return 0;
}
#define RTLD_FUNCTRACE "_rtld_functrace"
static int
load_preload_objects(void)
{
......
size_t len = strcspn(p, delim);
char *path;
char savech;
Obj_Entry *obj;
const Elf_Sym *sym;
savech = p[len];
p[len] = '\0';
if ((path = find_library(p, NULL)) == NULL)
return -1;
if (load_object(path) == NULL)
obj = load_object(path);
if (obj == NULL)
return -1; /* XXX - cleanup */
p[len] = savech;
p += len;
p += strspn(p, delim);
/* Check for the magic tracing function */
sym = symlook_obj(RTLD_FUNCTRACE, elf_hash(RTLD_FUNCTRACE), obj, true);
if (sym != NULL) {
rtld_functrace = (void *)(obj->relocbase + sym->st_value);
rtld_functrace_obj = obj;
}
}
return 0;
}
i386/rtld_start.S 30 Dec 2007 21:42:15 -0000
pushl %eax # Save %eax
pushl %edx # Save %edx
pushl %ecx # Save %ecx
pushl 20(%esp) # Copy reloff argument
pushl 20(%esp) # Copy obj argument
leal 24(%esp),%eax # Calculate original stack addr
pushl %eax # Pass stack addr as 3. arg
pushl 24(%esp) # Copy reloff argument
pushl 24(%esp) # Copy obj argument
call _rtld_bind@PLT # Transfer control to the binder
/* Now %eax contains the entry point of the function being called. */
addl $8,%esp # Discard binder arguments
addl $12,%esp # Discard binder arguments
movl %eax,20(%esp) # Store target over obj argument
popl %ecx # Restore %ecx
popl %edx # Restore %edx
    (1-1/1)