Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Oct 1995 16:12:09 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, terry@lambert.org
Cc:        CVS-commiters@freefall.freebsd.org, bde@freefall.freebsd.org, cvs-sys@freefall.freebsd.org, hackers@freebsd.org, swallace@ece.uci.edu
Subject:   Re: SYSCALL IDEAS [Was: cvs commit: src/sys/kern sysv_msg.c sysv_sem.c sysv_shm.c]
Message-ID:  <199510280612.QAA16949@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> >I don't understand why passing a bogus mode to open when O_CREAT wasn't
>> >present would be a problem???
>...
>Hence, my use of the 0 argument on the open in user space in the last
>posting to provide a valid call on vararg.  The open(2) call is not

The difficulty is to extract the 3rd arg if it exists.

>a traditional vararg -- it's a limited one.  The "..." in its case
>means "0 or one argument here" instead of "0 or n arguments here".

This only reduces the difficulty.  In general you might have to decode
all previous args to decide how to extract eacg arg.

>I don't know of a real vararg system call.

Grepping for \.\.\. in <sys/*.h> shows the following: open, fcntl, ioctl,
msgsys, semsys, shmsys.  The last 3 have more than one varargs arg.

>> >> SYSCALL_ENTRY(open)
>> >> {
>> >>     ARG( char const *,	PATH);
>> >>     ARG( int,			FLAGS);
>> >>     ARG( promoted_mode_t,	MODE);
>> >>
>> >>     return open(p, retval, PATH, FLAGS, MODE);
>> >> }
>> 
>> This would require large table of #defines of OFFSETs.  I prefer to use
>> literal offsets.

>Keep all paths at the same offset, etc.

You can't.  The offsets depend on the ABI.  In particular they depend on
the word size and endianness even if the packing is the natural one.

>Actually, MSC doesn't align stuff correctly.  They (Microsoft) pad many
>things to even alignment boundries, but structure contents themselves
>are tightly packed.

This is probably inherited from 16-bit packing and calling conventions.

>> #pragma pack(0) /* or whatever stops all packing */
>> struct read_args {
>> 	char const *path;
>> 	int flags;
>> 	char pad1[4];		/* little endian, 4 byte ints, 8 byte regs */
>> 	mode_t mode;
>> 	char pad2[6];
>> };

>That would be better expressed as:

>> #pragma pack(8) /* quad stack alignment, pointers are quads*/
>> struct read_args {
>> 	char const *path;
>> 	int flags;
>> 	mode_t mode;
>> };

gcc-2.6 only supports pack(1)..pack(4) - the natural padding can't be
increased.  Note that it need may need to be increased to support a
foreign ABI, and it isn't even natural on Pentiums (doubles should
have 8 byte alignment).  #pragma is unportable.  My version has the
advantage of requiring only 1 pragma per struct, while yours requires
up to one pragma per struct member and it may still require padding.
Consider alignment of 4-byte quantities on boundaries 4, 9, 16, 25, ...

>> `lcall' allow users to trace into syscalls.  This can be recovered from

>I understand the rationale for considering the changes.  I don't understand
>the rationale for making them.  It seems the rationale is "to compete with
>NetBSD and Linux regarding speed".  Is this correct?

To compete in speed and elegance.

>> >This was my point on the quad crap and reverting the default interfaces
>> >to POSIX compliance (and double doesn't count unless you can use it
>> >without a prototype in scope).
>> 
>> 	if (lseek(fd, (off_t)foo, SEEK_SET) == (off_t)-1)
>> 		perror("lseek");
>> 
>> works without a prototype in scope even if off_t is quad or double.

>But violates POSIX (in the quad case) or the spirit of POSIX (in the
>double case -- you yourself suggested that this is probably an error
>in the spec).

Doesn't matter.  The call and check must be written something like the
above so that it works independent of the type of off_t even if off_t
is one of char, short, int or long.  Actually if foo is a variable then
it should have type off_t, and the cast of -1 is unnecessary because
off_t is _signed_ arithmetic, so the statement should normally be
written as

	if (lseek(fd, foo, SEEK_SET) == -1)
 		perror("lseek");

>> >> Consider a 68K compiler that passes the first 2 pointer args (if any)
>> >> in a0-a1 and the first 2 integer args (if any) in d0-d1 and the other
>> ...
>> But not stupid :-).

>OK.  I admit it's probably minisculely faster.  Is it worth the clutter
>of the xxx_OFFSET and the xxx_type and the unreadable glue routines to
>get that miniscule speed "improvement"?

If it is the compiler or ABI's calling convention, then you have no choice.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510280612.QAA16949>