← Back to context

Comment by i_don_t_know

2 days 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).

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.

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.