9 ms·
liblinux: Architecture-independent access to Linux system calls
- phendrenad2 5y agoVery cool. It seems that glibc is not a faithful wrapper of the Linux syscalls (it makes assumptions about some calls, to provide a better C API, and doesn't support some Linux-specific syscalls). You could always call syscalls directly, using syscall() (https://man7.org/linux/man-pages/man2/syscall.2.html https://man7.org/linux/man-pages/man2/syscall.2.html), but a wrapper library is nicer.
- matheusmoreira 5y agoYes. Glibc is very heavyweight. Its supposedly thin wrappers provide features such as cancellation, for example. One of my objectives was to produce ELFs with no symbols other than those defined in my own code. Glibc adds a lot of symbols.
- Joker_vD 5y agoSo... it's basically kernel32.dll? That is, the shared library with a stable API across all supported platforms, and stable ABI inside any one specific platform which hides all the gritty details of switching to and back from the kernel? One wonders why it has not appeared much sooner but better late than never, I guess.
- guerrilla 5y agoThe explanation for why it's useful is at the bottom of the page, but it wasn't necessary before glibc got behind and before Linux started adding things that glibc would probably never implement*. Generally, on UNIX-like systems, the C library isn't just the C library but also exposes the UNIX/POSIX API which is just a set of wrappers around calling into the kernel (done with software interrupt 0x80 on x86 Linux.) * Remember that glibc is part of the GNU project and is meant to be portable beyond Linux, especially to Hurd. It might not make sense for them to implement interfaces that wouldn't work or would require significant work to emulate on Hurd, the BSDs and Solaris.
- Joker_vD 5y agoWell, yeah, merging kernel calls into the runtime of one specifically favoured programming language is a silly idea, why not have the kernel calls in a separate, cleanly defined language-agnostic OS-specific library? "It just the way the things has come to work historically"?
- guerrilla 5y agoWell, first of all the UNIX/POSIX API is a C API, so that question doesn't make much sense. On top of that, there have been no competitive systems programming languages until recently (and certainly none that weren't written in C), so that wouldn't have been worth it. Also, it wasn't really an idea per se: C is just the native language and lingua franca of UNIX and that's just how UNIX developed organically.
- GoblinSlayer 5y agoWhy would it matter what system programming languages are there? Unix can't run other languages?
- koprulusector 5y agoThe kernel is written in C. Ok, why does that matter? Because its interfaces and architecture are tightly intertwined with C. Remember that C was partially developed to use in building Unix. So, kernel was written in C and therefore uses C data structures, pointers, and follows C conventions for using them (for example, kernel might return a struct of pointers). This applies to interfaces and structures, making syscalls (depending on which syscall and what is needed), checking return values or error codes. You don’t NEED this stuff exactly to run on Unix. What and how much you need, or even just convenience, are how it boils down. If you want to use eBPF to trace things from raw network packets, syscalls, file systems, you can do some in Python but you’ll need some degree of C. You want to run a Django or flask app in just Python? Good to go. [This article on Linux ABI](https://en.wikipedia.org/wiki/Application_binary_interface https://en.wikipedia.org/wiki/Application_binary_interface) might help explain better/in more detail. Sorry if this isn’t the best explanation, I’m on mobile and up too late.
- GoblinSlayer 5y agokernel32.dll is a little more language agnostic: it provides heap, threads, mutexes, environment variables and whatnot.
- matheusmoreira 5y agoYes! The difference is on Linux a shared library is not actually required for kernel system calls. The binary interface is stable and will not change. https://github.com/torvalds/linux/blob/master/Documentation/ABI/stable/syscalls https://github.com/torvalds/linux/blob/master/Documentation/... On Windows and other operating systems, things such as system call numbers can and do change. There's no way to interface with the kernel without linking to vendor libraries. So on Linux you can ditch libc and write your own code. A Rust liblinux is definitely possible, I tested it. You can even have a compiler generate the system calls for you! It just needs to support the simple calling convention. No libraries necessary. I've seen a project that does just that: https://github.com/titzer/virgil https://github.com/titzer/virgil
- Joker_vD 5y agoI mean, I also can call functions from kernel32.dll on Windows without need of any libc, and the ABI is stable and will not change; and if/when MS decides to change the actual mechanism of switching into the kernel mode, or decide to move some stuff from the kernel into the user space ― they can, and I don't have to worry about that (and recompile my apps) because it's all abstracted away! "Fix it once in the shared library, and all its clients will benefit automatically". On Linux, however, we have, for example, glibc on one hand which claims that it doesn't have a goal of forwarding all of the Linux's syscall, and several failed initiatives on the other hand to allow the user's code to perform syscalls only from inside of glibc (which spells doom to anything that doesn't use libc, e.g. Golang) because of security reasons. And the history of still having to support INT 80h together with SYSCALL on x64 on the third hand.
- matheusmoreira 5y ago> several failed initiatives on the other hand to allow the user's code to perform syscalls only from inside of glibc (which spells doom to anything that doesn't use libc, e.g. Golang) because of security reasons I didn't know about these efforts. Please elaborate.
- 5y ago
- funcDropShadow 5y agoSeems, like a very interesting idea, but the readme states: > Currently, the only supported architecture and compiler is x86_64 and GCC, respectively Let's wait until its architecture-independence has arrived in practice.
- KitCapo 5y agoConsidering that the last commit was 3 years ago.. I'm not so optimistic that we'll ever see it arrive in practice.
- usr1106 5y agoI believe the author stated only a week ago that he has stopped working on it.
- matheusmoreira 5y agoYes. My next step was implementing modern ARM architectures at least so I could compile a version for my phone. I don't have other architectures to test on so I'd need pull requests for them. The Linux kernel nolibc.h already has support and is just better in almost every way. I wasn't sure if there was any point in continuing liblinux after I discovered it since it achieves almost everything I tried to do and doesn't even require a build system, shared libraries or anything. The support for auxiliary values is missing though. Maybe they'd accept a patch...? I also asked Greg on reddit about nolibc.h once: https://old.reddit.com/r/linux/comments/fx5e4v/im_greg_kroahhartman_linux_kernel_developer_ama/fn3rpht/ https://old.reddit.com/r/linux/comments/fx5e4v/im_greg_kroah... Turns out there was a klibc project that never turned up in my original research!
- GoblinSlayer 5y ago>The C library is itself a user space program, so the rule that a user space program has to go through the C library obviously isn't logical. And the GNU C library is an optional tool, not an official part of the kernel interface (if it were the latter, I would expect to see it packaged with the kernel). Ohh, if only we could make C the second class citizen. C brings with itself meaningless legacy from 1969 into modern systems, like you might think openat2 was created recently, but it's designed for PDP-7, because it's C and stuff was always done this way.
- lelanthran 5y agoWhat would be the first class citizen after you make C second class?
- GoblinSlayer 5y agoMore precisely it's about making PDP-7 design the second class citizen. Interoperable design becomes the first class instead. POSIX would be implemented on top of that.
- lelanthran 5y agoI understand that, but right now the C ABI is first class, and every language can call into it. What replacement are you proposing that every language can call into? How would a migration of existing Java, Python, Ruby, C++ etc programs be done to this new interface? Do programs need to be modified at the source level? Just recompiled? How will the existing programs that cannot be recompiled be handled? I quite aware that you can make the C ABI a shim into the new first class ABI to make existing programs work, but why would anyone target the new ABI when the existing one still works?
- GoblinSlayer 5y agoObviously it's not aimed at people who want to use only POSIX.
- Keyb0ardWarr10r 5y agohttps://github.com/matheusmoreira/liblinux/tree/master/source/system_calls https://github.com/matheusmoreira/liblinux/tree/master/sourc... "access to a very limited subset of Linux system calls" :P Still a cool project though and a good base.
- matheusmoreira 5y agoIndeed, the library is missing wrappers for most of the system calls. I wrote the functions I needed for the code in the examples directory. I even wrote a little script that lets me see which system calls haven't been implemented yet. make system-calls.missing The library does provide access to every system call through the generic system_call function. It just doesn't have compile time type checking.
- qalmakka 5y agoOT: I would have gone with the 'libinux' name, just to have a cool -linux command line flag like 'libiberty' .
- guerrilla 5y agolike -liberty in the gcc tree :)
- wongarsu 5y agoThe author of liblinux commented about it a couple days ago on HN [1] The part most relevant to this discussion: > I stopped developing this because I discovered the Linux itself has a better solution that they use for their own tools: > https://github.com/torvalds/linux/blob/master/tools/include/nolibc/nolibc.h https://github.com/torvalds/linux/blob/master/tools/include/... 1: https://news.ycombinator.com/item?id=29106179 https://news.ycombinator.com/item?id=29106179
- zokier 5y agoInteresting that nolibc reproduces one of the greatest misfeatures (obviously heavily imho) of libc, the errno. At least it is sort of optional there.
- matheusmoreira 5y agoI agree. That's one thing I don't like about the kernel header. Linux system calls already have a good interface, they return error codes that consist of negated errno constants. Since we're not using the C library, we might as well do things right and remove global variables. The kernel developers implemented nolibc.h with 3 levels of abstraction: system call entry point, function wrappers and libc interface. They set errno in the libc interface. Personally I don't see the point. > The third level is the libc call definition. > It exposes the lower raw sys_<name>() calls in a way that looks like what a libc usually does, takes care of specific input values, and of setting errno upon error. Defining NOLIBC_IGNORE_ERRNO solves the problem!
- remram 5y agoIf it's trying to be a drop-in replacement, it has to have the same API... You could also wonder why they spelled CREAT without an E again, with the same answer.
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]