Using GCC's built-in functions instead of self-written ones

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Neroku
Posts: 24
Joined: Tue Dec 01, 2015 4:53 am

Using GCC's built-in functions instead of self-written ones

Post by Neroku »

Hello,

I've been using for a while my own functions like memset(), strcmp() and so on. After I found a bug in one of them I decide to use the GCC's built-in functions instead of mine. =;
In the section "Other Builtins" of the GCC's manual state the following:
GCC includes built-in versions of many of the functions in the standard C library. These functions come in two forms: one whose names start with the __builtin_ prefix, and the other without.
The ISO C90 functions abort, abs, acos, asin, atan2, atan, calloc, ceil, cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, frexp, fscanf, isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit, tolower, toupper, labs, ldexp, log10, log, malloc, memchr, memcmp, memcpy, memset, modf, pow, printf, putchar, puts, scanf, sinh, sin, snprintf, sprintf, sqrt, sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf, vprintf and vsprintf are all recognized as built-in functions unless -fno-builtin is specified
I am implicitly using the -fno-builtin compiler option by passing the -ffreestanding option to the compiler.
In the section "C Dialect Options" of the GCC's manual it is found the following:
-fno-builtin
-fno-builtin-function
Don't recognize built-in functions that do not begin with ‘__builtin_’ as prefix.
if you wish to enable built-in functions selectively when using -fno-builtin or -ffreestanding, you may define macros such as:

#define abs(n) __builtin_abs ((n))
#define strcpy(d, s) __builtin_strcpy ((d), (s))
What's written above is what I am doing, however I keep on getting error messages at linking similar to the one below:

Code: Select all

fat16.c:(.text+0x4fb): undefined reference to 'strncmp'
I am also linking all the objects against -lgcc (placing it at the very end of the line). It seems GCC is not linking these functions against its built-in functions :cry:
Any ideas? #-o


Thanks in advance
currently working on kboot86, the Genesis of my kernel
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Using GCC's built-in functions instead of self-written o

Post by Octocontrabass »

Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function is emitted.
User avatar
Neroku
Posts: 24
Joined: Tue Dec 01, 2015 4:53 am

Re: Using GCC's built-in functions instead of self-written o

Post by Neroku »

Octocontrabass wrote:
Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function is emitted.
I've just prepared an example where I expect the function to be optimized:

Code: Select all

size_t len;
len = strlen("foo");
...and I don't get now the undefined reference error message. =D>


My assumptions about GCC's built-in functions were wrong. ](*,)
Then, we must implement these functions in our code if we want to be able to use them for all the scenarios, mustn't we?


Thanks a lot.
currently working on kboot86, the Genesis of my kernel
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Using GCC's built-in functions instead of self-written o

Post by gerryg400 »

That's correct. You need to have all the functions in your libc just in case gcc decides not to optimise. BTW, some of the optimisations call other functions. For example, printf() will often be optimised as puts() or putchar(). Basically gcc expects a conforming libc.
If a trainstation is where trains stop, what is a workstation ?
User avatar
Neroku
Posts: 24
Joined: Tue Dec 01, 2015 4:53 am

Re: Using GCC's built-in functions instead of self-written o

Post by Neroku »

I was mixing up basic concepts such as built-in functions and the libgcc.
Built-in functions are placed by the compiler (hence the name). Regarding the libgcc, from "The GCC low-level runtime library":
Most of the routines in libgcc handle arithmetic operations that the target processor cannot perform directly. This includes integer multiply and divide on some machines, and all floating-point and fixed-point operations on other machines. libgcc also includes routines for exception handling, and a handful of miscellaneous operations.
For that reason I wasn't able to find text-code-section symbols like memcpy or memset in the libgcc I was linking my object files against.

Thanks to all of you :D
currently working on kboot86, the Genesis of my kernel
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: Using GCC's built-in functions instead of self-written o

Post by glauxosdever »

Hi,

https://gcc.gnu.org/onlinedocs/gcc/Standards.html wrote:Most of the compiler support routines used by GCC are present in libgcc, but there are a few exceptions. GCC requires the freestanding environment provide memcpy, memmove, memset and memcmp. Finally, if __builtin_trap is used, and the target does not implement the trap pattern, then GCC emits a call to abort.
So you actually need only memcmp(), memcpy(), memmove(), memset() and abort().

Also, I don't see why is writing a couple of string functions so hard and troublesome. They are at most 10 lines of C code on average. And if you have trouble implementing them correctly, there is the POSIX specification. For example here is the specification for memcmp().


Regards,
glauxosdever
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Using GCC's built-in functions instead of self-written o

Post by FallenAvatar »

glauxosdever wrote:Hi,

https://gcc.gnu.org/onlinedocs/gcc/Standards.html wrote:Most of the compiler support routines used by GCC are present in libgcc, but there are a few exceptions. GCC requires the freestanding environment provide memcpy, memmove, memset and memcmp. Finally, if __builtin_trap is used, and the target does not implement the trap pattern, then GCC emits a call to abort.
So you actually need only memcmp(), memcpy(), memmove(), memset() and abort().

Also, I don't see why is writing a couple of string functions so hard and troublesome. They are at most 10 lines of C code on average. And if you have trouble implementing them correctly, there is the POSIX specification. For example here is the specification for memcmp().


Regards,
glauxosdever
How easy is it to implement them as effeciently as possible? (And who the heck mentioned POSIX? [which is outdated garbage at this point...])

- Monk
User avatar
Neroku
Posts: 24
Joined: Tue Dec 01, 2015 4:53 am

Re: Using GCC's built-in functions instead of self-written o

Post by Neroku »

glauxosdever wrote:
https://gcc.gnu.org/onlinedocs/gcc/Standards.html wrote:Most of the compiler support routines used by GCC are present in libgcc, but there are a few exceptions. GCC requires the freestanding environment provide memcpy, memmove, memset and memcmp. Finally, if __builtin_trap is used, and the target does not implement the trap pattern, then GCC emits a call to abort.
So you actually need only memcmp(), memcpy(), memmove(), memset() and abort().
Then, how I can use every time the string functions provided by GCC (i.e.: the built-in string functions)?
Seemingly, it only works when GCC is able to optimize the call to these functions, e.g.: when the string passed to strlen() can be determined at comile-time:
Octocontrabass wrote:
Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function is emitted.
Besides, I don't find these string functions in the libgcc.

Code: Select all

nm libgcc.a | grep str
         U strlen
         U strlen
Am I making wrong assumptions?


Thanks in advanced
currently working on kboot86, the Genesis of my kernel
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: Using GCC's built-in functions instead of self-written o

Post by glauxosdever »

Hi,

Neroku wrote:Then, how I can use every time the string functions provided by GCC (i.e.: the built-in string functions)?
Simple, you implement them. Or you use __builtin_function instead of function.

I still can't understand what is wrong with writing a couple of string functions. For example strlen() can be implemented like this:

Code: Select all

size_t strlen (const char* s)
{
	size_t i = 0;
	while (s[i] != '\0')
	{
		i += 1;
	}
	return i;
}
Is it really so hard? If so, writing an operating system is impossible compared to that.
tjmonk15 wrote:And who the heck mentioned POSIX? [which is outdated garbage at this point...]
POSIX specifies these functions most correctly. Man pages on your Linux system often have flaws.


Regards,
glauxosdever
User avatar
Neroku
Posts: 24
Joined: Tue Dec 01, 2015 4:53 am

Re: Using GCC's built-in functions instead of self-written o

Post by Neroku »

Hello glauxosdever,

let's go one step at a time:
  • glauxosdever wrote:I still can't understand what is wrong with writing a couple of string functions.
    I think you could be taking me wrong. The topic of this post is not about implementing your own string functions, but how to use the ones already provided.
    It is not as if I got stuck, since I can use my own functions, but I would really know what's going wrong here.
  • glauxosdever wrote:
    Neroku wrote:Then, how I can use every time the string functions provided by GCC (i.e.: the built-in string functions)?
    Simple, you implement them. Or you use __builtin_function instead of function.
    That's actually my problem. By writing just __builtin_function instead of function I don't get it working. For instance, I get the following regarding to the strncmp():

    Code: Select all

    fat16.c:(.text+0x4fb): undefined reference to 'strncmp'

I assume GCC only links against the built-in functions when it is not able to optimize the function call, otherwise it looks for a function in a library, just as Octocontrabass suggested:
Octocontrabass wrote:
Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function is emitted.
But I may be wrong... #-o
Any ideas?


Thanks a lot
currently working on kboot86, the Genesis of my kernel
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Using GCC's built-in functions instead of self-written o

Post by Octocontrabass »

glauxosdever wrote:
Neroku wrote:Then, how I can use every time the string functions provided by GCC (i.e.: the built-in string functions)?
Simple, you implement them. Or you use __builtin_function instead of function.
Builtin functions are not replacements for C library functions. If you want to use a builtin function, you must also have a working implementation of that function in your C library.
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: Using GCC's built-in functions instead of self-written o

Post by glauxosdever »

Hi,

Octocontrabass wrote:Builtin functions are not replacements for C library functions. If you want to use a builtin function, you must also have a working implementation of that function in your C library.
It seems you are right. I missed this point (emphasis mine):
https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html wrote:GCC includes built-in versions of many of the functions in the standard C library. These functions come in two forms: one whose names start with the __builtin_ prefix, and the other without. Both forms have the same type (including prototype), the same address (when their address is taken), and the same meaning as the C library functions even if you specify the -fno-builtin option see C Dialect Options). Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function is emitted.
Neroku wrote:It is not as if I got stuck, since I can use my own functions, but I would really know what's going wrong here.
Still, built-in functions are such a hassle, so you should better not rely on them. As for wanting to know what is wrong here, it is because these functions you are trying to use are nowhere declared and at the same time the built-ins emit a call to them, as proven just above.

I hope I helped. :)


Regards,
glauxosdever
User avatar
Rusky
Member
Member
Posts: 792
Joined: Wed Jan 06, 2010 7:07 pm

Re: Using GCC's built-in functions instead of self-written o

Post by Rusky »

To clarify a bit, the builtin functions are not actually functions. They are bits of compiler magic that let the compiler understand the intent of a function, and only come into play in cases where the optimizer feels like it's a good idea to generate some code inline. When the optimizer feels like it'd be better to call out to a full implementation, it needs a separate full implementation, since the builtin functions don't actually provide any code.

With that in mind, you need to provide your own implementations (or use a libc's), and then the builtin functions are just a way to get a free performance boost (either by turning or leaving on -fbuiltin or by calling __builtin_ functions).
User avatar
Neroku
Posts: 24
Joined: Tue Dec 01, 2015 4:53 am

Re: Using GCC's built-in functions instead of self-written o

Post by Neroku »

Now, that I think the question is clear for all of us, I'm making my proposal: considering I want to let GCC replace the calls to my library functions with its built-in functions whenever possible.

I define a preprocessor macro for each function I want to let GCC to be replaced. This macro expands to the text __builtin_ prefixed to the actual function name. I surround the corresponding functions's prototype with a conditional directive checking against the inexistence of the just-defined preprocessor macro. Finally I provide the code for my function being preceded by the preprocessor directive #undef which does away with the previously defined macro.

For example, for strlen() I would proceed just as follows:
In the file string.h:

Code: Select all

#define strlen(s)    __builtin_strlen((s))
...
#ifndef strlen
size_t strlen(const char *);
#endif
In the file string.c:

Code: Select all

#include <string.h>

#undef strlen
size_t strlen(const char *s)
{
    // my implementation
    ...
}
Any suggestions are welcome.

Thank you, all of you.
currently working on kboot86, the Genesis of my kernel
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Using GCC's built-in functions instead of self-written o

Post by Combuster »

I want to let GCC replace the calls to my library functions with its built-in functions whenever possible.
Why don't you just simply compile with optimisations enabled instead of doing all these ifdefs? That way you can't mess things up.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply