5 ms·
> Heck, I don't understand why -dead_strip isn't enabled by default. My guess would be to facilitate debugging, where you might want to invoke a symbol that wo
by johncolanduoni 8y ago
> Heck, I don't understand why -dead_strip isn't enabled by default.
My guess would be to facilitate debugging, where you might want to invoke a symbol that wouldn't otherwise be used at runtime (e.g. some sort of debug print).
- jacobush 8y agoCan it be also for something dynamically load a symbol and call it? Like for .so making
- userbinator 8y agoYes, as someone with a Windows background I think this is one of the most unusual aspects of the dynamic linking system on Unix-likes --- everything is "exported" by default and the basic system has no concept of linking to symbols from a specific module, it only looks at the symbol name itself. In Windows you have to explicitly specify which symbols to export, and only those exported ones can be imported.
- klodolph 8y agoOn Windows this has the consequence that if you have a DLL, it might use a different malloc than your application. As a result, you can’t safely free objects that were created in a DLL unless you go to all sorts of trouble. This can mean passing objects back into a DLL to free them or using some other mechanism to ensure that you use the same allocator everywhere. This is especially problematic with C++ because of inlining. The “everything is exported” default can be fixed with a flag, you then set symbol visibility with attributes like __declspec or use a linker script. This doesn’t change the calling convention, unlike with DLLs.
- comex 8y agoWhat you said about malloc on Windows is true, but I wouldn’t blame it on symbols not being exported by default – but rather on Windows’ choice to ship N different C runtime libraries, one for each MSVC version, as separate DLLs. Most applications and libraries link to one of those DLLs, and if two images link to the same DLL, they do share C runtime state, including the malloc heap [1]. But that’s only possible if they were compiled with the same MSVC version. (There is also an option, -MT, to fully statically link the C runtime, but it’s less commonly used.) In contrast, both Linux and Darwin have only one C runtime library for the system, in libc.so.6 (typically) or libSystem.dylib respectively, which maintains backwards compatibility over a longer time period. Sometimes there’s a need to make changes to libc that would normally be ABI-breaking, e.g. when off_t was changed to be 64 bits to support >4GB file sizes on 32-bit platforms. But to avoid breakage, special mechanisms are used to provide two different versions of the same symbol within the same library, for each affected symbol; existing binaries will use the old version, while programs compiled and linked on a newer system will automatically use the new version. (On Linux, a complicated mechanism called symbol versioning is used for this, while Darwin just renames symbols with the asm() directive in header files.) On Linux, it is possible to statically link any of various libcs, but programs that do that typically can’t use shared libraries * at all*, so the issue of malloc across library boundaries doesn’t come up. Oh, and for the record, apparently Windows 10 has a new “universal” CRT DLL for new code that will be maintained in place going forward, but it’s still separate from all the pre-existing versioned DLLs, and there’s a debug variant that’s a separate DLL from the normal one and probably doesn’t share state with it. [1] https://msdn.microsoft.com/en-us/library/ms235460.aspx https://msdn.microsoft.com/en-us/library/ms235460.aspx
- userbinator 8y agoThere is one CRT that has existed since Win95 and is still there in Win10, it's called MSVCRT.DLL and getting versions of MSVC other than 6 to link to it is possible and has been done (although not trivial). MS rather strongly discourages this, but as evidenced by all the apps out there that do it and continue to work, it's pretty much the only way to get a single small dynamically-linked binary that'll run on every 32-bit version of Windows ever released. In contrast the "universal" CRT is not very universal at all, and a horrible bloated mess. But certainly not unusual of MS...
- userbinator 8y agoThis can mean passing objects back into a DLL to free them or using some other mechanism to ensure that you use the same allocator everywhere. That's what the LocalAlloc/LocalFree functions are for.
- comex 8y agoOnly if the symbol is exported, but in that case it won’t be removed even if -dead_strip is used. As userbinator noted, Unix has an awful tradition of exporting most symbols by default, which is also in effect on macOS. The modern approach is to pass -fvisibility=hidden to the compiler, which changes the default to unexported, and then mark symbols that are supposed to be exported with __attribute__((visibility(“default”))). Alternately, there’s a Darwin-specific ld option (-exported_symbols_list) where you write a list of names to export in a separate text file, and everything else is forced to be unexported.