GCC offers many builtin functions, such as memcpy() and vsnprintf():
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
However, many people rewrite their own versions of those functions and use the -fno-builtin option when compiling.
What's the practical reason for doing this; are there dangers in using the GCC builtins?
GCC builtins, to use or not to use?
Re: GCC builtins, to use or not to use?
They may for example use sse2 for memcpy, while you have no sse2 state set up in your kernel.
They may also be implemented in libgcc while you might be not linking it in.
They may also be implemented in libgcc while you might be not linking it in.
Learn to read.
Re: GCC builtins, to use or not to use?
Thanks, I was pretty sure they were optimized but didn't occur to me that may cause problems.
Re: GCC builtins, to use or not to use?
Yes, you do want the compiler builtins. They allow the compiler optimize code such as strlen("foo") to 3. The only reason you won't want to use builtins is when you violate common C semantics by having a strlen function (or something else) that doesn't do what you would expect - but that's pretty crazy in the first place.
However, passing -ffreestanding implies -fno-builtin. That took me by surprise, I thought I was using them in my kernel. You have to explicitly pass -fbuiltin to your kernel build. dozniak suggested that some builtins may be problematic, but I doubt it. If you encounter a bad builtin foo, you can disable it by passing -fno-builtin-foo.
Note that you do want to use libgcc as the compiler will emit calls to it regardless of whether you use it or not. It's almost no extra work to build it and use it.
You should almost never pass -fno-builtin (and if you encounter it in tutorials, delete it) because freestanding code is the only where it makes sense (and it is disabled by default there, so the option is redundant) and you most certainly want them enabled in user-space code (as they are by default).
However, passing -ffreestanding implies -fno-builtin. That took me by surprise, I thought I was using them in my kernel. You have to explicitly pass -fbuiltin to your kernel build. dozniak suggested that some builtins may be problematic, but I doubt it. If you encounter a bad builtin foo, you can disable it by passing -fno-builtin-foo.
Note that you do want to use libgcc as the compiler will emit calls to it regardless of whether you use it or not. It's almost no extra work to build it and use it.
You should almost never pass -fno-builtin (and if you encounter it in tutorials, delete it) because freestanding code is the only where it makes sense (and it is disabled by default there, so the option is redundant) and you most certainly want them enabled in user-space code (as they are by default).
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
Re: GCC builtins, to use or not to use?
You should be careful using compiler builtins (and be sure you have things like -mno-sse if your -march will use SSE etc by default) to ensure that they don't surprise you later.
Being careful is not necessarily the same as outright avoiding them. However, note that one of the primary reasons to not use builtins is to ensure that you always know exactly what a particular operation does. Particularly for somebody new to freestanding development, understanding how a builtin can be broken based on the combination of -march/-mno-*/-On (and by broken, I mean strange, strange behaviour from using say SSE without any init whatsoever) doesn't necessarily come intuitively.
Knowing what a builtin emits in assembly is important when you need to read disassemblies to trace a bug.
So, use them if you can demonstrate they are appropriate when used within your kernel. But if you aren't sure whether they're appropriate, or the thought of disassembling your kernel to identify that the builtins are sane and do what you expect, it's always better to err on the side of caution and avoid them.
Being careful is not necessarily the same as outright avoiding them. However, note that one of the primary reasons to not use builtins is to ensure that you always know exactly what a particular operation does. Particularly for somebody new to freestanding development, understanding how a builtin can be broken based on the combination of -march/-mno-*/-On (and by broken, I mean strange, strange behaviour from using say SSE without any init whatsoever) doesn't necessarily come intuitively.
Knowing what a builtin emits in assembly is important when you need to read disassemblies to trace a bug.
So, use them if you can demonstrate they are appropriate when used within your kernel. But if you aren't sure whether they're appropriate, or the thought of disassembling your kernel to identify that the builtins are sane and do what you expect, it's always better to err on the side of caution and avoid them.