WHO WHEN

Rick Hohensee 19990903

WHAT

libsys is for throwing out all of the cost and facilities of libc without
throwing out all of the facilities of the kernel.  libsys itself is
written in GNU C, and the argv wrapper is written in GNU gas assembly, but
the routines in the resulting libsys.a and arg_env.o can be linked to an
unstripped ELF relocatable object produced by anything. This package also
includes an x86 wrapper similar in function to libc and gcc's crt0.o. This
wrapper provides the argv/environ arrays supplied by execve to a program,
without needing to link to libc. This version of libsys is a large subset
of the Linux syscalls but mmap, ipc, module stuff, and some other things
are missing. What is here is what had a manpage in the current standard
"section 2" Linux manpages and worked unmodified with the asm/unistd.h
macros.  libsys should be portable across Linux. The argv/environ service
wrapper is platform-specific, and all I have is x86's. Compare to crt0.S
for your platform. The arc_env.c in here is heavily commented. 

WHY

libsys is a side-effect of work I am doing on a Forth-like language I call
H3sm, Hohensee's 3-stack machine. Being fundamentally Forth-like, H3sm
does not have the C nature. Not a bit. That's the point, and therefor libc
is no help at all. Most popular unix languages, from sed to C to Perl have
a distinct family resemblance that is due to the fact that they are all
largely interfaces to libc. H3sm is different. Forths traditionally have
functionality analagous to linker, compiler, editor, and virtual storage
in the "interpreter". In less space than you expect. And faster than other
interpreters.

Calling syscalls directly can be useful for other less daunting things
than writing a very un-C-like programming language. In fact, examples
based on libsys make more sense to a Forth guy for introducing the new C
programmer to C than the prevalent approach. "Hello world" is not the
simplest quantum of a valid C program. "true" written without libc or
argv, or explicit syscalls for that matter, is. There's a delightful
example like that at www.muppetlabs.com, a page that helped with this
effort quite a bit. 

libsys allows creating space-efficient non-trivial stand-alone (statically
linked) programs. My first libsys-linked program was a thing that simply
echoes it's arguments to standard out, which was < 1200 bytes stripped,
static, and it wasn't the extreme hacking exercise that e.g. the
muppetlabs example is.  The code for the program itself was reasonably
normal C. Concise static executables are real handy for install
situations, rescue situations, and low resource situations such as
embedded apps, legacy hardware, "travel disks" ... I suppose for extreme
low resource systems one might even consider a dynamic libsys. At about
100 bytes per syscall, I'm fine with static. That's not much of a hit
considering all the work most syscalls do, and with the robustness of
static linking in the bargain. 

An example is in order. A counter-example actually. Let's say you want a
small static binary that does almost nothing. For example purposes, our
program will do exactly nothing. Well, maybe it returns 0. (This is from
memory because I recently rm'ed my libc.a ;o). 

$echo " main(){} " > null.c
$gcc -static null.c
$strip a.out
$file a.out
ELF static executable, stripped    or words to that effect
$ls -s  a.out
94 a.out

94k or so for a program that does nothing. This hit apparently is not
proportional to program size, mercifully, but 94k is still perfectly
ridiculous. 

HOW, internal

libsys uses the macros is asm/unistd.h to put C/asm wrappers around the
syscalls.  There's really not much to it, once you figure out how to do
it. These macros appear to be portable across Linux/GNU.  asm/unistd.h is
the crucial include file, which in fact does most of the compiling work.
The arg/env services wrapper code is x86 GNU gas assembly wrapped in a GNU
C asm statement for build convenience. The argv wrapper will be linked to
your program as a relocatable object, a .o file. libsys.a is each syscall
as a separate .o object, archived with ar -r. 

HOW to build

./build

Or you can just paste libsys.c.bulk into your app, or pieces of it, and
maybe the argv wrapper too.

HOW to install

Put libsys.a and the wrapper .o file in your library search path.

Actually, you may have to put arg_env.o in the directory crt0.o is in in
your gcc tree, or of course you can just keep them near the program you
are working on. 


HOW to use

The shell does file IO redirection. The kernel endows any executable with
the necessary file descriptors, so stdin/out/err "just works", as does any
C or other code that just uses the CPU. The file descriptors are there,
but you have nothing that can use them without some syscalls.  When you
link with libsys you then also have about 130 named functions available
for the kernel syscalls. nm libsys.a will list them. The section 2
manpages will tell you what they do and what thier arguments' C types are.
man 2 intro is very good and very pertinent.  They all use the errno
variable, mostly in redundancy to thier return value, but sometimes not.
Basically, you code them like libc or other calls. The equivalent of
main() in the arg_env.o wrapper is named begin_flow(). This is to
distinguish libsys-linked code from libc-linked code, which are quite
different. Then the build is a bit unique...

	gcc -nostdlib your_proggy.c libsys.a

or, if you need commandline args or the parent's environment variables...

	gcc -nostdlib your_proggy.c libsys.a arg_env.o

libsys is about rolling your own, and about bottom-up. Try things. Learn.
Drop me an email :o) 

RIGHTS

Copyright 1999 Richard Allen Hohensee
 This package is released for redistribution only as part of an intact
entire cLIeNUX Core.

TANGENTS

Note that I don't use make. It seems to me that make is an unfortunate
leftover from the days before shells had a "fileA is_newer_than fileB" 
comparison, or something. In general, I spend a lot of time removing
unnecessary dependancies. make is one of them. 

libsys was mostly for H3sm, but I'm starting to think the next cLIeNUX
will be all static. 

A GNU ld quantum of linkability is apparently the object file. That is, if
you compile libsys.c.bulk as one .o and link to it you get the whole .o
linked in, not just the routines you call. That's a bit curious, since
it's much bigger as an ar archive for all the individual routines. This is
a minor gripe though, since the end result of linking with the .a is not
at all bletcherous, and I don't grasp the issues of yanking routines from
objects, and I hope to have a H3sm dictionary soon anyway  :o) 


Rick Hohensee
humbubba@smart.net
http://linux01.gwdg.de/~rhohen
cLIeNUX		H3sm 		xart		libsys		cycluphonics

