Shared Libraries as Executables
stoppels.ch
stoppels.ch
gcc -fPIC -shared -o test test.c -Wl,--entry,_start -D 'PT_INTERP="/lib64/ld-linux-x86-64.so.2"' /usr/lib64/crt1.o
In Oberon systems object files are executable files. Every object file can have subcommands, like the git command has init, add, commit etc. but it also contains the library functions (like libgit has) in that same object file. In Oberon all those concepts are the same thing.
Why? I mean, what use do you see in executing a shared library? It sounds like adding complicated and unnecessary usecases.
What's wrong with invoking an executable or using libgit?
It seems you're totally missing the whole point. The problem was never that you could not consume libraries from an executable. The actual problem is that you're somehow expecting to consume a third-party package in a way that the project maintainers do not support, let alone maintain.
Adding a build flag that supports a convoluted and arguably useless usecases of linking with symbols shipped in third-party executables change nothing.
Moreover, it is interesting to note that in the same time, the opposite trend exists: some libraries used to be the "meat" of a program, but as connecting two programs in flexible ways is not always easy, that core was extracted and made available directly to other programs. Well-known examples are libCurl and zlib.
http://www.codersnotes.com/notes/a-constructive-look-at-temp...
Another way to look at it is other needs outstrip the mild convenience of packaging library and exe code together.
The concept here is that executables and objects are the same structures and there's no reason why we shouldn't be able to link to a routine found in /bin/ls as we would link to a routine found in libm.so.
This has nothing to do with "packaging library and exe code together."
In the world of client-side rendering, one could ask a somewhat similar question of why HTML and JS files are a different thing, and why you can’t just load a JS file to run your SPA in a browser.
If you want the previous one concept, you can get it via static linking alongside OS IPC.
However it requires more OS resources and is complexer to program.
Now every shared functionality has to do a shared memory or pipe configuration dance, to expose their functionality.
All shared libraries, .NET and COM objects can be consumed by PowerShell scripts and REPL in such way.
It isn't as deeply integrated, but close enough.
For win32, loading executables as code libraries is not officially supported. Now, it does sort-of work, but there are limitations that are totally undocumented. What is officially supported is dynamically loading executables to access resources.
How?
(I've always had great difficulty with the discoverability of powershell features)
https://docs.microsoft.com/en-us/powershell/scripting/sample...
https://devblogs.microsoft.com/scripting/learn-how-to-use-ne...
ubuntu@ip-10-16-0-17:~$ /lib/aarch64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.9) stable release version 2.31.
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 9.4.0.
libc ABIs: UNIQUE ABSOLUTE
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>. $ /lib/x86_64-linux-gnu/libpthread-2.31.so
Native POSIX Threads Library
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Forced unwind support included.The first and most obvious example is the dynamic linker itself."
Maybe it's obvious, but why is the linker itself a shared library? why would you want to link against it?
One of the central libraries in our system as, IIRC, its own main loop that's never run in normal operation - usually the process of injecting it into a target process also ensures it gets set to an entry point that'll actually do stuff.
But you can execute it and it'll just sit there spinning happily on its own like some kind of weird debugging singularity. There must be something we can use it for but I'm not sure what...
If you `readelf -h` an executable on your system and then look up the entry point it gives you in the executable's symbols you'll see it's indeed _start.
The goal would be to use Capnproto RPC but rip the asynchronous part out by dynamically linking the library and rather than using a thread pool you just execute some sort of "message_receive" function with the serialised data in the library. Alternatively, regular capnproto RPC is used over TCP but in this case it wouldn't matter if the library is in the same process or a standalone executable on a different computer with which you can communicate over the network.
Here's my usage scenario: I want to test a subset of the code in a large binary. One thing I could do is to build a test program from a subset of the application's sources, and then call the required code for the test. But that gets laborious in a large codebase.
So could one hack around that, by somehow turning the binary into a shared library, and telling LD to ignore the fact that there's a main() in there, and replace it with a different one?
https://github.com/jevinskie/dylibify/blob/jev/main/dylibify...
Edit: tangent: the excuse nautilus developers have for not having fixed this bug (for probably more than 10 years) is that people should use .desktop files... which don't work to execute an application extracted from a tarball either (because IIRC they want either an absolute path to the executable, or one that is in $PATH, or something along these lines).
The state of desktop Linux just depresses me. Gnome especially, it just gets worse, and never seems to focus on the problems that actually matter.
$ apk add gcc libc-dev
$ gcc -shared -o hello -Wl,--entry,main hello.c -D 'PT_INTERP="/lib/ld-musl-x86_64.so.1"'
$ gcc -o main main.c -L. -l:hello -Wl,-rpath,.
$ ./main
hello
$ ./hello
hello
helloThere are, though, even more sophisticated options than just FFI, like the Witchcraft Compiler Collection [1], which includes among other things an interactive shell.
Standardization seemingly has windows, which if missed, make it far less likely and harder. Even when a need is recognized - eg, python's years of struggle to create a central module repository. But especially when you hit "why would anyone want that?!?" and "we don't approach things that way" barriers.
I recall many years back... dlopen/dlsym can redirect through a lazily-set lookup table, so a seemingly obvious thing to want, is to reset table entries, for live reloading. Given a very simple lookup table, value setting didn't seem a bizarre ask. But "changing a binding?!?" and "there's no standard spec" and "intriguing, but why?" and... I'd not be surprised if it never happened.
I love to see a sketch of the "how hard is it to standardize something, and what you can do about it" space.