The Unix Heritage Society mailing list
 help / color / mirror / Atom feed
* [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).