Ask HN: Help with LLVM
33 points
3 days ago
| 5 comments
| HN
I'm developing a new language, and everything is pretty nice so far.

I need to know if there's a way to prevent LLVM from linking in CRT symbols entirely. The goal is to make a new runtime.

I have a stub library written in my language, when I go to compile the library in .lib form, I keep running into a wall where LLVM forcefully brings in _fltused, causing my definition to get flagged with an error saying _fltused already exists.

There is nothing in the .ll IR file other than the _fltused definition, the one that I want to have end up in the final .lib.

I have Googled and asked AI for days now what compiler/linker flags I can use to get LLVM to bypass the CRT entirely so I can develop my own runtime, and Clang, MinGW, and LLVM are all aggressively linking in the CRT no matter what flags I add.

I'm pulling my hair out over here. I can't convert my .ll file directly to .as because the LLVM compiler is getting in the way, otherwise I'd have my library by now.

tester756
14 hours ago
[-]
LLVM has active discord server and there's many people who develop LLVM daily and you're more likely to find help there, I think.
reply
bo1024
11 hours ago
[-]
The broad use of discord is so frustrating, how can people find information by searching when it is locked behind registration and not indexed?
reply
Neywiny
15 hours ago
[-]
It might not be documented. You may have to do the grunt work when that happens and read the code.

If you can't find it in the code, my recommendation is to just delete the CRT files and see who screams.

Once you've found it, check up the call stack (either by running a debugger or looking for calls to the functions in the source) and see if any of them have if statements.

If truly not a single conditional is present between main() and linking the CRT, you may just want to add one and submit a patch.

If you can edit your post it would also be helpful to know which flags you've already tried.

reply
andrewf
13 hours ago
[-]
https://devblogs.microsoft.com/oldnewthing/20130108-00/?p=56...

Sounds like this is about making .OBJs that fit in the conventions set by Win32 and the Microsoft linker. If you were using Microsoft's LINK.EXE I'd look at https://learn.microsoft.com/en-us/cpp/build/reference/nodefa... (and /Zi for the Microsoft compiler)

More generally, a lot of compiler generated code (including from LLVM IR -> native) will rely on compiler-specific runtime library functions, which aren't necessarily considered part of the "C runtime". https://wiki.osdev.org/Libgcc occupies this role for GCC-compiled code. See https://godbolt.org/z/fb75PPobz for an example (64-bit division on 32-bit x86 generates a call to ___divdi3)

reply
i_don_t_know
15 hours ago
[-]
I haven't used LLVM in ages. I think it injects references to functions in the CRT when you do certain operations in your code. _fltused is one of them, and I think _ftol? or something like that for floating point numbers is another one. There was also a "security cookie" at some point in the MSVC libs. Unfortunately, I don't remember the linker flags to get rid of that reference, IIRC it had to do with runtime stack checking.

These references do not appear in the .ll file. They are injected when the .ll file is compiled to object files.

I think something in your code triggers a reference to one of the other injected functions and that pulls in the CRT.

Try compiling your test file into an .o or .obj, that is, without linking. Then dump the symbols in the object file to see what symbols are referenced. I suspect you'll see other references to symbols in CRT and you will have to replace those as well with stubs.

Unfortunately, I don't remember the linker flags to replace/suppress the default CRT libs. Well, actually, you might compile to .o / .obj and then manually link on your system. If you're using MSVC check the options to its "link" executable (I don't remember the exact name of the MSVC linker).

reply
coldcity_again
14 hours ago
[-]
Possibly unhelpful for OP, but for MSVC try /NODEFAULTLIB for specific libraries, or IgnoreAllDefaultLibraries to remove everything not explicitly specified to the linker.

On x86 only, if you need to cast floats, try /QIfist (deprecated) to avoid hitting _ftol. Doesn't work for x64 or ARM.

reply
sir-nochill
14 hours ago
[-]
I second this approach, also check with all the verbose flags enabled (eg. clang -v) to get a full list of the linking flags used.

One other thing you may want to try is writing a linker script manually. If you could provide the linker flags as mentioned elsewhere, that would be useful.

reply
wmobit
13 hours ago
[-]
The _fltused handling is quite crude: https://github.com/llvm/llvm-project/blob/5cfd02f44a43a2e2a0...

TLDR it's going to emit the reference if it's targeting MSVC and there's any float typed reference. You'd need to do something to avoid it, other than avoiding float types.

Presumably you are compiling for the MSVC ABI. Trying to plug your own runtime that doesn't behave exactly as the MSVC scheme isn't going to just work out of the box. The compiler has to know the details of the ABI you are targeting, if you're doing your own thing the compiler would need to treat that as a separate ABI. I'm not sure there's a triple now that means MSVC-like-freestanding.

The same logic applies on the clang driver side. The ABI expects to link those libraries, so it will.

reply
wmobit
13 hours ago
[-]
Possibly -ffreestanding will help
reply