* [TUHS] link() syscall implementation
@ 2015-11-14 12:34 Oliver Lehmann
2015-11-14 12:56 ` Oliver Lehmann
2015-11-14 13:33 ` Random832
0 siblings, 2 replies; 8+ messages in thread
From: Oliver Lehmann @ 2015-11-14 12:34 UTC (permalink / raw)
Hi,
I'm struggling on reimplementing the C code for the link()
syscall.
Usually on SYSIII and V7 you have something like:
link()
{
register struct inode *ip, *xp;
register struct a {
char *target;
char *linkname;
} *uap;
[...]
u.u_dirp = (caddr_t)uap->linkname;
[...]
}
The problem now on my system is, u_dirp in the user struct
is saddr_t (*long) and not caddr_t (*char) and I wonder how
I have to assign uap->linkname.
The original ASM code looks like:
_link::
{
dec fp,#~L2
ldm _stkseg+4(fp),r8,#6
ldl rr8,_u+36
[...]
ldl rr2,rr8(#4)
ldl rr4,rr2
and r4,#32512
ldl _u+78,rr4
[...]
I had the same problem already 7 years ago but didn't came up
with a solution back then.
http://home.salatschuessel.net/quest/problems.php
What came to my mind in the meantime is the following and maybe
someone can check if this is right:
1. _u+78 (u.u_dirp) contains a pointer - so what is assigned
here in ASM is a memory address.
2. The memory notation for accessing segmented data on Z8001
seems to be 0xSS00XXXX where SS is the segment number up
to 127 and XXXX is the relative address in that segment.
3. This means ANDing 0xSS00 with 0x7F00 means to strip out
all invalid data from the segment-position of the address,
to make sure it can only be between 0 and 127 (0x0000 and
0x7F00).
I wonder how the assignment of uap->linkname to u.u_dirp has
to be done correctly?!
^ permalink raw reply [flat|nested] 8+ messages in thread
* [TUHS] link() syscall implementation
2015-11-14 12:34 [TUHS] link() syscall implementation Oliver Lehmann
@ 2015-11-14 12:56 ` Oliver Lehmann
2015-11-14 15:17 ` Oliver Lehmann
2015-11-14 13:33 ` Random832
1 sibling, 1 reply; 8+ messages in thread
From: Oliver Lehmann @ 2015-11-14 12:56 UTC (permalink / raw)
Oliver Lehmann <lehmann at ans-netz.de> wrote:
> The problem now on my system is, u_dirp in the user struct
> is saddr_t (*long) and not caddr_t (*char) and I wonder how
^^^^^^^^^^^^^^^
must read saddr_t (long)
typedef union
{
caddr_t l;
struct
{
unsigned left;
unsigned right;
} half;
} saddr_t; /* segmented address with parts */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [TUHS] link() syscall implementation
2015-11-14 12:34 [TUHS] link() syscall implementation Oliver Lehmann
2015-11-14 12:56 ` Oliver Lehmann
@ 2015-11-14 13:33 ` Random832
1 sibling, 0 replies; 8+ messages in thread
From: Random832 @ 2015-11-14 13:33 UTC (permalink / raw)
Oliver Lehmann <lehmann at ans-netz.de> writes:
> The problem now on my system is, u_dirp in the user struct
> is saddr_t (*long) and not caddr_t (*char) and I wonder how
> I have to assign uap->linkname.
> I wonder how the assignment of uap->linkname to u.u_dirp has
> to be done correctly?!
Isn't uap->linkname also a pointer? Or does your system have near and
far pointers?
^ permalink raw reply [flat|nested] 8+ messages in thread
* [TUHS] link() syscall implementation
2015-11-14 12:56 ` Oliver Lehmann
@ 2015-11-14 15:17 ` Oliver Lehmann
2015-11-14 21:18 ` Random832
0 siblings, 1 reply; 8+ messages in thread
From: Oliver Lehmann @ 2015-11-14 15:17 UTC (permalink / raw)
I've now implemented this:
u.u_dirp.left = hiword(uap->linkname) & 0x7f00;
u.u_dirp.right = loword(uap->linkname);
while hiword and loword being defined in my param.h like this:
# define loword(X) (((unsigned short *)&X)[sizeof(X) - \
(sizeof(unsigned short)+1)])
# define hiword(X) (((unsigned short *)&X)[0])
This results in:
ld r2,rr8(#4)
and r2,#32512
ld _u+78,r2
ld r2,rr8(#6)
ld _u+80,r2
versus
ldl rr2,rr8(#4)
ldl rr4,rr2
and r4,#32512
ldl _u+78,rr4
does the same but with more instructions and of course not 1:1
binary "the same" ;)
wonder why
u.u_dirp.l = (caddr_t)(((long)uap->linkname) & 0x7F00FFFF);
didn't worked.
At least link() is now working again (before the fix it was only
working when the file to be linked is in the working directory)
#1 ls -i /z/tmp/
2487 hugo 2486 walter
#2 rm /z/tmp/walter
#3 ln /z/tmp/hugo /z/tmp/walter
#4 !1
ls -i /z/tmp/
2487 hugo 2487 walter
#5 ln /z/tmp/hugo /z/walter
#6 ls -i /z/tmp/hugo /z/walter
2487 /z/tmp/hugo 2487 /z/walter
#7
^ permalink raw reply [flat|nested] 8+ messages in thread
* [TUHS] link() syscall implementation
2015-11-14 15:17 ` Oliver Lehmann
@ 2015-11-14 21:18 ` Random832
2015-11-14 21:42 ` Oliver Lehmann
0 siblings, 1 reply; 8+ messages in thread
From: Random832 @ 2015-11-14 21:18 UTC (permalink / raw)
Oliver Lehmann <lehmann at ans-netz.de> writes:
> ldl rr2,rr8(#4)
> ldl rr4,rr2
> and r4,#32512
> ldl _u+78,rr4
This looks like it could be:
u.u_dirp.l = uap->linkname;
u.u_dirp.left &= 0x7f00;
>
> does the same but with more instructions and of course not 1:1
> binary "the same" ;)
> wonder why
> u.u_dirp.l = (caddr_t)(((long)uap->linkname) & 0x7F00FFFF);
> didn't worked.
Well, what code did it generate? Are longs in the same byte order as
pointers (could it have needed to be FFFF7F00)?
^ permalink raw reply [flat|nested] 8+ messages in thread
* [TUHS] link() syscall implementation
2015-11-14 21:18 ` Random832
@ 2015-11-14 21:42 ` Oliver Lehmann
2015-11-14 23:07 ` Random832
0 siblings, 1 reply; 8+ messages in thread
From: Oliver Lehmann @ 2015-11-14 21:42 UTC (permalink / raw)
Random832 <random832 at fastmail.com> wrote:
> Oliver Lehmann <lehmann at ans-netz.de> writes:
>> ldl rr2,rr8(#4)
>> ldl rr4,rr2
>> and r4,#32512
>> ldl _u+78,rr4
>
> This looks like it could be:
> u.u_dirp.l = uap->linkname;
> u.u_dirp.left &= 0x7f00;
Good guess, but the optimizer didn't optimized this "away" so this
generates literally what is done in C:
ldl rr2,rr8(#4)
ldl _u+78,rr2
ld r2,_u+78
and r2,#32512
ld _u+78,r2
>
>>
>> does the same but with more instructions and of course not 1:1
>> binary "the same" ;)
>> wonder why
>> u.u_dirp.l = (caddr_t)(((long)uap->linkname) & 0x7F00FFFF);
>> didn't worked.
>
> Well, what code did it generate? Are longs in the same byte order as
> pointers (could it have needed to be FFFF7F00)?
Should be the same byte order, yes. It generates:
0530 3582 0004 584 ldl rr2,rr8(#4)
0536 0702 7f00 and r2,#32512
04d2 5d02 8000* 585 ldl _u+78,rr2
04d6 004e*
OK - it is not temporarily copied to rr4, but directly modfied in
rr2 and then assigned to u.u_dirp. It should be "the same" - But
- ln(1) does not work with this code. Instead of creating a
hardlink, it creates a new empty file (different inode).
And to be honest - who would write such a code in the first place
u.u_dirp.l = (caddr_t)(((long)uap->linkname) & 0x7F00FFFF);
Feels to crazy for me as someone would really write such a code.
There are so many "better" way (readability) someone would come
up with than this.... I/We just didn't figured out the better
way yet ;)
Another possibility could be, that the sys2.o was generated with
an earlier version if the assembler and not recompiled with the
"newer"/shipped one and that it might be impossible to generate
this code now. But all sccs tags in the assembler are before the
sccs tag in sys2.o....
Regards, Oliver
^ permalink raw reply [flat|nested] 8+ messages in thread
* [TUHS] link() syscall implementation
2015-11-14 21:42 ` Oliver Lehmann
@ 2015-11-14 23:07 ` Random832
2015-11-15 14:43 ` Oliver Lehmann
0 siblings, 1 reply; 8+ messages in thread
From: Random832 @ 2015-11-14 23:07 UTC (permalink / raw)
Oliver Lehmann <lehmann at ans-netz.de> writes:
> OK - it is not temporarily copied to rr4, but directly modfied in
> rr2 and then assigned to u.u_dirp. It should be "the same" - But
> - ln(1) does not work with this code. Instead of creating a
> hardlink, it creates a new empty file (different inode).
Are you sure this is where the problem is?
For the pointer assignment, what about just using u.u_dirp.l =
uap->linkname, and validating there are no invalid bits (return EFAULT
or raise SIGSEGV if so - also should the user code really be allowed to
pass in arbitrary segment IDs?) in a separate step?
^ permalink raw reply [flat|nested] 8+ messages in thread
* [TUHS] link() syscall implementation
2015-11-14 23:07 ` Random832
@ 2015-11-15 14:43 ` Oliver Lehmann
0 siblings, 0 replies; 8+ messages in thread
From: Oliver Lehmann @ 2015-11-15 14:43 UTC (permalink / raw)
Random832 <random832 at fastmail.com> wrote:
> Oliver Lehmann <lehmann at ans-netz.de> writes:
>> OK - it is not temporarily copied to rr4, but directly modfied in
>> rr2 and then assigned to u.u_dirp. It should be "the same" - But
>> - ln(1) does not work with this code. Instead of creating a
>> hardlink, it creates a new empty file (different inode).
>
> Are you sure this is where the problem is?
Not any longer - I tried it again with
u.u_dirp.l = (caddr_t)(((long)uap->linkname) & 0x7F00FFFF);
and it seems to work now - no idea what went wrong the last time
I tried it.
#1 rm /z/tmp/*
#2 echo "test" > /z/tmp/hugo
#3 ln /z/tmp/hugo /z/tmp/walter
ls#4 -li /z/tmp
total 2
2452 -rw-rw-rw- 2 wega system 5 Nov 15 02:44 hugo
2452 -rw-rw-rw- 2 wega system 5 Nov 15 02:44 walter
#5
I still have direct modification of rr2 and not the copy to rr4,
so if I would aim for binary equalness it is still not the same,
but it seems that it can't be done another way.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-11-15 14:43 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-14 12:34 [TUHS] link() syscall implementation Oliver Lehmann
2015-11-14 12:56 ` Oliver Lehmann
2015-11-14 15:17 ` Oliver Lehmann
2015-11-14 21:18 ` Random832
2015-11-14 21:42 ` Oliver Lehmann
2015-11-14 23:07 ` Random832
2015-11-15 14:43 ` Oliver Lehmann
2015-11-14 13:33 ` Random832
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).