Page 2 of 2
Re:Return Value from Syscall
Posted: Thu May 27, 2004 10:05 am
by amirsadig
I have put at the beginning and end of syscall kprintf to see the system call number and return value which I have stored in regs->eax. And it display at the beginning the correct number for system call function and at the end it print the correct retun value.
here is the code :
Code: Select all
void syscall(regs_t *regs)
{
kprintf("system call function number %d ", regs->eax);
disable();
__asm__ __volatile__(
"mov %1, %%ebx;"
"mov %2, %%ecx;"
"pushl %%ecx ;"
"pushl %%ebx ;"
"call *sys_call_table(,%3, 4) ;"
"popl %%ebx;"
"popl %%ecx; "
:"=a" (regs->eax):"r"(regs->ebx), "r"(regs->ecx), "r" (regs->eax)
);
kprintf(" return value = %d", regs->eax);
enable();
}
but return value to task I receive always the system call number ( like at the beginning of isr syscall).
regs should normaly store registers value as I call the int 0x80, but as I modify regs in the syscall (exaclty EAX), why I receive the same value?
Re:Return Value from Syscall
Posted: Thu May 27, 2004 12:54 pm
by BI lazy
Hm ...
Have you tried to print a register dump of your task before and after execution of syscall?
debugging such a thing a bit awful ...
can you get hands on bochs and make a debug run with hlt instruction before and after call to syscall? I'd like to see/read, what the bochs debugger says after issueing a dump-cpu command?
Re:Return Value from Syscall
Posted: Thu May 27, 2004 2:38 pm
by amirsadig
note that syscall will be called from an isr as I mention earlier.
that mean when we return from syscall we still in isr.
here is before the syscall call the sys_read function
Code: Select all
eax 0x3 3
ecx 0x1 1
edx 0x1 1
ebx 0x10009fc7 268476359
esp 0x10009f28 0x10009f28
ebp 0x10009f44 0x10009f44
esi 0x108646 1082950
edi 0x108660 1082976
eip 0x104979 0x104979
eflags 0x6 6
cs 0x18 24
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x10 16
gs 0x10 16
this when return from sys_read ( we still in syscall handler)
Code: Select all
eax 0xffffffff -1
ecx 0x10000ec0 268439232
edx 0xffffffff -1
ebx 0x10009fc7 268476359
esp 0x10009f24 0x10009f24
ebp 0x10009f44 0x10009f44
esi 0x108646 1082950
edi 0x108660 1082976
eip 0x104981 0x104981
eflags 0x46 70
cs 0x18 24
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x10 16
gs 0x10 16
here is direct after return from syscall to ISR
Code: Select all
eax 0xffffffff -1
ecx 0x10000ec0 268439232
edx 0xffffffff -1
ebx 0x10009fc7 268476359
esp 0x10009f24 0x10009f24
ebp 0x10009f44 0x10009f44
esi 0x108646 1082950
edi 0x108660 1082976
eip 0x104981 0x104981
eflags 0x46 70
cs 0x18 24
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x10 16
gs 0x10 16
now come the error which i don't now why( EAX is still 3 as before entering syscall, but I have change the value of regs->eax!!!). if someone can exract it from such regist value, I will be glad.
Code: Select all
eax 0x3 3
ecx 0x1 1
edx 0x10009000 268472320
ebx 0x10009fc7 268476359
esp 0x10009f70 0x10009f70
ebp 0x10009f98 0x10009f98
esi 0x108646 1082950
edi 0x108660 1082976
eip 0x10009e 0x10009e
eflags 0x246 582
cs 0x18 24
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x10 16
gs 0x10 16
Re:Return Value from Syscall
Posted: Thu May 27, 2004 11:25 pm
by virusx
wait a sec,
"call *sys_call_table(,%3, 4) ;"
does this handler has return statement.
int sys_write()
{
......
return state;
}
The return statements usually puts the value in eax.
Try that.
regards
Re:Return Value from Syscall
Posted: Fri May 28, 2004 12:26 am
by distantvoices
now, pls dump the values of esp before and after call to syscall. Not what happens inside syscall. this seems to be plain correct for you get your return code as you wish.
what I mean is: the position of esp before these instructions:
mov eax,esp
push eax.
and then the position of esp *after* the call to syscall and after this instruction:
pop eax - in your isr epilogue - all_ints.
And inside syscall, pls dump the value of regs. Maybe comparison of these three values reveals something?
Re:Return Value from Syscall
Posted: Fri May 28, 2004 8:00 am
by amirsadig
what I mean is: the position of esp before these instructions:
mov eax,esp
push eax.
here is the dump for register and the value at which stack pointed before "mov eax, esp"
Code: Select all
eax 0x10 16
ecx 0x1 1
edx 0x108c91 1084561
ebx 0x10009fd7 268476375
esp 0x10009f60 0x10009f60
ebp 0x10009fa8 0x10009fa8
esi 0x108c91 1084561
edi 0x0 0
eip 0x101439 0x101439
eflags 0x7 7
cs 0x18 24
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x10 16
gs 0x10 16
<bochs:17> x /9dw 0x10009f60
[bochs]:
0x10009f60 <bogus+ 0>: 0 1084561 268476328 268476288
0x10009f70 <bogus+ 16>: 268476375 1084561 1 3
0x10009f80 <bogus+ 32>: 16
the value at stack is regs struct which syscall uses it later and you see the 8 value (eax is 3 - sys_read number) is correct.
the dumb for registers at all_int you find in my last reply third code. but I put also here again.
Code: Select all
(0) [0x0010009c] 0018:0010009c (unk. ctxt): pop eax ; 5
<bochs:20> info registers
eax 0xffffffff -1
ecx 0x1 1
edx 0xffffffff -1
ebx 0x10009fd7 268476375
esp 0x10009f5c 0x10009f5c
ebp 0x10009fa8 0x10009fa8
esi 0x108c91 1084561
edi 0x0 0
eip 0x10009c 0x10009c
eflags 0x242 578
cs 0x18 24
ss 0x10 16
ds 0x10 16
es 0x10 16
fs 0x10 16
gs 0x10 16
<bochs:21> x /9dw 0x10009f5c
[bochs]:
0x10009f5c <bogus+ 0>: 268476256 0 1084561 268476328
0x10009f6c <bogus+ 16>: 268476288 268476375 1084561 1
0x10009f7c <bogus+ 32>: 3
note that is before push eax and pusha instructions.
hi all this not a private talk beween me and "beyond infinity"
.
I thank all for their answer. I improve always my Assembly knowledge with debugging my kernel and your question and answer.
Re:Return Value from Syscall
Posted: Fri May 28, 2004 8:53 am
by amirsadig
as I have take a look at the assemly code to syscall. I have notice some mistake (my be in my code or compiler-asm code). tell me if I WRONG.
Code: Select all
0010495c <syscall>:
10495c: 55 push %ebp
10495d: 89 e5 mov %esp,%ebp
10495f: 83 ec 14 sub $0x14,%esp
104962: 53 push %ebx
104963: 8b 5d 08 mov 0x8(%ebp),%ebx
104966: e8 85 39 00 00 call 1082f0 <disable>
10496b: 8b 4b 10 mov 0x10(%ebx),%ecx
10496e: 8b 53 18 mov 0x18(%ebx),%edx
104971: 8b 43 1c mov 0x1c(%ebx),%eax
104974: 89 cb mov %ecx,%ebx
104976: 89 d1 mov %edx,%ecx
104978: 51 push %ecx
104979: 53 push %ebx
10497a: ff 14 85 40 b8 10 00 call *0x10b840(,%eax,4)
104981: 5b pop %ebx
104982: 59 pop %ecx
104983: 89 43 1c mov %eax,0x1c(%ebx)
104986: e8 75 39 00 00 call 108300 <enable>
10498b: 5b pop %ebx
10498c: c9 leave
10498d: c3 ret
* gcc use EBX to as placehalter for regs and mov value to ecx and eax and ebx in instructions "10496b -> 104971"
* then it change the value of ebx ( !!) at 104974. that mean the ebx not point now to regs.
* when return from sys_read it save the return in 0x1c(%ebx), which not point regs now.
there for the eax value in regs struct have not been change. thus i receive the old value eax before call syscall.
the c-code for syscall you can find it here in this thread.
please correct me if I am wrong in my analysis !
Re:Return Value from Syscall
Posted: Fri May 28, 2004 9:27 am
by amirsadig
now I have fix the problem.
in syscall i have clobbered ebx register like ,
Code: Select all
:"=a" (regs->eax):"r"(regs->ebx), "r"(regs->ecx), "r" (regs->eax):"ebx"
that mean gcc will not use this register to store any value, because it asm inline use it.
without you help and the debugger, it could take along time to solve.
thanks everyone
Re:Return Value from Syscall
Posted: Sat May 29, 2004 6:45 am
by distantvoices
Well done, gosh.
See: the smallest bugs have always the biggest effects.
Have a nice elongated weekend
btw, I didn't do so much as asking questions and peeking around.
stay safe