public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
* [Linux-ia64] patching sys_call_table from a module
@ 2001-07-03 13:45 chas williams
  2001-07-03 20:03 ` chas williams
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: chas williams @ 2001-07-03 13:45 UTC (permalink / raw)
  To: linux-ia64

afs patches the sys_call_table to provide support for various functions.
the existing doesnt seem to work right.  i figured out that the ia64
calls are offset by 1024.  but know i have a different problem:

during insmod i printk what i patch the table with:

sys_call_table[__NR_afs_syscall - 1024] = a000000000125bd0
afs_syscall a000000000125bd0

however, i get the following ksymoops when i try to use that syscall:

>>IP;  a000000000125bd1 <[libafs-2.4.5].bss.end+7e32/3fffffffffee2261>   <==>>b0;  e000000004415ce0 <ia64_ret_from_syscall+0/20>
>>b6;  e000000004402f60 <demine_args+0/a0>
>>b7;  e0000000044157b0 <ia64_switch_to+b0/120>
Trace; e00000000441a080 <show_stack+40/c0>
Trace; e00000000441a840 <show_regs+740/780>
Trace; e00000000442b830 <die_if_kernel+70/140>
Trace; e00000000442c510 <ia64_illegal_op_fault+130/220>
Trace; e000000004403ed0 <dispatch_illegal_op_fault+2b0/400>

so yes, a000000000125bd0 does seem to be [libafs-2.4.5].bss.end+7e32
however, if i look at the loadmap from the insmod, i see:

a0000000000f59e0 T afs_syscall

would this have anything to do with -mconstant-gp?


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
@ 2001-07-03 20:03 ` chas williams
  2001-07-03 20:44 ` Don Dugger
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: chas williams @ 2001-07-03 20:03 UTC (permalink / raw)
  To: linux-ia64

i wrote a little example to illustrate my problem.  its attached at the
bottom.  if i make a syscall(__NR_afs_syscall, ...) i get the following:

pts[2437]: Bad break 104

psr : 0000101008026018 ifs : 8000000000000008 ip  : [<a0000000000344b0>]
unat: 0000000000000000 pfs : 0000000000000089 rsc : 0000000000000003
rnat: 40000000000bb190 bsps: e0000000044157b0 pr  : 000000000001015b
ldrs: 0000000000000000 ccv : 0000000000000000 fpsr: 0009804c0270033f
b0  : e000000004415ce0 b6  : e000000004402f60 b7  : e0000000044157b0
f6  : 1003e0000000000000020 f7  : 1003e0000000000000010
f8  : 1003e0000000000000006 f9  : 10002a000000000000000
r1  : e000000004a12b20 r2  : 0000000000000000 r3  : 00000000000000ff
r8  : e00000002facff00 r9  : 0000000000000000 r10 : ffffffffffffffff
r11 : 600000000000c3b8 r12 : e00000002facfe60 r13 : e00000002fac8000
r14 : e000000000000000 r15 : e000000004415ce0 r16 : e00000002facfe70
r17 : e00000002facfe78 r18 : 00001013080a6010 r19 : 20000000001e1bb0
r20 : 0000000000000000 r21 : 4000000000000e98 r22 : 600000000005ec20
r23 : 600000000005ed28 r24 : 0000000000005540 r25 : 2000000000293f90
r26 : 600000000005ed28 r27 : 0000000000000000 r28 : 0000000000000040
r29 : 0000000000000000 r30 : 0000000000000008 r31 : 0000000000000000
r32 : 0000000000000000 r33 : 0000000000000000 r34 : 0000000000000000
r35 : 0000000000000000 r36 : 0000000000000000 r37 : 0000000000000000
r38 : 0000000000000000 r39 : 0000000000000000

Call Trace: [<e00000000441a080>] sp=0xe00000002facfa50 bsp=0xe00000002fac8ec8
[<e00000000441a840>] sp=0xe00000002facfc10 bsp=0xe00000002fac8e70
[<e00000000442b830>] sp=0xe00000002facfc30 bsp=0xe00000002fac8e48
[<e00000000442bb00>] sp=0xe00000002facfc30 bsp=0xe00000002fac8e28
[<e000000004415d00>] sp=0xe00000002facfcc0 bsp=0xe00000002fac8e28
[<a0000000000344b0>] sp=0xe00000002facfe60 bsp=0xe00000002fac8de0
[<e000000004415ce0>] sp=0xe00000002facfe60 bsp=0xe00000002fac8dd8

what am i doing wrong or cant i do this?

/* mysyscall.c 
  
% cc -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -ffixed-r13 -mfixed-rangeñ0-f15,f32-f127 -falign-functions2 -mb-step -D__KERNEL__ -DKERNEL -D_KERNEL -DMODULE -c mysyscall.c

*/

#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/init.h>
#include <sys/syscall.h>

extern long sys_call_table[];
static long saved_syscall;

asmlinkage long 
afs_syscall(long arg0, long arg1, long arg2, long arg3,
          long arg4, long arg5, long arg6, long arg7, long stack)
{
        struct pt_regs *regs = (struct pt_regs *) &stack;
	
	printk("afs_syscall()\n");

	return 0;
}

int __init
mysyscall_init(void)
{
	printk("hello world\n");
	saved_syscall = sys_call_table[__NR_afs_syscall - 1024];
	sys_call_table[__NR_afs_syscall - 1024] = (long) afs_syscall;
	return 0;
}

void __exit
mysyscall_exit(void)
{
	printk("goodbye cruel world\n");
	sys_call_table[__NR_afs_syscall - 1024] = saved_syscall;
}

module_init(mysyscall_init);
module_exit(mysyscall_exit);



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
  2001-07-03 20:03 ` chas williams
@ 2001-07-03 20:44 ` Don Dugger
  2001-07-03 20:53 ` chas williams
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Don Dugger @ 2001-07-03 20:44 UTC (permalink / raw)
  To: linux-ia64

Chas-

Your problem is that, in IA64, a pointer to a function does not point
directly to the function itself.  Instead it points to a data structure
where the first element truly points to the function and the second
element contains the GP value for the function.

Changing your code to something like:

  int __init
  mysyscall_init(void)
  {
        struct foo {
            long addr;
            long gp;
        } fp;

        printk("hello world\n");
        saved_syscall = sys_call_table[__NR_afs_syscall - 1024];
        fp = (struct foo *)afs_syscall;
        sys_call_table[__NR_afs_syscall - 1024] = fp->addr;
        return 0;
  }

should accomplish what you want.  (I think there are some magic C
macros that will break a function pointer into it's component pieces
but I don't know what they are, I just do it the hard way :-)

On Tue, Jul 03, 2001 at 04:03:23PM -0400, chas williams wrote:
> i wrote a little example to illustrate my problem.  its attached at the
> bottom.  if i make a syscall(__NR_afs_syscall, ...) i get the following:
> 
> pts[2437]: Bad break 104
> 
> psr : 0000101008026018 ifs : 8000000000000008 ip  : [<a0000000000344b0>]
> unat: 0000000000000000 pfs : 0000000000000089 rsc : 0000000000000003
> rnat: 40000000000bb190 bsps: e0000000044157b0 pr  : 000000000001015b
> ldrs: 0000000000000000 ccv : 0000000000000000 fpsr: 0009804c0270033f
> b0  : e000000004415ce0 b6  : e000000004402f60 b7  : e0000000044157b0
> f6  : 1003e0000000000000020 f7  : 1003e0000000000000010
> f8  : 1003e0000000000000006 f9  : 10002a000000000000000
> r1  : e000000004a12b20 r2  : 0000000000000000 r3  : 00000000000000ff
> r8  : e00000002facff00 r9  : 0000000000000000 r10 : ffffffffffffffff
> r11 : 600000000000c3b8 r12 : e00000002facfe60 r13 : e00000002fac8000
> r14 : e000000000000000 r15 : e000000004415ce0 r16 : e00000002facfe70
> r17 : e00000002facfe78 r18 : 00001013080a6010 r19 : 20000000001e1bb0
> r20 : 0000000000000000 r21 : 4000000000000e98 r22 : 600000000005ec20
> r23 : 600000000005ed28 r24 : 0000000000005540 r25 : 2000000000293f90
> r26 : 600000000005ed28 r27 : 0000000000000000 r28 : 0000000000000040
> r29 : 0000000000000000 r30 : 0000000000000008 r31 : 0000000000000000
> r32 : 0000000000000000 r33 : 0000000000000000 r34 : 0000000000000000
> r35 : 0000000000000000 r36 : 0000000000000000 r37 : 0000000000000000
> r38 : 0000000000000000 r39 : 0000000000000000
> 
> Call Trace: [<e00000000441a080>] sp=0xe00000002facfa50 bsp=0xe00000002fac8ec8
> [<e00000000441a840>] sp=0xe00000002facfc10 bsp=0xe00000002fac8e70
> [<e00000000442b830>] sp=0xe00000002facfc30 bsp=0xe00000002fac8e48
> [<e00000000442bb00>] sp=0xe00000002facfc30 bsp=0xe00000002fac8e28
> [<e000000004415d00>] sp=0xe00000002facfcc0 bsp=0xe00000002fac8e28
> [<a0000000000344b0>] sp=0xe00000002facfe60 bsp=0xe00000002fac8de0
> [<e000000004415ce0>] sp=0xe00000002facfe60 bsp=0xe00000002fac8dd8
> 
> what am i doing wrong or cant i do this?
> 
> /* mysyscall.c 
>   
> % cc -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -ffixed-r13 -mfixed-rangeñ0-f15,f32-f127 -falign-functions2 -mb-step -D__KERNEL__ -DKERNEL -D_KERNEL -DMODULE -c mysyscall.c
> 
> */
> 
> #include <linux/config.h>
> #include <linux/module.h>
> #include <linux/version.h>
> #include <linux/kernel.h>
> #include <linux/errno.h>
> #include <linux/types.h>
> #include <linux/string.h>
> #include <linux/init.h>
> #include <sys/syscall.h>
> 
> extern long sys_call_table[];
> static long saved_syscall;
> 
> asmlinkage long 
> afs_syscall(long arg0, long arg1, long arg2, long arg3,
>           long arg4, long arg5, long arg6, long arg7, long stack)
> {
>         struct pt_regs *regs = (struct pt_regs *) &stack;
> 	
> 	printk("afs_syscall()\n");
> 
> 	return 0;
> }
> 
> int __init
> mysyscall_init(void)
> {
> 	printk("hello world\n");
> 	saved_syscall = sys_call_table[__NR_afs_syscall - 1024];
> 	sys_call_table[__NR_afs_syscall - 1024] = (long) afs_syscall;
> 	return 0;
> }
> 
> void __exit
> mysyscall_exit(void)
> {
> 	printk("goodbye cruel world\n");
> 	sys_call_table[__NR_afs_syscall - 1024] = saved_syscall;
> }
> 
> module_init(mysyscall_init);
> module_exit(mysyscall_exit);
> 
> 
> _______________________________________________
> Linux-IA64 mailing list
> Linux-IA64@linuxia64.org
> http://lists.linuxia64.org/lists/listinfo/linux-ia64

-- 
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
n0ano@valinux.com
Ph: 303/938-9838


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
  2001-07-03 20:03 ` chas williams
  2001-07-03 20:44 ` Don Dugger
@ 2001-07-03 20:53 ` chas williams
  2001-07-03 21:04 ` chas williams
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: chas williams @ 2001-07-03 20:53 UTC (permalink / raw)
  To: linux-ia64

>where the first element truly points to the function and the second
>element contains the GP value for the function.

ok. i see. so i can now set the syscall table to the 'real' location
for the afs_syscall routine.  however, i still run into trouble
when invoking the syscall:

>>IP;  a000000000034250 <[mysyscall].text.end+11/31>   <==>>b0;  a0000000000340e0 <[mysyscall].text.start+20/40>
>>b6;  e000000004402f60 <demine_args+0/a0>
>>b7;  e0000000044157b0 <ia64_switch_to+b0/120>
Trace; e00000000441a080 <show_stack+40/c0>
Trace; e00000000441a840 <show_regs+740/780>
Trace; e00000000442b830 <die_if_kernel+70/140>
Trace; e000000004443fc0 <ia64_do_page_fault+760/800>
Trace; e000000004415d00 <ia64_leave_kernel+0/2a0>
Trace; a000000000034250 <[mysyscall].text.end+11/31>
Trace; a0000000000340e0 <[mysyscall].text.start+20/40>
Trace; a0000000000340e0 <[mysyscall].text.start+20/40>

i suspect that my afs_syscall() is trying to use the 'gp' which is
probably not setup?


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
                   ` (2 preceding siblings ...)
  2001-07-03 20:53 ` chas williams
@ 2001-07-03 21:04 ` chas williams
  2001-07-03 21:16 ` Don Dugger
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: chas williams @ 2001-07-03 21:04 UTC (permalink / raw)
  To: linux-ia64

>`-mconstant-gp' which I didn't see in your flags list.  In general,
>you must compile your modules with the same flags that were

that's a problem.  modules cant be compiled with -mconstant-gp apparently.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
                   ` (3 preceding siblings ...)
  2001-07-03 21:04 ` chas williams
@ 2001-07-03 21:16 ` Don Dugger
  2001-07-03 21:22 ` Don Dugger
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Don Dugger @ 2001-07-03 21:16 UTC (permalink / raw)
  To: linux-ia64

Chas-

Looking back at your last message I think you are compiling your
module with the wrong flags.  My kernel uses the flag
`-mconstant-gp' which I didn't see in your flags list.  In general,
you must compile your modules with the same flags that were
used to compile the kernel.

On Tue, Jul 03, 2001 at 04:53:56PM -0400, chas williams wrote:
> >where the first element truly points to the function and the second
> >element contains the GP value for the function.
> 
> ok. i see. so i can now set the syscall table to the 'real' location
> for the afs_syscall routine.  however, i still run into trouble
> when invoking the syscall:
> 
> >>IP;  a000000000034250 <[mysyscall].text.end+11/31>   <==> >>b0;  a0000000000340e0 <[mysyscall].text.start+20/40>
> >>b6;  e000000004402f60 <demine_args+0/a0>
> >>b7;  e0000000044157b0 <ia64_switch_to+b0/120>
> Trace; e00000000441a080 <show_stack+40/c0>
> Trace; e00000000441a840 <show_regs+740/780>
> Trace; e00000000442b830 <die_if_kernel+70/140>
> Trace; e000000004443fc0 <ia64_do_page_fault+760/800>
> Trace; e000000004415d00 <ia64_leave_kernel+0/2a0>
> Trace; a000000000034250 <[mysyscall].text.end+11/31>
> Trace; a0000000000340e0 <[mysyscall].text.start+20/40>
> Trace; a0000000000340e0 <[mysyscall].text.start+20/40>
> 
> i suspect that my afs_syscall() is trying to use the 'gp' which is
> probably not setup?
> 
> _______________________________________________
> Linux-IA64 mailing list
> Linux-IA64@linuxia64.org
> http://lists.linuxia64.org/lists/listinfo/linux-ia64

-- 
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
n0ano@valinux.com
Ph: 303/938-9838


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
                   ` (4 preceding siblings ...)
  2001-07-03 21:16 ` Don Dugger
@ 2001-07-03 21:22 ` Don Dugger
  2001-07-03 22:58 ` Luck, Tony
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Don Dugger @ 2001-07-03 21:22 UTC (permalink / raw)
  To: linux-ia64

Uh, maybe you should ignore my last message.  I don't use modules
so I'm really shouldn't try to debug them.

On Tue, Jul 03, 2001 at 05:04:29PM -0400, chas williams wrote:
> >`-mconstant-gp' which I didn't see in your flags list.  In general,
> >you must compile your modules with the same flags that were
> 
> that's a problem.  modules cant be compiled with -mconstant-gp apparently.

-- 
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
n0ano@valinux.com
Ph: 303/938-9838


^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
                   ` (5 preceding siblings ...)
  2001-07-03 21:22 ` Don Dugger
@ 2001-07-03 22:58 ` Luck, Tony
  2001-07-04 15:31 ` chas williams
  2001-07-04 21:34 ` Chas Williams
  8 siblings, 0 replies; 10+ messages in thread
From: Luck, Tony @ 2001-07-03 22:58 UTC (permalink / raw)
  To: linux-ia64

It looks like you can't do this easily right now.  As others
have pointed out, on IA64 a pointer to a function is actually
a pointer to a two element structure that contains the actual
function address, and the gp value to use for that function.

However, sys_call_table in the kernel is not currently implemented
as a real "array of pointers to functions" ... it is simply an
array of function addresses ... and the code in ivt.S that makes
the branch through the pointer when a user invokes a system call
knows this.  So the ivt.S code just leaves "gp" unchanged ... which
works for all system calls that are staticly linked into the kernel,
but means that system calls in modules are in trouble as they will
be invoked with the kernel "gp" instead of their own, and they will
fault as soon as they try to access any data objects that belong to
the module.

You might be able to workaround this for now by providing a stub
function in your module that sets "gp" and calls your real function.

Probably the real fix would be to change sys_call_table and ivt.S to
make them follow the usual ia64 conventions for pointers to functions.


-Tony Luck

-----Original Message-----
From: chas williams [mailto:chas@cmf.nrl.navy.mil]
Sent: Tuesday, July 03, 2001 6:46 AM
To: linux-ia64@linuxia64.org
Subject: [Linux-ia64] patching sys_call_table from a module



afs patches the sys_call_table to provide support for various functions.
the existing doesnt seem to work right.  i figured out that the ia64
calls are offset by 1024.  but know i have a different problem:




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
                   ` (6 preceding siblings ...)
  2001-07-03 22:58 ` Luck, Tony
@ 2001-07-04 15:31 ` chas williams
  2001-07-04 21:34 ` Chas Williams
  8 siblings, 0 replies; 10+ messages in thread
From: chas williams @ 2001-07-04 15:31 UTC (permalink / raw)
  To: linux-ia64

>You might be able to workaround this for now by providing a stub
>function in your module that sets "gp" and calls your real function.

this seems the best idea at the moment.  only one problem.  i really
dont know ia64 assembly.  i managed to write a little function that
just returns and patching the syscall entry with that doesnt crash.
that's about the extent of my ability.  i would guess that when
module functions are called from the kernel that a small stub
routine that preserves the kernel's gp and sets up the function's gp
is called first?  perhaps i could look at this code for some help?
or if someone on this list would be kind enough...


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Linux-ia64] patching sys_call_table from a module
  2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
                   ` (7 preceding siblings ...)
  2001-07-04 15:31 ` chas williams
@ 2001-07-04 21:34 ` Chas Williams
  8 siblings, 0 replies; 10+ messages in thread
From: Chas Williams @ 2001-07-04 21:34 UTC (permalink / raw)
  To: linux-ia64

>You might be able to workaround this for now by providing a stub
>function in your module that sets "gp" and calls your real function.

i took at look at the what the modutil did when loading kernel modules.
the following stub seems to work with one small problem:

GLOBAL_ENTRY(afs_syscall_stub)
      mov r8=-1

      movl r15=0xa000000000034610 /* afs_syscall */;;
      ld8 r16=[r15],8
      mov r14=gp;;
      ld8 gp=[r15]
      mov b6=r16
      br.few b6;;
END(afs_syscall_stub)

0xa000000000034610 is the descriptor for afs_syscall.  if i use
movl r15,afs_syscall;; instead, insmod fails to load the module:

insmod: obj_ia64.c:258: obj_ia64_ins_imm64: Assertion `slot = 1' failed.

i guess i dont know afs_syscall until the module is actually loaded?


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2001-07-04 21:34 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-07-03 13:45 [Linux-ia64] patching sys_call_table from a module chas williams
2001-07-03 20:03 ` chas williams
2001-07-03 20:44 ` Don Dugger
2001-07-03 20:53 ` chas williams
2001-07-03 21:04 ` chas williams
2001-07-03 21:16 ` Don Dugger
2001-07-03 21:22 ` Don Dugger
2001-07-03 22:58 ` Luck, Tony
2001-07-04 15:31 ` chas williams
2001-07-04 21:34 ` Chas Williams

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox