Support for system calls?
rempas opened this issue · comments
I don't remember if I have requested that (or if we have talked about it at all in another issue) and I wasn't able to find another issue with that I posted talking about that, but could you add system call support?
I have requested about inline assembly, but this isn't as important as system call support, tbh.
Thank you for your work and time reviewing this. If you are interested, let me know! If not, closing the issue will give me the message ;)
Hey there,
Not sure if it helps, but if you're using the libc, you can use the syscall(2)
interface
Hey there,
Not sure if it helps, but if you're using the libc, you can use the
syscall(2)
interface
Thanks for the information. But no, I will not use any library. If anything, my language will have its own library that will not be depended on libc.
Hi, I am also interested in reducing runtime dependencies while using Mir, but I really don't understand what is requested here. Traditionally, the syscall interface is a stable ASM interface used mostly by the system library only.
For example, here is a part of the Cosmo libc implementation:
https://github.com/jart/cosmopolitan/blob/master/libc/sysv/syscalls.sh
https://github.com/jart/cosmopolitan/blob/master/libc/sysv/syscall2.S
https://github.com/jart/cosmopolitan/blob/master/libc/sysv/syscall3.S
https://github.com/jart/cosmopolitan/blob/master/libc/sysv/syscall4.S
To remove such a dependency, it means syscall functions must be statically implemented in the Mir runtime. This can be done by copying existing code like musl libc's or Cosmo's into the project, as their licenses probably allow it. This seems like quite a lot of work and maintenance, especially when considering the multiple target architectures that the project already supports.
Maybe we could statically link the Mir runtime with musl or cosmo libc, would that answer your need ?
Hello @cyrilmhansen! When you say "Mir runtime", I suppose you are talking about the loader and the backend itself?
Considering that you are talking about that, then it makes sense that a system will always have to include libc as Mir itself (both the loader and the backend) are written in C.
However, the actual file that will be created will just be text (regardless if it's bytecode or human-readable) that the loader will interpret and either use as is or do JIT.
For that reason, a "syscall" Mir instruction in the Mir IR can be used to tell the loader about the system call that needs to be executed.
For a language that has a backend that can create a "system binary" (for example, ELF in case of Unix OSes) like LLVM, you can create the system library of the language using that backend and then use MIR for everything else and link with this library. But this will be complicated to implement and support.
What I don't understand is the following:
This can be done by copying existing code like musl libc's or Cosmo's into the project, as their licenses probably allow it
But wouldn't it just be a regular instruction like anything else? In X86_X64, there is the "syscall" instruction that does that. You just move the value in registers and then use that instruction. So Mir could also give custom assembly (or even binary!) support and having to do less work!
Let me know if anything doesn't make sense :)
I guess an option, if libc is not intended, which in your case would be alright given you intend to provide a standard library yourself, would be to use Linux Kernel's "nolibc",
You would probably need to create a wrapper or modify it a bit, but that should provide a basic "runtime" for your language,
Hope it helps
Hello @cyrilmhansen! When you say "Mir runtime", I suppose you are talking about the loader and the backend itself?
Yes I meant the support code included in the loader for mir bytecode "binaries".
The existing code relies on dynamic linking, it failed when I tried to compile and run it with Cosmo libc which supports only static linking.
Yes I meant the support code included in the loader for mir bytecode "binaries".
The existing code relies on dynamic linking, it failed when I tried to compile and run it with Cosmo libc which supports only static linking.
Oh! I get it now! You mean the actual Mir! I don't understand, however, what you mean when you say that "it relies on dynamic linking". Do you mean that when you compile Mir, you need to use dynamic linking with "libc" and you cannot create a static binary?
I guess an option, if libc is not intended, which in your case would be alright given you intend to provide a standard library yourself, would be to use Linux Kernel's "nolibc",
You would probably need to create a wrapper or modify it a bit, but that should provide a basic "runtime" for your language,
Hope it helps
That's a nice solution, thanks for sharing!
Oh! I get it now! You mean the actual Mir! I don't understand, however, what you mean when you say that "it relies on dynamic linking". Do you mean that when you compile Mir, you need to use dynamic linking with "libc" and you cannot create a static binary?
Mir driver calls dlopen function. This is not supported by Musl libc :
https://git.musl-libc.org/cgit/musl/tree/src/ldso/dlopen.c
Cosmo libc contains hacks for this I am not sure to understand (uses a bridge with a second process...) see comment on top of https://github.com/jart/cosmopolitan/blob/master/libc/dlopen/dlopen.c
As Mir is a lightweight, portable project I would prefer the sample code to be compatible with static linking options and this seems to require the removal of every calls to dlopen().
Mir driver calls dlopen function. This is not supported by Musl libc :
https://git.musl-libc.org/cgit/musl/tree/src/ldso/dlopen.c
Cosmo libc contains hacks for this I am not sure to understand (uses a bridge with a second process...) see comment on top of https://github.com/jart/cosmopolitan/blob/master/libc/dlopen/dlopen.c
As Mir is a lightweight, portable project I would prefer the sample code to be compatible with static linking options and this seems to require the removal of every calls to dlopen().
Yeah, I think we are on the same page now! Ok, why these libraries don't support dlopen
? This doesn't make sense! You don't need to use a dynamic executable to use dlopen
. In fact, the Linux ELF loader itself is a static executable that brings the code in memory and uses dlopen
to load the libraries. So, unless I don't know (or miss) something, it's the fault of these libraries not support it.
When it comes to Mir, it makes sense that it needs dlopen
if the .bmir
file requires linking with ELF libraries. I suppose, we could have a compilation option (is this how they are called in C projects, right?) that allows you to disable the capability of linking with ELF. Or maybe completely ignore it and just not link with ELF libraries in systems that use that "libc" libraries. But this will mean that you won't be able to use some programs that require linking with other ELF libraries.
You could create a new issue from this reply, as either way, the issue you mention is a different problem than this one. We could continue the conversation there!
You could create a new issue from this reply, as either way, the issue you mention is a different problem than this one. We could continue the conversation there!
I am not confident enough to create an issue, but a discussion : #390