<q3k[cis]>
<whitequark[cis]> "py.run" <- works on nixos, my congratulations/condolences
<whitequark[cis]>
nice
<q3k[cis]>
i should try packaging an llvm/clang distro this way
<q3k[cis]>
this might solve my 'god i really need a portable C/C++ toolchain' problem
<whitequark[cis]>
right now lldb doesn't work
<whitequark[cis]>
because of TLS fuckery
<q3k[cis]>
that's fine
<whitequark[cis]>
let me see if clang has the same problem
<whitequark[cis]>
also if you give me a bit of cash i can make sure it does work
<q3k[cis]>
i would give you cash if i had cash
<whitequark[cis]>
gotcha
<whitequark[cis]>
q3k[cis]: it could also be a multicall binary!
<whitequark[cis]>
which is another thing i really want
<q3k[cis]>
yeah you'd probably need that, otherwise you'd end up with libLLVM.so in 20 copies in each tool
<q3k[cis]>
you're currently embedding musl into this, right?
<whitequark[cis]>
llvm actually includes its own multicall binary functionality, but it can't run an internal lld the way it can run internal as
<whitequark[cis]>
q3k[cis]: you can. if you give superlinker musl (must be the last argument) then it embeds musl
<q3k[cis]>
i don't insist
<q3k[cis]>
just curious if glibc is happy to get superlink'd
<q3k[cis]>
(i would assume not?)
<q3k[cis]>
(because of libnss and friends)
<whitequark[cis]>
there are several currently unimplemented relocations
<whitequark[cis]>
re: libnss, this isn't a problem i think
<q3k[cis]>
won't it blow up at runtime if it attempts to dlopen libnss which has been linked against possibly a different glibc?
<whitequark[cis]>
the way it works when you superlink a libc, is that you have two ELF objects resident in the final binary
<whitequark[cis]>
you have the dynamic linker (which in case of musl is also the libc) and you have the main object. the main object should, but currently does not, include DT_SONAME for all of the dynamic objects superlinked into it
<whitequark[cis]>
so dlopen()ing any of those should just return a handle to the app
<q3k[cis]>
ah, i see
<q3k[cis]>
isn't the problem with shoving in libnss is that this might bring with it a bunch of crud, no?
<q3k[cis]>
like ldap and kerberos clients and whatnot
<q3k[cis]>
either that, or you have to not support those and end up with 'incorrect' behaviour on some systems (which is fine, but you know)
<whitequark[cis]>
q3k[cis]: it's just disk space. how much can it cost, ten cents per gigabyte?
<q3k[cis]>
i'm thinking more about the combinatorial explosion of possible versions and behaviours of these versions
<whitequark[cis]>
btw you should check out the way i get python to load extension modules
<q3k[cis]>
i have unfortunately used zipimport before
<whitequark[cis]>
it was shockingly easy to get it to just dlopen itself whenever it needed an extension
<q3k[cis]>
anyway, this sounds like a great start to actually solving portable binaries on linux
<q3k[cis]>
i'm just sorry that you might've cursed yourself into maintaining yet another critical bit of duct tape :P
<whitequark[cis]>
hahahahaha (sobs)
<whitequark[cis]>
you know, superlinker could also be a way to run nix binaries on non-nix systems
<q3k[cis]>
as a translation/interface layer?
<whitequark[cis]>
like, nix can give me a closure of the subset of nix store an application uses, right?
<q3k[cis]>
ah, sorry, read 'nix' as 'linux' for some readon
<whitequark[cis]>
if nix gives me that i can superlink all of the binaries into The Binary and then embed the entire store using the read-only memfd mechanism
<q3k[cis]>
yeah, as long as you redirect /nix/store/* accesses it should work
<q3k[cis]>
(ie. dlopen and open and exec etc should be all redirected)
<whitequark[cis]>
yep
<whitequark[cis]>
i think this is by far the funniest way to distribute applications
<whitequark[cis]>
forget flatpak, appimage, and snap
<q3k[cis]>
also you'll probably have to work around some hacks where people run syscalls directly
<q3k[cis]>
(not just in libc)
<whitequark[cis]>
oh, it can use syscall user dispatch
<q3k[cis]>
Catherine: also you might be able to do the same thing for docker/oci images
<q3k[cis]>
probably semi-automatically
<whitequark[cis]>
you've heard of unfork, now prepare for undocker
<q3k[cis]>
(i have this long running brainworm that makes me want to make a docker compatible stub, call it 'focker' or something)
<q3k[cis]>
('focker' for 'fat docker binary')
<whitequark[cis]>
do you wanna collab on this or something
<q3k[cis]>
possibly! but you seem to be making fast progress now, and right now i'm super busy with other projects
<q3k[cis]>
so i would probably only impede you
<whitequark[cis]>
i ask because i have* depression* and it gets much easier if i don't have to stare at binaries all day alone
<whitequark[cis]>
* not exactly but close enough for how long the description is
<whitequark[cis]>
* i ask because i have* depression* and it gets much easier if i don't have to stare at binaries all day alone
<whitequark[cis]>
* not exactly but close enough for how long the description is
<whitequark[cis]>
s/*/\*/, s/*/\*/, s/*/\*/
<q3k[cis]>
it sounds super interesting, but yeah, i have other things to finish for now :/
<whitequark[cis]>
actually thinking more about it, seccomp would do the job better than syscall user dispatch
<q3k[cis]>
yes
<whitequark[cis]>
do a SECCOMP_RET_USER_NOTIF on open/openat/execve/execveat in the ranges that exclude only the shim itself
<q3k[cis]>
an interesting experiment with the codebase right now would be to also slurp in all of mesa/libvk and see if that works
<whitequark[cis]>
this relies on either (a) restricting the flexibility to interpose filesystem access to only straightforward things like "detect nix store" or (b) making the shim able to self-relocate
<whitequark[cis]>
slurping in mesa will almost certainly break because of TLS
<q3k[cis]>
peh
<whitequark[cis]>
i mean i should just implement proper TLS handling
<whitequark[cis]>
it's not that difficult, it's just finicky and weird
<whitequark[cis]>
it's like within an executable image, you have a TLS image with its own address space and relocation rules
<whitequark[cis]>
anyway i was looking at clang. so one other thing i currently just don't implement is exception handling
<whitequark[cis]>
it's really not that difficult either, it's a table that i need to copy around and relocate. i think
<whitequark[cis]>
actually i might be able to get away with just copying several PT_GNU_EH_FRAME into the final binary, i need to look at the libstdc++ unwinder again
<whitequark[cis]>
lol. did you know that linux really doesn't like binaries with >60 phdrs?
<whitequark[cis]>
wow, adding libclang really causes the emit stage to take a while
<whitequark[cis]>
also the resulting binary spends 7.5 seconds (!!) launching
<whitequark[cis]>
all of the DT_* addresses are currently treated as phys==virt and it's not right
<q3k[cis]>
ah, ok
<whitequark[cis]>
i first hit it with DT_INIT_ARRAY
<whitequark[cis]>
and in fact init/fini handling does address translation properly
<whitequark[cis]>
so yeah, linking in both libclang and libllvm fails because it can't merge TLS images
<whitequark[cis]>
let me try glxgears
<whitequark[cis]>
yeah so it instantly segfaults, because mesa is using TLS descriptors
galibert[m] has joined #glasgow
<galibert[m]>
Cat, you're doing dark magic, again ?
<whitequark[cis]>
again? i never stopped
<galibert[m]>
Oh, carry on then
<whitequark[cis]>
i really need a working TLS impl
<q3k[cis]>
Catherine: is there also an issue where the resulting segments get moved to a virtaddr 0 base?
<q3k[cis]>
(i have a test_exec.elf with base of 0x40000 as above, but it seems like merged.elf these get remapped to 0x0)
<whitequark[cis]>
q3k[cis]: superlinker assumes that any ELF you feed it is position-independent and so it moves the segments to be sequential starting at roughly 0, with a phys==virt correspondence
<q3k[cis]>
hm, so i don't know why the merged elf tries to jump to a higher address
<whitequark[cis]>
(and offset is the start address of the non-x mapping you see in the output)
<whitequark[cis]>
you know
<q3k[cis]>
i'll do that after i have my breakfast
<whitequark[cis]>
i should just write a symbolizer that doesn't depend on gdb or something
<whitequark[cis]>
the shim could install a SEGV handler that does dl_iterate_phdr to get the relocated addresses of all the constituent libraries and then like return a JSON of it or whatever