Closed jacereda closed 3 years ago
I've noticed this comment:
OpenBSD does indeed use auxv, it's just the constants aren't called PT_XXX
. They use instead AuxId
from https://github.com/openbsd/src/blob/b996670b127aa2bbace3bf72918329136b33fbf2/sys/sys/exec_elf.h#L681
At least on 7.0 I can inpect auxv values, but I don't know if that was true on earlier versions...
This is what auxv looks like on OpenBSD 7.0:
AUX_phdr c9c7c663040
AUX_phent 38
AUX_phnum c
AUX_pagesz 1000
AUX_base c9f40545000
AUX_flags 0
AUX_entry c9c7c664720
AUX_openbsd_timekeep c9e86bc6000
@jart Any hint on who could be stripping the auxv info?
I had a feeling this day might come. I'm going to install OpenBSD 7.0 and take a look. That header file says auxv isn't part of the ABI but that may have changed recently.
OK APE binaries still appear to work fine on OpenBSD 7.0. Taking a second look at the header it might be the case that OpenBSD only passes auxiliary values to dynamic shared object executables. It'd be interesting if there was a way of obtaining those values in a normal executable, but judging by the list you shared, there doesn't appear to be anything there we need. It might be nice to have AUX_openbsd_timekeep
assuming it is what I think it is, but that's something which can easily be worked around by using something like nowl()
.
APE binaries work fine, but I'm having trouble loading the helper executable that prepares for dlopen
.
I do need the auxv to make dlopen
work, I'm getting crashes when jumping to the dynamic interpreter and I suspect this is the reason.
I also thought only dynamic executables would get auxv, but I've tried to compile a static test executable that dumps auxv values and it still dumps the auxv properly.
@jart can we leave this open?
I have some WIP adding the AT_xxx
values for OpenBSD to consts.sh
and modifying loader.c
and systemfive.S
to detect OpenBSD via AUX_openbsd_timekeep
instead of using the empty auxv, do you want me to open a draft PR with that?
Looks like even static executables are dynamic somehow...
#include <stdio.h>
#define _DYN_LOADER
#include <elf.h>
int
main(int argc, char* argv[], char* envp[])
{
while(*envp++);
for (AuxInfo * au = (AuxInfo *)envp; au->au_id; au++)
{
#define D(x) if (au->au_id==x) printf(#x " %llx\n", au->au_v)
D(AUX_phdr);
D(AUX_phent);
D(AUX_phnum);
D(AUX_pagesz);
D(AUX_base);
D(AUX_flags);
D(AUX_entry);
D(AUX_openbsd_timekeep);
}
}
/ssh:jacereda@localhost#2222:/home/jacereda/ #$ cc -static aux.c
cc -static aux.c
/ssh:jacereda@localhost#2222:/home/jacereda/ #$ ./a.out
./a.out
AUX_phdr 9fd3190c040
AUX_phent 38
AUX_phnum b
AUX_pagesz 1000
AUX_base 9fd3190c000
AUX_flags 0
AUX_entry 9fd31911940
AUX_openbsd_timekeep a0012776000
/ssh:jacereda@localhost#2222:/home/jacereda/ #$ ldd a.out
ldd a.out
a.out:
Start End Type Open Ref GrpRef Name
000002dd9b03f000 000002dd9b062000 dlib 1 0 0 /home/jacereda/a.out
/ssh:jacereda@localhost#2222:/home/jacereda/ #$
Notice the dlib
type. Maybe it has something to do with ASLR on static executables?
How are you getting the auxv values?
Did you get a chance to read https://github.com/jart/cosmopolitan/issues/35#issuecomment-951864818 by the way? What did you think of my suggestion? I ask because GUIs are nice to have but I'm not willing to migrate away from the executable model towards dynamic shared objects in order to have them. The only way to develop GUIs the way you want to build them is to use the tools that are provided by each individual platform, which they control, and it would be hard for us to maintain a contribution we don't have any control over.
I read it, but I don't get the rationale. Why use the terminal when you can have a normal native window and OpenGL rendering via dlopen
? Offscreen rendering will involve a readback operation, that's usually a non-optimized path in most GPUs and will also introduce additional traffic in the PCI bus.
As of now, I have tested the demo on Windows and some Linux distributions (NixOS, Ubuntu, Debian) and looks like FreeBSD should work because I've reached the point where it opens the window and creates the context, but it crashes after a few operations . Probably because I'm running through emulation.
Maybe I'll figure out some way to get it running on OpenBSD that doesn't involve moving to DSOs... I'll try to construct a fake auxv and see how it goes.
Failing that, maybe we can just wait until someone with carnal knowledge about OpenBSD puts a remedy to the situation.
As for NetBSD, I can't get the latest image running on qemu.
The only way to develop GUIs the way you want to build them is to use the tools that are provided by each individual platform
I don't get this. I don't want to build GUIs using any tool, I think https://github.com/vurtun/nuklear https://github.com/cimgui/cimgui or https://github.com/rxi/microui are the way to go. But someone might disagree and might prefer to adapt something like https://github.com/andlabs/libui once dlopen
is in place.
Because Cosmopolitan doesn't support dynamic shared objects. You can read more about the problems they have in Ulrich Drepper's paper. It's incompatible with the core development model. Every platform does them differently. They can only be used if you depend on the platform's C library which means we'd need to stop using our own. If you want to link system libraries into the process address space then the recommended approach is to use the platform local tools to build a driver program and launch it as a subprocess.
I'm not sure I explained my approach properly. What I'm doing (inspired by https://github.com/pfalcon/foreign-dlopen )
dlfcn
entry points. https://github.com/jacereda/cosmogfx/blob/01b58a23bd15373536c1496c3d8e7c8bdd109636/cosmogfx.c#L35dlopen
libraries. I'm aware of problems caused by having several runtimes coexisting in an application, but I think those will only affect broken APIs (like something returning malloc
ed memory and expecting the caller to just free
it without passing through the library). Am I missing something else? Something that could affect OpenGL?
You know your business. If I understand correctly, you can assure us that the namespaces are disjoint. Sort of like how in Go if you want to call platform C functions you use the naming C.free()
. This can work. In that case, the biggest obstacle you're likely to encounter with OpenBSD isn't auxiliary values, it's msyscall()
. OpenBSD has a feature where the kernel checks the RIP provenance of SYSCALL
instructions. Only one contiguous memory range is permitted and msyscall()
can only be called once. On process birth, it defaults to the .text section specified by the loaded PHDR. When we load the OpenBSD C library we likely have two choices. The first is that we use //third_party/xed to rewrite its instructions so they indirect through Cosmopolitan Libc. The second is we might be able to get away with just saying msyscall(0,2**47-1)
but ideally it's nice to conform to platform norms and intentions in spirit whenever possible.
As for NetBSD the second time's a charm. Cosmopolitan initially didn't support it, since I failed in my first attempt to install it. Then the second time I tried, many months later, the process just worked for some reason. Still haven't figured out how to get the man pages and a working compiler installed, although I hear their way of installing things is actually very good if you take the time to grok it.
While trying to get OpenGL running on OpenBSD I noticed auxv is empty. Why is that?