kerchen@iris.ucdavis.edu (Paul Kerchen) (02/28/89)
Hello all! Currently I'm researching computer viruses here at UCD and I have encountered an interesting question (at least I think it's interesting): Is the system call "syscall()" necessary? I am *not* asking if system calls in general are necessary. I *am* asking about a particular system call called "syscall" which allows indirect system calls (see section 2 of the man pages for more info). It seems like anything one could do with syscall() could be done just using the needed system call directly. I'd like to know if there are certain applications for which this function is a *necessity*, not just a convenience. Also, I am looking for *real* examples, not contrived ones with no basis in reality. (Sorry for being so verbose. I want to make sure that it is clear what I am asking--I've already received enough replies which go something like, "System calls are needed so that applications become independent of changes in the kernel....") Paul Kerchen | kerchen@iris.ucdavis.edu
gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/28/89)
In article <3740@ucdavis.ucdavis.edu> kerchen@iris.ucdavis.edu (Paul Kerchen) writes: >Is the system call "syscall()" necessary? It's not a system call, just a library function. Of course it is not necessary in any logical sense. I don't even think it's particularly useful these days; the last time I saw it used was on a Sixth Edition UNIX system.
lee@doc.cs.unm.edu (Lee Ward) (02/28/89)
In article <9742@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <3740@ucdavis.ucdavis.edu> kerchen@iris.ucdavis.edu (Paul Kerchen) writes: >>Is the system call "syscall()" necessary? > >It's not a system call, just a library function. >Of course it is not necessary in any logical sense. >I don't even think it's particularly useful these days; >the last time I saw it used was on a Sixth Edition UNIX system. It still has uses... #include <stdio.h> /* 4.{2,3} reset UBA - BSD VAX */ #define RESUBA 119 main(argc, argv) int argc; char *argv[]; { if (argc != 2) { fprintf(stderr, "Usage: %s UBA#\n", argv[0]); exit(1); } exit (syscall(RESUBA, atoi(argv[1]))); } --Lee (Ward)
ekrell@hector.UUCP (Eduardo Krell) (02/28/89)
In article <3740@ucdavis.ucdavis.edu> kerchen@iris.ucdavis.edu (Paul Kerchen) writes: >Is the system call "syscall()" necessary? Yes, and I'll give you an example where I use it. We have a user level C library which implements an extension to the Unix File System. This work was originally done inside the kernel (where it belongs), but for practical reasons we decided to write a user level library which emulates the semantics of our extensions (we didn't want to force our users to run a new kernel just to play with our stuff). This user level library contains functions for all the system calls which take pathnames as arguments (like stat, open, link, etc.). We do some magic with the pathnames supplied to these functions and then call the *real* system calls with maybe different pathnames. The call to the real system call is accomplished through syscall(). I could have done it without syscall(), but it would have required major kludges to do it in a portable way. Eduardo Krell AT&T Bell Laboratories, Murray Hill, NJ UUCP: {att,decvax,ucbvax}!ulysses!ekrell Internet: ekrell@ulysses.att.com
haahr@phoenix.Princeton.EDU (Paul Gluckauf Haahr) (02/28/89)
kerchen@iris.ucdavis.edu (Paul Kerchen) writes: > Is the system call "syscall()" necessary? as doug points out, it's just a library function not a system call. all it provides is a (portable) C callable interface to the assembly language glue that traps to the operating system. it is the moral equivalent of an inline asm directive for a "chmk" or "trap #0" or "syscall" instruction. on some systems i've seen, the system calls that can be implemented as calls to syscall() are. (things like wait() and pipe() often are hard to do) this makes it easy to write the syscalls directly in c. gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) responds: > It's not a system call, just a library function. > Of course it is not necessary in any logical sense. > I don't even think it's particularly useful these days; > the last time I saw it used was on a Sixth Edition UNIX system. it can be useful if one is spoofing other system calls. i have code, for example, that replaces read() and write() with functions that somewhere down the road do real syscalls. with syscall() declared as int syscall(int, ...); one can conveniently use #define _read(fd, buf, n) syscall(SYS_read, fd, buf, n) [ to do this in an ansi c environment, one would probably have to spoof out _SYS_read as well. ] paul haahr princeton!haahr haahr@princeton.edu haahr@pucc.bitnet
gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/28/89)
In article <2292@unmvax.unm.edu> lee@doc.cs.unm.edu () writes: -In article <9742@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: ->In article <3740@ucdavis.ucdavis.edu> kerchen@iris.ucdavis.edu (Paul Kerchen) writes: ->>Is the system call "syscall()" necessary? ->I don't even think it's particularly useful these days; ... -It still has uses... - exit (syscall(RESUBA, atoi(argv[1]))); Only because Berkeley neglected to provide a resuba() hook in the C library! Given direct hooks in the library for all system calls, I know of no real requirement for the syscall() function.
jik@athena.mit.edu (Jonathan I. Kamens) (02/28/89)
The workstation installation floppies at Project Athena are severely limited by space -- they must fit on a 1.2meg floppy (for a VAX workstation) or on 2 1.2meg floppies (for an IBM RT). We can't include a different binary for every system call we need to use, so we write one binary with a simple interface to syscall() and then write shell scripts to do what the rest of the binaries would do. Works great for us :-) Jonathan Kamens USnail: MIT Project Athena 410 Memorial Drive, No. 223F jik@Athena.MIT.EDU Cambridge, MA 02139-4318 Office: 617-253-4261 Home: 617-225-8218
debra@alice.UUCP (Paul De Bra) (03/01/89)
In article <3740@ucdavis.ucdavis.edu> kerchen@iris.ucdavis.edu (Paul Kerchen) writes: >Hello all! >Currently I'm researching computer viruses here at UCD and I have >encountered an interesting question (at least I think it's >interesting): Is the system call "syscall()" necessary?... >... Also, I am looking for *real* examples, not contrived >ones with no basis in reality. A *real* example can be found in the EUUG UUCP source. Uucp used to create *lots* of files in /usr/spool/uucp. It is more convenient to distribute these files among several directories, as modern uucp's do. What this uucp does is modify names like "D.systemXXXX" into "D.system/XXXX" or something. The way this works is as follows: 1) the source code for uucp is not modified. 2) a new routine "open()" is written, which modifies the "D.systemXXXX" into "D.system/XXXX", and then calls syscall() with the right parameters to do the real open(). By having your own open() routine there is no way to access the real open() system call any more, so they use syscall instead. Paul. -- ------------------------------------------------------ |debra@research.att.com | uunet!research!debra | ------------------------------------------------------
guy@auspex.UUCP (Guy Harris) (03/01/89)
An omnibus reply: > (Sorry for being so verbose. I want to make sure that it is clear > what I am asking--I've already received enough replies which go > something like, "System calls are needed so that applications become > independent of changes in the kernel....") It's unfortunate that people believe that, because it's not true. There exist other mechanisms for dynamically binding code to a particular procedure, which is what the person is *really* saying is needed here; those other mechanisms work for functions *not* implemented in the kernel, and that greater generality can be a big win. It should be possible to make applications independent of changes to the implementation of user-mode library routines, as well; that way, for example, you can have the same application binary work, regardless of whether "gethostbyname" reads "/etc/hosts", or talks to the Internet name server, or talks to the Yellow Pages server, or talks to an Apollo Registry server, or.... The application just binds to whatever the local implementation of "gethostbyname" is. (Sun has put a version of its SunOS 4.0 "libc" shared library on "uunet" that contains a "gethost*" that talks to the Internet name server rather than to the Yellow Pages server, for example, so this isn't just a theoretical "this could be done" argument - it *has* been done.) > It still has uses... > #include <stdio.h> > /* 4.{2,3} reset UBA - BSD VAX */ It is useful there only because there's no library routine in the 4.{2,3}BSD C library that directly executes the appropriate trap, or whatever. Had they included such a routine, "syscall" wouldn't be necessary in this case; nothing *prevented* them from including such a routine, so the example does not at all demonstrate that "syscall" is an absolute necessity, merely that a deficiency in the OS requires that "syscall" be used to work around it. >This user level library contains functions for all the system calls which >take pathnames as arguments (like stat, open, link, etc.). We do some >magic with the pathnames supplied to these functions and then call the *real* >system calls with maybe different pathnames. The call to the real system >call is accomplished through syscall(). > >I could have done it without syscall(), but it would have required >major kludges to do it in a portable way. Again, this is a special-case solution to a more general problem; had a more general mechanism for writing "wrappers" for existing procedure calls existed - one that would, say, permit you to write "wrappers" around routines that *aren't* just stubs that trap to the kernel - such a mechanism could have been used. So again, it doesn't demonstrate that "syscall" is an absolute necessity, merely that it's required in some cases to get around deficiencies in the OS.
Leisner.Henr@xerox.com (marty) (03/01/89)
Geez, I never knew about syscall.
Recently I wanted to control the amount of ram my program had to work with
so I could see how it failed under various memory-short environments.
I wanted to move my stack to N bytes over my data area, so I had a heap N
bytes large (only in effect for this process) and I wanted N configurable
at run time. I wrote my own sbrk which checked against the current stack
pointer to see whether or not to allocate space for malloc (which used
morecore).
Turns out sbrk and brk were in the same module -- so I had to unassemble
and synthesize my own brk system call (this was on an Opus board with a
National 32016 running Sys V.?).
If I knew about syscall, I support I could have just coded brk as:
brk(void *address)
{
return (int) syscall(BRK_#, address)
}
instead of messing with assembler. (It didn't take long anyway).
When I get back to playing with that piece of software, I'll try the
syscall apporach.
marty
ARPA: leisner.henr@xerox.com
GV: leisner.henr
NS: martin leisner:wbst139:xerox
UUCP: hplabs!arisia!leisner
kerchen@iris.ucdavis.edu (Paul Kerchen) (03/01/89)
Thank you to everyone who replied to my question about syscall(). I'm posting this here because I couldn't reply to everyone who sent me responses ( mailer bounced 'em )-: ). I did get several good reasons for having the beast, so I'm more or less satisfied. Again, thank you. Paul Kerchen | kerchen@iris.ucdavis.edu
gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/01/89)
In article <8984@alice.UUCP> debra@alice.UUCP () writes: >2) a new routine "open()" is written, which modifies the "D.systemXXXX" > into "D.system/XXXX", and then calls syscall() with the right > parameters to do the real open(). By having your own open() routine > there is no way to access the real open() system call any more, so > they use syscall instead. There is a danger here that you need to be aware of. Quite possibly some of the application code opens files via calls to fopen() rather than directly using open(). The above trick has worked so far because UNIX fopen() eventually invokes the open() function in the C library. In the near future, it is probable that UNIX fopen() will instead invoke a function called __open() or some such; this is required for compliance with the (forthcoming) ANSI C standard. (There are actually some ways around this but the simplest implementation is as I've just described.) Therefore the application will no longer have all its file-opening attempts intercepted by your "wrapper" around the OPEN system call.
mirk@warwick.UUCP (Mike Taylor) (03/07/89)
In article <9757@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB)) writes: >Quite possibly some of the application code opens files via calls to >fopen() rather than directly using open(). The above trick has worked >so far because UNIX fopen() eventually invokes the open() function in >the C library. In the near future, it is probable that UNIX fopen() >will instead invoke a function called __open() or some such; Am I missing something here, or is this a major disaster? I always thought that the beauty of UNIX was supposed be that everything went through a simple, elegant and well-defined interface of system-calls, that *all* reading was via read(2), that *all* writing was via write(2), and so on. I thought that UNIX was the operating system where the user Knows Where He Stands? It's kinda sad to see how the minimal set of low-level routines in primitive UNICES has mushroomed to the incredible 178 distinct system calls that our current UNIX (SunOS 4.3, in fact) seems to find necessary. But surely once you start saying that fopen() doesn't have to use the system-calls at all, the whole ethos goes right out the window? I remember the quote from Ken Thompson: "The only thing I would chnage if I designed UNIX now is that I would call the creat() system call create()". Ask yourself how *that* ties in with this apalling move? ______________________________________________________________________________ Mike Taylor - {Christ,M{athemat,us}ic}ian ... Email to: mirk@uk.ac.warwick.cs "Can't say my name's well-known, you don't see my face in Rolling Stone (yet)" ------------------------------------------------------------------------------
lm@snafu.Sun.COM (Larry McVoy) (03/08/89)
In article <1449@ubu.warwick.UUCP> mirk@uk.ac.warwick.cs (Mike Taylor) writes: >It's kinda sad to see how the minimal set of low-level routines in >primitive UNICES has mushroomed to the incredible 178 distinct system >calls that our current UNIX (SunOS 4.3, in fact) seems to find >necessary. Umm, this is a bit naive. Granted, I'm working at Sun at the moment, but those of you who remember my screaming and yelling about the size of the SunOS kernel will realize that I tend to speak my mind without letting any corporation's feelings get in the way. Anyway, counting system calls is bogus, completely bogus. You need to count syscalls & ioctls. ioctls() bop right down into the kernel too, you know. AT&T adds ioctls like there is no tomorrow. I'm not saying that the kernel isn't too big, in fact I agree completely if that is the poster's point. I am saying that it is naive to simply count system calls. It's a lot more than 178; Unix is corporate software. Larry McVoy, Lachman Associates. ...!sun!lm or lm@sun.com
kerchen@iris.ucdavis.edu (Paul Kerchen) (03/08/89)
At the request of several people, here's a brief list of reasons supporting the need for syscall(2). For those who are tired of this discussion, hit 'n' now! :-} Compelling reasons for the use of syscall(2): 1) Changing the functionality of a system call, keeping track of the number of times a call is made, or intervening before a call is made. 2) Testing new system calls before adding them to the kernel. 3) Simulating system calls. 4) Backwards compatibility to phased-out system calls (eg. stty vs. ioctl). 5) Certain other, specific applications. Note: On some OS's (like SunOS), syscall(2) is just another function, while on others (like Ultrix V2.2), syscall(2) is the only mechanism for making system calls (ie. all other calls eventually call syscall(2) to do the actual call). Therefore, syscall(2) really is a necessity for some systems. For a more verbose listing of reasons, send me e-mail and I'll send you a trimmed down concatenation of all the responses I've received (provided the mailer doesn't bounce 'em). That is, I'll send you a list of verbatim responses without all of the extra header junk. Paul Kerchen | kerchen@iris.ucdavis.edu
gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/08/89)
In article <1449@ubu.warwick.UUCP> mirk@uk.ac.warwick.cs (Mike Taylor) writes: >Ask yourself how *that* ties in with this apalling move? IT HAS NOTHING TO DO WITH IT. It's also not an "appalling move". In fact it is designed to make it possible to port C applications around between widely different types of operating systems, something that is problematic if each system's C environment be allowed to preempt names from the application for its own use. In a UNIX implementation of C, I would expect that you could still get at the open() system call by that name. However, the portable C library must not use that name if it could accidentally be linked so that an application-provided function named open() would be used where a system call interface is expected by the library implementation. Thus the need for the library to be implemented using calls to names outside the application's name space, e.g. __open().
boyd@necisa.necisa.oz (Boyd Roberts) (03/16/89)
This discussion is really getting beyond the pale. The _correct_ evaluation is probably three-fold: 1. In V[67] there was such a feature which worked out the system call from the byte following the trap instruction. From a historical perspective such functionality was turned into a library routine. 2. Portability in some bizzare sense. Although, by rights there should be a function for every system call you'd need to make. 3. A simple mechanisam for adding system calls without having to mess with libc. Useful for debugging during kernel development. Now, enough! Desist! Stop! Boyd Roberts NEC Information Systems Australia boyd@necisa.necisa.oz ``When the going gets wierd, the weird turn pro...''
friedl@vsi.COM (Stephen J. Friedl) (03/20/89)
In article <807@necisa.necisa.oz>, boyd@necisa.necisa.oz (Boyd Roberts) writes: > This discussion is really getting beyond the pale. The _correct_ > evaluation is probably three-fold: There's another one. I recally from a V7 man page (From the Onyx, RIP) talking about syscall that it was implemented so pure-text programs could do variable system calls without needing to write to their own text space. Steve -- Stephen J. Friedl / V-Systems, Inc. / Santa Ana, CA / +1 714 545 6442 3B2-kind-of-guy / friedl@vsi.com / {attmail, uunet, etc}!vsi!friedl "I think, therefore I'm a yam." - me
rbj@dsys.icst.nbs.gov (Root Boy Jim) (04/06/89)
? From: Doug Gwyn <gwyn@smoke.brl.mil> ? Date: 28 Feb 89 04:48:24 GMT ? In article <2292@unmvax.unm.edu> lee@doc.cs.unm.edu () writes: ? -In article <9742@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: ? ->In article <3740@ucdavis.ucdavis.edu> kerchen@iris.ucdavis.edu (Paul Kerchen) writes: ? ->>Is the system call "syscall()" necessary? ? ->I don't even think it's particularly useful these days; ... ? -It still has uses... ? - exit (syscall(RESUBA, atoi(argv[1]))); ? Only because Berkeley neglected to provide a resuba() hook in ? the C library! Given direct hooks in the library for all system ? calls, I know of no real requirement for the syscall() function. You may be correct in the specific case of what you just said, but the general case is more like asking whether pointers to functions are desirable in C or whether "funcall" or "apply" is useful in LISP. Also note that VMS has (or at least RSX has) an indirect format of their system call. Catman Rshd <rbj@nav.icst.nbs.gov> Author of "The Daemonic Versions"