Meanwhile, I am concentrating to something I believe I could do: port SBCL to Haiku x86. I expect it to only work with recent gcc, no BeOS compatibility. So, before build I use:
setarch x86
And I already hit a problem. To detect features provided by OS, which do not need to be emulated, SBCL uses short C programs and watches their exist code. One of these programs compiles and executes without any issue with gcc2 but compiles with warnings and fails during execution with modern gcc13. It makes use of:
warning: implicit declaration of function 'getprotobyname_r'; did you mean 'getprotobyname'?
warning: implicit declaration of function 'getprotobynumber_r'; did you mean 'getprotobynumber'?
These functions are expected to be defined in header file, not in this program. As result, compiled with gcc2 the program is 16.56 KB compared to just 5.79 KB compiled by gcc13. The situation looks like some devel package is missing for gcc13. However, readelf -d os-provides-getprotoby-r-test only lists:
The program is auxiliary and compiled with gcc2 it works exactly the same in x86 and x86_gcc2 environments. It may be unnecessary to actually compile it with gcc13, but I am unsure.
So, I have 2 questions:
Is it possible after setarch x86 to compile something with gcc2?
Is there some devel package I could install to get this program compiled with gcc13?
~> lgrep getprotoby
/boot/system/lib/x86/libnetwork.so:00014160 T getprotobyname
/boot/system/lib/x86/libnetwork.so:000141b0 T getprotobyname_r
/boot/system/lib/x86/libnetwork.so:00014290 T getprotobynumber
/boot/system/lib/x86/libnetwork.so:000142e0 T getprotobynumber_r
At least one error in the 2.5.0 recipe, cmd:gcc$secondaryArchPrefix should be cmd:gcc$secondaryArchSuffix
Having said that, it expects a value for sbcl_arch? (fixed with an export ā¦)
Another edit, the archive doesnāt seem to contain genesis directory/code? (seems to be triggered with export SBCL_ARCH=x86.
SBCL contains platform specific source code (Config.x86-haiku, x86-haiku-os.h, x86-haiku-os.c), which is at the moment missing. Without them, it is impossible to build something really helpful for this unsupported platform.
I do not yet use haikuporter and the problems mentioned by me are plain gcc problems.
Is libnetwork_devel contained in haiku_devel package or is it a 3rd party library? How is it possible that it is available for gcc2 and not available for gcc13?
This file is already included. Again, it is visible for gcc2 but not for gcc13.
A more in-depth question is: What exactly does setarch? I imagine it sets some simlinks to proper gcc binaries, headers and libraries. Does it changes something else system-wide (something similar to what chroot does)?
setarch switches compiler as you already found out, it also alters the paths to library/headers to look for, like lib/x86 instead of lib or develop/headers/x86 ā¦ (most of these are defined by the packages required).
Itās part of Haiku, so should be included in haiku_x86_devel for 32bit.
Found different packages haiku_devel and haiku_x86_devel, both are installed by default.
After analysis of /boot/system/develop I found common folder headers and separate folders lib and lib/x86. The header netdb.h contain functions getprotobyname and getprotobynumber but does not contain (low level) functions getprotobyname_r and getprotobynumber_r. The former (without _r) probably call the later (with _r suffix). But the difference between gcc2 and gcc13 is these low level functions are exposed to user for gcc2 but are hidden in private API in gcc13.
With assumption of relativity of these functions, I adapted the test code to call functions getprotobyname and getprotobynumber and no more crash occurs.
Still I do not go far forward in porting SBCL to x86 Haiku.
Looking at the headerās information itās part of haiku_devel (gcc2), seeing itās available as /boot/system/develop/headers/posix I assume it would be available cross arch? (not an expert on the matter).
Searching it on haikuports doesnāt really mention any patching for it:
Same for me. But netdb.hdoes not contain functions getprotobyname_r and getprotobynumber_r. I did not find them in any available header. My assumption is these functions are available elsewhere in private API, which for some reason is visible for gcc2 but not for gcc13.
Anyway, I configured and tested 2 possible solutions (I do not know how reliable are they):
Build SBCL with gcc13 but auxiliary feature tests (features provided by OS) with gcc2
Change this test to call getprotobyname and getprotobynumber instead as they are directly available in the header (assuming these function implementation make use of getprotobyname_r and getprotobynumber_r defined somewhere else).
The warning is harmless, it just means the function is not defined in a header and the compiler attempted to guess at its prototype. gcc2 likely has the same issue, but doesnāt bother you with a warning about it, because in old versions of C, this was a normal thing to do.
If the function was private or did not exist, you would get a linker error (āundefined referenceā or similar).
So Iām confused about the situation where the program linked correctly (meaning the function is found), but then fails to execute.
Thatās possible, but would result in a linker error, not an execution error.
The _r functions are reentrant, which means they are safe to use in threaded environments. The ones without _r may not be. Since you already have problems with threading in SBCL, maybe that is not such a great idea?
The size difference of binaries compiled with gcc2 and gcc13
The crash running program compiled with gcc13
When compiled with gcc2 there are no compilation warning and program exists with 104 code, i.e. works as intended. So, I guess, the _r variants of functions are visible for gcc2.
Depending on how these functions are used in SBCL, my defending approaches may be relevant or irrelevant. But before I reach SBCL team with this question, I would like to know more about presence / accessibility of _r variants of these functions for gcc13.
I had a look at it, here are my conclusions (this applies to both functions tested, but I refer to only one for simplicity):
getprotobyname_r is not a standardized function in POSIX
in Haiku, getprotobyname is thread safe (by using a mutex) but slower than getprotobyname_r (which does not need a mutex)
since the function is non-standard, different versions of it exist. The one in Haiku is identical to the one in NetBSD and has a different prototype: struct protoent* getprotobyname_r(const char*, struct protoent*, struct protoent_data*);
However, it is not declared in any public .h files. Which means the compiler canāt detect this problem, and tries to pass the arguments anyways. The linker also cannot check it (it would in C++, but not in C).
The function is called with invalid arguments and crashes.
I think the solution is to make this test behave the same as in NetBSD, by changing the #if __NetBSD__ to #if __NetBSD__ || defined(__HAIKU__). Then these functions will be marked as ānot usableā and you should be fine.
I doubt I fully understand the way C++ handles functions with identical name but different signature. I just want to make sure that Haiku x86 and Haiku x86-64 has the same signature of getprotobyname_r and getprotobynumber_r functions, and thus neither Haiku x86 nor x86-64 provide them as SBCL expects. Is this understanding right, @PulkoMandy?
Yes, itās the same for both architectures. The code for these functions is imported from NetBSD, and is incompatible with what SBCL expects in the same way as for NetBSD.