Add -Os to the libpayload CFLAGS
On Wed, Mar 19, 2008 at 06:27:12PM -0600, Jordan Crouse wrote:
libpayload: Add -Os to the CFLAGS
Adding -Os to the CFLAGS gains us about 25% smaller code (give or take). Unfortunately, it exposes a strange issue where strcpy() suddenly goes missing - we think that strcpy() is being provided by libgcc, and that for some reason, -Os changes the beahavior. Oh, well - add a quick strcpy() function and we're good.
Signed-off-by: Jordan Crouse jordan.crouse@amd.com
Thanks, r3175.
Uwe.
Unfortunately, it exposes a strange issue where strcpy() suddenly goes missing - we think that strcpy() is being provided by libgcc, and that for some reason, -Os changes the beahavior.
strcpy() isn't part of libgcc. What happened is that without -Os, the compiler will inline certain invocations of strcpy() as a builtin.
+char *strcpy(char *d, const char *s) +{
- return strncpy(d, s, strlen(s));
+}
This doesn't put a terminating 0 on the string.
Segher
On 20/03/08 04:03 +0100, Segher Boessenkool wrote:
Unfortunately, it exposes a strange issue where strcpy() suddenly goes missing - we think that strcpy() is being provided by libgcc, and that for some reason, -Os changes the beahavior.
strcpy() isn't part of libgcc. What happened is that without -Os, the compiler will inline certain invocations of strcpy() as a builtin.
What other builtin functions do we need to be worried about?
+char *strcpy(char *d, const char *s) +{
- return strncpy(d, s, strlen(s));
+}
This doesn't put a terminating 0 on the string.
Oops - he's right. Uwe, can you do a quick fix?
Jordan
strcpy() isn't part of libgcc. What happened is that without -Os, the compiler will inline certain invocations of strcpy() as a builtin.
What other builtin functions do we need to be worried about?
All of them. You have to provide all C library functions you use; there is no guarantee that GCC will inline any of them. Builtin functions like this are purely an optimisation, and the compiler makes choices based on if the tradeoffs involved make the inlining worthwhile. With -Os, it won't inline much, but it will still do some.
Segher
On Thu, Mar 20, 2008 at 04:36:13PM +0100, Segher Boessenkool wrote:
With -Os, it won't inline much, but it will still do some.
-fno-inlines -fno-inline-functions ?
//Peter
With -Os, it won't inline much, but it will still do some.
-fno-inlines -fno-inline-functions ?
That won't prevent GCC from doing builtins; -fno-builtin is for that.
There is no real reason to do any of this though; GCC's choices are generally sane ones. Jordan's problem was just a silly "forgot to provide a definition of some function" problem, this won't happen too often I hope ;-P
Segher
On Thu, Mar 20, 2008 at 08:51:39AM -0600, Jordan Crouse wrote:
+char *strcpy(char *d, const char *s) +{
- return strncpy(d, s, strlen(s));
+}
This doesn't put a terminating 0 on the string.
Oops - he's right. Uwe, can you do a quick fix?
How about this? Untested, but should work.
Uwe.
On Thu, Mar 20, 2008 at 05:26:17PM +0100, Uwe Hermann wrote:
This doesn't put a terminating 0 on the string.
How about this? Untested, but should work.
char *strcpy(char *d, const char *s) {
- return strncpy(d, s, strlen(s));
- char *orig = d;
- while ((*(d++) = *(s++)));
- return orig;
}
I'd try to reuse strncpy() so that any optimizations need to be done in as few places as possible.
Save strlen() and just append the 0.
//Peter
I'd try to reuse strncpy() so that any optimizations need to be done in as few places as possible.
Save strlen() and just append the 0.
Just do strlen() + 1, heh.
Or do Uwe's thing (without the parentheses around d and s, and with the loop body on a separate line, coding standards...) if you are terribly worried about performance here. Or just import from some existing C library, no need to reinvent the wheel, and some of these functions can be quite tricky to get right ;-)
Segher
On Thu, Mar 20, 2008 at 06:03:08PM +0100, Segher Boessenkool wrote:
I'd try to reuse strncpy() so that any optimizations need to be done in as few places as possible.
Save strlen() and just append the 0.
Just do strlen() + 1, heh.
Yes of course. :)
Or do Uwe's thing (without the parentheses around d and s, and with the loop body on a separate line, coding standards...) if you are terribly worried about performance here. Or just import from some existing C library, no need to reinvent the wheel, and some of these functions can be quite tricky to get right ;-)
Well the memcpy() from HelenOS seemed to be a bit optimized already so would be good to reuse it via strncpy().
//Peter
On Thu, Mar 20, 2008 at 06:08:13PM +0100, Peter Stuge wrote:
On Thu, Mar 20, 2008 at 06:03:08PM +0100, Segher Boessenkool wrote:
I'd try to reuse strncpy() so that any optimizations need to be done in as few places as possible.
Save strlen() and just append the 0.
Just do strlen() + 1, heh.
Yes of course. :)
So is this ok?
- return strncpy(d, s, strlen(s)); + return strncpy(d, s, strlen(s) + 1);
Or do Uwe's thing (without the parentheses around d and s, and with the loop body on a separate line, coding standards...) if you are terribly worried about performance here. Or just import from some existing C library, no need to reinvent the wheel, and some of these functions can be quite tricky to get right ;-)
Well the memcpy() from HelenOS seemed to be a bit optimized already so would be good to reuse it via strncpy().
Hm? strncpy doesn't call memcpy().
Uwe.
So is this ok?
return strncpy(d, s, strlen(s));
return strncpy(d, s, strlen(s) + 1);
It is okay, yes.
Well the memcpy() from HelenOS seemed to be a bit optimized already so would be good to reuse it via strncpy().
Hm? strncpy doesn't call memcpy().
Hey, you could factor it into strlen() + memcpy() + memset() [*], if you don't mind walking the string twice. You could use memcpy() instead of strncpy() in your strcpy(), too, for a minor optimisation.
It's really not worth it if you ask me; an optimised memcpy() -- and, to a lesser degree, an optimised memset() -- might be noticeable, but for the rest of these functions?
Segher
[*] Actually, you need strnlen(), but that's not a standard function.
On 20/03/08 17:26 +0100, Uwe Hermann wrote:
On Thu, Mar 20, 2008 at 08:51:39AM -0600, Jordan Crouse wrote:
+char *strcpy(char *d, const char *s) +{
- return strncpy(d, s, strlen(s));
+}
This doesn't put a terminating 0 on the string.
Oops - he's right. Uwe, can you do a quick fix?
How about this? Untested, but should work.
Yeah, that seems good to me.
Signed-off-by: Jordan Crouse jordan.crouse@amd.com
Uwe.
http://www.hermann-uwe.de | http://www.holsham-traders.de http://www.crazy-hacks.org | http://www.unmaintained-free-software.org
Fix strcpy() implementation.
Signed-off-by: Uwe Hermann uwe@hermann-uwe.de
Index: libc/string.c
--- libc/string.c (Revision 3179) +++ libc/string.c (Arbeitskopie) @@ -143,7 +143,10 @@
char *strcpy(char *d, const char *s) {
- return strncpy(d, s, strlen(s));
- char *orig = d;
- while ((*(d++) = *(s++)));
- return orig;
}
char *strncat(char *d, const char *s, int n)