Hi all,
The program has been tested on a HP-ia machine with redhat AS2.1
installed, and the kernel version is 2.4.18-e.47smp.
Thanks helps from David .
JinShan
Here is the source code:
/* ro.c */
/* vi: set ts=4 sw=4 expandtab: */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/unistd.h>
#include <linux/sched.h>
#include <asm/pgtable.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
extern unsigned long sys_call_table[];
//static long (*old_time)(struct timeval *, struct timezone *);
//extern unsigned long new_time_stub;
static unsigned long old_time;
extern void new_time_stub();
struct foo {
void *ip;
void *gp;
};
asm (
" .text\n"
" .proc new_time_stub\n"
"new_time_stub:"
" .prologue\n"
" .regstk 2, 3, 2, 0\n"
" .save ar.pfs, loc1\n"
" alloc loc1 = ar.pfs, 2, 3, 2, 0\n"
" movl r2 = @gprel(zero);;\n"
" .save rp, loc0\n"
" mov loc0 = rp\n"
" mov loc2 = gp\n"
" sub gp = r0, r2\n"
" mov out0 = in0\n"
" mov out1 = in1\n"
" br.call.sptk.many rp = new_time\n"
"1: mov rp = loc0\n"
" mov ar.pfs = loc1\n"
" mov gp = loc2\n"
" br.ret.sptk.many rp\n"
" .endp\n"
);
static atomic_t time_enter_count = ATOMIC_INIT(0);
long new_time(struct timeval *tv, struct timezone *tz)
{
int ret = -EFAULT;
atomic_inc(&time_enter_count);
printk("time be called!\n");
if (tv) {
struct timeval ktv;
do_gettimeofday(&ktv);
if (copy_to_user(tv, &ktv, sizeof(ktv))) {
goto out;
}
}
if (tz) {
extern struct timezone sys_tz;
if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) {
goto out;
}
}
ret = 0;
out:
atomic_dec(&time_enter_count);
return ret;
}
int init_module(void)
{
printk("new_time_stub is %llx\n", new_time_stub);
old_time = sys_call_table[__NR_gettimeofday - 1024];
sys_call_table[__NR_gettimeofday - 1024] = ((struct
foo*)&new_time_stub)->ip;
printk("old_time is %llx\n", old_time);
return 0;
}
void cleanup_module()
{
/* should restore syscall here! */
sys_call_table[__NR_gettimeofday - 1024] = old_time;
printk("Byebye!\n");
/* Here is a race condition window when running on smp. */
do {
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(1);
} while(atomic_read(&time_enter_count));
}
makefile:
gcc -c -D__KERNEL__ -DMODULE -I/lib/modules/`uname
-r`/build/include ro.c
ld -r -o mod.o ro.o --defsym zero=0
-
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html