I don’t know, I don’t hate the ELF interpreter bit; I actually don’t see why we need to have an ELF parser in the kernel at all—or rather I do, but the answer is likely “setuid”, which, bleh.
The emulating static linking semantics badly bit, though, I do hate, because it just seems so unnecessary and self-inflicted. The entirety of the symbol versioning mess could be reduced to build-time symbol aliases if only we agreed to bind symbols to imported dynamic libraries at build time and not at runtime. (MacOS’s “two-level namespaces” are a hack that tries to retrofit the sane behaviour on top of that, but of course it can’t free you from the underlying mess completely.)
And if we are comparing Unix and its descendants with Windows, isn’t it the case that dynamic linking is, in fact, an afterthought? Windows has had dynamic linking since literally 1.0, because without that you simply can’t fit multiple graphical apps into memory on the kind of machine it was supposed to target. I’d say that early 16-bit Windows essentially is a fancy dynamic linker tied to an overlay manager, plus a cooperative actor/object-like thing, and only then some graphics and input routines on top of all that. At least as far as the application programmer’s mental model is concerned.
Whereas Unix got dynamic linking well into the workstation era, and I remember somebody saying it was an attempt to reduce the memory overhead of Xlib; the classic Unix answer to runtime extensibility would be to spawn a separate process.