Re: undefined reference to `memset'
Vinod Kashyap writes: And now, moving to the important thing... in kern.pre.mk, I changed COPTFLAGS from -O2 to -O for amd64 (just like i386), and the problem is gone!! Better to do it in /etc/make.conf. --- Gary Jennejohn / garyjATjennejohnDOTorg gjATfreebsdDOTorg garyjATdenxDOTde ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: undefined reference to `memset'
Can you not submit it with the patch I sent? Submit the entire /usr/src/sys kernel source?? A stand alone foo.c will have to be a new module under a new directory (/sys/dev/foo), with its own Makefile, with changes to /sys/conf/files, and an entry in GENERIC. A module would still depend on files in /usr/share/mk, /usr/src/sys/conf, /usr/src/sys/modules, /usr/src/sys/dev/foo. NO! nothing other than a single file -- foo.c in my home directory that shows the problem is a stand alone example. Here is memset_issue.c (also attached). But note that you cannot reproduce the undefined reference to `memset' issue with this (that's what I have been trying to explain). You could also use the earlier posting from Sean McNeil. #include stdio.h main() { char a[100] = {0}; char *ap; ap = (a[0]); printf(a[0] = %d\n, a[0]); } With the patch that I sent earlier applied to /sys/dev/twa/twa.c, 'nm twa.o' shows this when twa is built as a stand alone module: 03f0 t memset 'nm twa.o' shows this when twa is built as part of the kernel: U memset And now, moving to the important thing... in kern.pre.mk, I changed COPTFLAGS from -O2 to -O for amd64 (just like i386), and the problem is gone!! #include stdio.h main() { char a[100] = {0}; char *ap; ap = (a[0]); printf(a[0] = %d\n, a[0]); } ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
On Wed, 23 Mar 2005, Vinod Kashyap wrote: If any kernel module has the following, or a similar line in it: - char x[100] = {0}; - I think you mean: - auto char x[100] = {0}; - or after fixing some style bugs: - char x[100] = { 0 }; - building of the GENERIC kernel on FreeBSD 5 -STABLE for amd64 as of 03/19/05, fails with the following message at the time of linking: undefined reference to `memset'. The same problem is not seen on i386. The problem goes away if the above line is changed to: - char x[100]; memset(x, 0, 100); - This version makes the pessimizations and potential bugs clear: - clearing 100 bytes on every entry to the function is wasteful. C90's auto initializers hide pessimizations like this. They should be used very rarely, especially in kernels. But they are often misused, even in kernels, even for read-only data that should be static. gcc doesn't optimize even auto const x[100] = { 0 }; to a static initialization -- the programmer must declare the object as static to prevent gcc laboriously clearing it on every entry to the function. - 100 bytes may be too much to put on the kernel stack. Objects just a little larger than this must be dynamically allocated unless they can be read-only. Adding CFLAGS+=-fbuiltin, or CFLAGS+=-fno-builtin to /sys/conf/Makefile.amd64 does not help. -fno-builtin is already in CFLAGS, and if it has any effect on this then it should be to cause gcc to generate a call to memset() instead of doing the memory clearing inline. I think gcc has a builtin memset() which is turned off by -fno-builtin, but -fno-builtin doesn't affect cases where memset() is not referenced in the source code. -ffreestanding should prevent gcc generating calls to library functions like memset(). However, -ffreestanding is already in CFLAGS too, and there is a problem: certain initializations like the one in your example need to use an interface like memset(), and struct copies need to use and interface like memcpy(), so what is gcc to do when -fno-builtin tells it to turn off its builtins and -ffreestanding tells it that the relevant interfaces might not exist in the library? Anyone knows what's happening? gcc is expecting that memset() is in the library, but the FreeBSD kernel is freestanding and happens not to have memset() in its library. Related bugs: - the FreeBSD kernel shouldn't have memset() at all. The kernel interface for clearing memory is bzero(). A few files misspelled bzero() as memset() and provided a macro to convert from memset() to bzero(), and instead of fixing them a low-quality memset() was added to sys/libkern.h. This gives an inline memset() so it doesn't help here. memset() is of some use for setting to nonzero, but this is rarely needed and can easily be repeated as necessary. The support for the nonzero case in sys/libkern.h is of particularly low quality -- e.g., it crashes if asked to set a length of 0. - memset() to zero and/or gcc methods for initialization to 0 might be much slower than the library's methods for clearing memory. This is not a problem in practice, although bzero() is much faster than gcc's methods in some cases, because: (a) -fno-builtin turns off builtin memset(). (b) the inline memset() just uses bzero() in the fill_byte = 0 case, so using it instead of bzero() is only a tiny pessimization. (c) large copies that bzero() can handle better than gcc's inline method (which is stosl on i386's for your example) cannot because the data would be too large to fit on the kernel statck. - there are slightly different problems for memcpy(): (a) memcpy() is in the library and is not inline, so there is no linkage problem if gcc generates a call to memcpy() for a struct copy. (b) the library memcpy() never uses bcopy(), so it is much slower than bcopy() in much cases. (c) the reason that memcpy() is in the library is to let gcc inline memcpy() for efficiency, but this reason was turned into nonsense by adding -fno-builtin to CFLAGS, and all calls to memcpy() are style bugs and ask for inefficiency. (The inefficiency is small or negative in practice because bzero() has optimizations for large copies that are small pessimizations for non-large copies.) - the FreeBSD kernel shouldn't have memcmp(). It has an inline one that has even lower quality than the inline memset(). memcmp() cannot be implemented using bcmp() since memcmp() is tri-state but bcmp() is boolean, but the inline memcmp() just calls bcmp(). This works, if at all, because nothing actually needs memcmp() and memcmp() is just a misspelling of bcmp(). Bruce ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
On Thu, 24 Mar 2005, Bruce Evans wrote: On Wed, 23 Mar 2005, Vinod Kashyap wrote: If any kernel module has the following, or a similar line in it: - char x[100] = {0}; - building of the GENERIC kernel on FreeBSD 5 -STABLE for amd64 as of 03/19/05, fails with the following message at the time of linking: undefined reference to `memset'. ... ... Anyone knows what's happening? gcc is expecting that memset() is in the library, but the FreeBSD kernel is freestanding and happens not to have memset() in its library. As to why gcc calls memset() on amd64's but not on i386's: - gcc-3.3.3 doesn't call memset() on amd64's either. - gcc-3.4.2 on amd64's calls memset() starting with an array size of 65. It uses mov[qlwb] for sizes up to 16, then stos[qlwb] up to size 64. gcc-3.3.3 on i386's uses mov[lwb] for sizes up to 8, then stos[lwb] for all larger sizes. - the relevant change seems to be: % Index: i386.c % === % RCS file: /home/ncvs/src/contrib/gcc/config/i386/i386.c,v % retrieving revision 1.20 % retrieving revision 1.21 % diff -u -2 -r1.20 -r1.21 % --- i386.c19 Jun 2004 20:40:00 - 1.20 % +++ i386.c28 Jul 2004 04:47:35 - 1.21 % @@ -437,26 +502,36 @@ % ... % +const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6; % ... Note that rep_movl is considered optimal on i386's but not on amd64's. % @@ -10701,6 +11427,10 @@ %/* In case we don't know anything about the alignment, default to % library version, since it is usually equally fast and result in % - shorter code. */ % - if (!TARGET_INLINE_ALL_STRINGOPS align UNITS_PER_WORD) % + shorter code. % + % + Also emit call when we know that the count is large and call overhead % + will not be important. */ % + if (!TARGET_INLINE_ALL_STRINGOPS % +(align UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL)) % return 0; % TARGET_REP_MOVL_OPTIMAL is x86_rep_movl_optimal modulo a mask. It is zero for amd64's, so 0 is returned for amd64's here unless you use -mfoo to set TARGET_INLINE_ALL_STRINGOPS. Returning 0 gives the library call instead of a stringop. This is in i386_expand_clrstr(). There is an identical change in i386_expand_movstr() that gives library calls to memcpy() for (at least) copying structs. Bruce ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
At 2005-03-24 08:31:14+, Bruce Evans writes: what is gcc to do when -fno-builtin tells it to turn off its builtins and -ffreestanding tells it that the relevant interfaces might not exist in the library? Plainly, GCC should generate code which fills the array with zeroes. It's not obliged to generate code which calls memset (either builtin or in a library). If it knows that it can do so, then fine. Otherwise it must do it the Old Fashioned Way. So this is surely a bug in GCC. Nick B, who used to write compilers for a living ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
Peter Wemm [EMAIL PROTECTED] writes: I wondered if it might be because of something like -O2 (don't do that) Peter, stop that. The kernel builds and runs fine with -O2, and has for a long time. DES -- Dag-Erling Smørgrav - [EMAIL PROTECTED] ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: undefined reference to `memset'
This version makes the pessimizations and potential bugs clear: - clearing 100 bytes on every entry to the function is wasteful. C90's auto initializers hide pessimizations like this. They should be used very rarely, especially in kernels. But they are often misused, even in kernels, even for read-only data that should be static. gcc doesn't optimize even auto const x[100] = { 0 }; to a static initialization -- the programmer must declare the object as static to prevent gcc laboriously clearing it on every entry to the function. - 100 bytes may be too much to put on the kernel stack. Objects just a little larger than this must be dynamically allocated unless they can be read-only. A statement like this (auto and not static) is necessary if you are dealing with re-entrancy. Whatever the issues with wastage or bad performance, a programmer should definitely be able to do it, if he so desires. Also, the line I mentioned earlier was only an example. Something like this also fails (your response already explains this): - struct x_type x = {0}; - Adding CFLAGS+=-fbuiltin, or CFLAGS+=-fno-builtin to /sys/conf/Makefile.amd64 does not help. -fno-builtin is already in CFLAGS, and if it has any effect on this then it should be to cause gcc to generate a call to memset() instead of doing the memory clearing inline. I think gcc has a builtin memset() which is turned off by -fno-builtin, but -fno-builtin doesn't affect cases where memset() is not referenced in the source code. -ffreestanding should prevent gcc generating calls to library functions like memset(). However, -ffreestanding is already in CFLAGS too, and there is a problem: certain initializations like the one in your example need to use an interface like memset(), and struct copies need to use and interface like memcpy(), so what is gcc to do when -fno-builtin tells it to turn off its builtins and -ffreestanding tells it that the relevant interfaces might not exist in the library? Anyone knows what's happening? gcc is expecting that memset() is in the library, but the FreeBSD kernel is freestanding and happens not to have memset() in its library. How is it then, that an explicit call to memset (like in my example) works? As about other questions in the thread: 1. Yes, the example code is within a function, 2. I should have mentioned that I don't see the problem if I am building only the kernel module. It happens only when I am building the kernel integrating the module containing the example code. ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
Dag-Erling Smørgrav wrote: Peter Wemm [EMAIL PROTECTED] writes: I wondered if it might be because of something like -O2 (don't do that) Peter, stop that. The kernel builds and runs fine with -O2, and has for a long time. DES No it doesn't. See the gymnastics that Bill Paul had to do recently in the iee80211 code to get around the insane inlining that gcc does with -O2. I'm not saying that gcc produces incorrect code, but I am saying that there is very strong evidence that it produces code that is incompatible with the restrictions inherent to the kernel, mainly that stack space is not infinite. Scott ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
Scott Long writes: No it doesn't. See the gymnastics that Bill Paul had to do recently in the iee80211 code to get around the insane inlining that gcc does with -O2. I'm not saying that gcc produces incorrect code, but I am saying that there is very strong evidence that it produces code that is incompatible with the restrictions inherent to the kernel, mainly that stack space is not infinite. I wonder how this is being done elsewhere, on NetBSD, everything is built with -O2 and has been for several years afair. Not that I care much about it but apparently it doesn't seem to be such a big problem everywhere? mkb. ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
On Thu, 2005-Mar-24 12:03:19 -0800, Vinod Kashyap wrote: [ char x[100] = { 0 }; ] A statement like this (auto and not static) I'd point out that this is the first time that you've mentioned that the variable is auto. Leaving out critical information will not encourage people to help you. is necessary if you are dealing with re-entrancy. This isn't completely true. The preferred approach is: char*x; x = malloc(100, MEM_POOL_xxx, M_ZERO | M_WAITOK); (with a matching free() later). Whatever the issues with wastage or bad performance, a programmer should definitely be able to do it, if he so desires. Again, untrue. The FreeBSD kernel is not a standard C environment. Kernel stack is a relatively small, fixed size and using excessive kernel stack will lead to panics. Increasing the kernel stack size is undesirable because it's expensive in RAM consumption. How is it then, that an explicit call to memset (like in my example) works? The code auto char x[100] = {0}; is equivalent to auto char x[100]; memset(x, 0, sizeof(x)); but memset only exists as a static inline function (defined in libkern.h). If an explicit call to memset works then the problem would appear to be that the compiler's implicit expansion is failing to detect the static inline definition, and generating an external reference which can't be satisfied. This would seem to be a gcc bug. 2. I should have mentioned that I don't see the problem if I am building only the kernel module. It happens only when I am building the kernel integrating the module containing the example code. This is the opposite of what you implied previously. There are some differences in how kernel modules are built so this How about posting a (short) compilable piece of C code that shows the problem. I would expect that an nm of the resultant object would show U memset when the code was compiled for linking into the kernel and some_address t memset or not reference memset at all when compiled as a module. -- Peter Jeremy ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
Matthias Buelow wrote: Scott Long writes: No it doesn't. See the gymnastics that Bill Paul had to do recently in the iee80211 code to get around the insane inlining that gcc does with -O2. I'm not saying that gcc produces incorrect code, but I am saying that there is very strong evidence that it produces code that is incompatible with the restrictions inherent to the kernel, mainly that stack space is not infinite. I wonder how this is being done elsewhere, on NetBSD, everything is built with -O2 and has been for several years afair. Not that I care much about it but apparently it doesn't seem to be such a big problem everywhere? mkb. I'm sure that it's highly dependent on the version of gcc in use and the other -f flags that are passed to it, neither of which I'm familiar with in NetBSD. Scott ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
On Thu, 24 Mar 2005, Nick Barnes wrote: At 2005-03-24 08:31:14+, Bruce Evans writes: what is gcc to do when -fno-builtin tells it to turn off its builtins and -ffreestanding tells it that the relevant interfaces might not exist in the library? Plainly, GCC should generate code which fills the array with zeroes. It's not obliged to generate code which calls memset (either builtin or in a library). If it knows that it can do so, then fine. Otherwise it must do it the Old Fashioned Way. So this is surely a bug in GCC. Nick B, who used to write compilers for a living But the compiler can require the Old Fashioned Way to be in the library. libgcc.a is probably part of gcc even in the freestanding case. The current implementation of libgcc.a won't all work in the freestanding case, since parts of it call stdio, but some parts of it are needed and work (e.g., __divdi3() on i386's at least). The kernel doesn't use libgcc.a, but it knows that __divdi3() and friends are needed and implements them in its libkern. Strictly, it should do something similar for memset(). I think the only bugs in gcc here are that the function it calls is in the application namespace in the freestanding case, and that the requirements for freestanding implementations are not all documented. The requirement for memset() and friends _is_ documented (in gcc.info), but the requirement for __divdi3() and friends are only documented indirectly by the presence of these functions in libgcc.a. Bruce ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
On Fri, 25 Mar 2005, Peter Jeremy wrote: On Thu, 2005-Mar-24 12:03:19 -0800, Vinod Kashyap wrote: [ char x[100] = { 0 }; ] A statement like this (auto and not static) I'd point out that this is the first time that you've mentioned that the variable is auto. Leaving out critical information will not encourage people to help you. It was obviously auto, since memset() would not have been called for a global variable. is necessary if you are dealing with re-entrancy. This isn't completely true. The preferred approach is: char*x; x = malloc(100, MEM_POOL_xxx, M_ZERO | M_WAITOK); (with a matching free() later). This is also preferred to alloca() and C99's dynamic arrays. BTW, the kernel has had some dubious examples of dynamic arrays in very important code since long before C99 existed. vm uses some dynamic arrays, and this is only safe since the size of the arrays is bounded and small. But when the size of an array is bounded and small, dynamic allocation is just a pessimization -- it is more efficient to always allocate an array with the maximum size that might be needed. How is it then, that an explicit call to memset (like in my example) works? The code auto char x[100] = {0}; is equivalent to auto char x[100]; memset(x, 0, sizeof(x)); but memset only exists as a static inline function (defined in libkern.h). If an explicit call to memset works then the problem would appear to be that the compiler's implicit expansion is failing to detect the static inline definition, and generating an external reference which can't be satisfied. This would seem to be a gcc bug. No, it is a feature :-). See my earlier reply. 2. I should have mentioned that I don't see the problem if I am building only the kernel module. It happens only when I am building the kernel integrating the module containing the example code. This is the opposite of what you implied previously. There are some differences in how kernel modules are built so this How about posting a (short) compilable piece of C code that shows the problem. I would expect that an nm of the resultant object would show U memset when the code was compiled for linking into the kernel and some_address t memset or not reference memset at all when compiled as a module. I deleted the actual example. Most likely it would fail at load time do to using memset(). Another possibility is for the code that needs memset to be unreachable in the module since it is inside an ifdef. Bruce ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: undefined reference to `memset'
-Original Message- From: Peter Jeremy [mailto:[EMAIL PROTECTED] Sent: Thursday, March 24, 2005 2:46 PM To: Vinod Kashyap Cc: freebsd-stable@freebsd.org; [EMAIL PROTECTED] Subject: Re: undefined reference to `memset' On Thu, 2005-Mar-24 12:03:19 -0800, Vinod Kashyap wrote: [ char x[100] = { 0 }; ] A statement like this (auto and not static) I'd point out that this is the first time that you've mentioned that the variable is auto. Leaving out critical information will not encourage people to help you. It is char x[100] = {0}; and that's it. Doesn't it make it auto? Isn't auto the default? is necessary if you are dealing with re-entrancy. This isn't completely true. The preferred approach is: char*x; x = malloc(100, MEM_POOL_xxx, M_ZERO | M_WAITOK); (with a matching free() later). Well, I am in a function that is OS-independent, and cannot assume malloc (or a wrapper to it) is available. Whatever the issues with wastage or bad performance, a programmer should definitely be able to do it, if he so desires. Again, untrue. The FreeBSD kernel is not a standard C environment. Kernel stack is a relatively small, fixed size and using excessive kernel stack will lead to panics. Increasing the kernel stack size is undesirable because it's expensive in RAM consumption. Whatever that may be, I don't think the compiler should be stopping me from doing standard C stuff. I could be having this statement in my module with full knowledge that it would not cause a kernel stack overflow. How is it then, that an explicit call to memset (like in my example) works? The code auto char x[100] = {0}; is equivalent to auto char x[100]; memset(x, 0, sizeof(x)); but memset only exists as a static inline function (defined in libkern.h). If an explicit call to memset works then the problem would appear to be that the compiler's implicit expansion is failing to detect the static inline definition, and generating an external reference which can't be satisfied. This would seem to be a gcc bug. 2. I should have mentioned that I don't see the problem if I am building only the kernel module. It happens only when I am building the kernel integrating the module containing the example code. This is the opposite of what you implied previously. There are some differences in how kernel modules are built so this No, it's not. This is what I wrote in my first e-mail: building of the GENERIC kernel on FreeBSD 5 -STABLE for amd64. I just forgot to mention that the problem did not occur when I build only the module. This is possibly due to different gcc flags being used in the 2 cases. How about posting a (short) compilable piece of C code that shows the problem. I would expect that an nm of the resultant object would show U memset when the code was compiled for linking into the kernel and some_address t memset or not reference memset at all when compiled as a module. Just like the problem is not seen when I build only the module, it's not seen if I simply write a foo.c (with the example code) and compile it. That's the reason I posted the patch to /sys/dev/twa/twa.c, which would cause the problem if applied, and then followed with a kernel build. I can send the result of running nm on twa.o tomorrow. ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: undefined reference to `memset'
Vinod, On Thu, 2005-03-24 at 19:01 -0800, Vinod Kashyap wrote: Just like the problem is not seen when I build only the module, it's not seen if I simply write a foo.c (with the example code) and compile it. That's the reason I posted the patch to /sys/dev/twa/twa.c, which would cause the problem if applied, and then followed with a kernel build. I can send the result of running nm on twa.o tomorrow. Please take a look at other messages in this thread, like some of the ones I have posted. They clearly show your problem in a small example and how it is happening in the -O2 case as memset is being optimized away. -O would appear to do the right thing and adding -minline-all-stringops (at either optimization level) would produce even better code. Cheers, Sean ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: undefined reference to `memset'
-Original Message- From: Sean McNeil [mailto:[EMAIL PROTECTED] Sent: Thursday, March 24, 2005 7:15 PM To: Vinod Kashyap Cc: Peter Jeremy; freebsd-stable@freebsd.org; [EMAIL PROTECTED] Subject: RE: undefined reference to `memset' Vinod, On Thu, 2005-03-24 at 19:01 -0800, Vinod Kashyap wrote: Just like the problem is not seen when I build only the module, it's not seen if I simply write a foo.c (with the example code) and compile it. That's the reason I posted the patch to /sys/dev/twa/twa.c, which would cause the problem if applied, and then followed with a kernel build. I can send the result of running nm on twa.o tomorrow. Please take a look at other messages in this thread, like some of the ones I have posted. They clearly show your problem in a small example and how it is happening in the -O2 case as memset is being optimized away. -O would appear to do the right thing and adding -minline-all-stringops (at either optimization level) would produce even better code. I did look at your posting Sean, thanks. But did you see the undefined reference to `memset' linker error when you built it? It's obvious that a reference to memset is being generated by the initialization of an array of 100 bytes to 0. The linker is getting the needed memset if you build a stand alone program, or even build a stand alone kernel module, but is not being able to find it when building the kernel itself. This implies to me that it is a difference in the use of flags, or linking/not linking with particular libraries that's causing the problem. I am also confused as to how an explicit call to memset works, when compiler generated call doesn't! Are we talking 2 different memset's here? Maybe a memset and an __memset? ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: undefined reference to `memset'
On Thu, 2005-03-24 at 19:51 -0800, Vinod Kashyap wrote: I did look at your posting Sean, thanks. But did you see the undefined reference to `memset' linker error when you built it? It's obvious that a reference to memset is being generated by the initialization of an array of 100 bytes to 0. The linker is getting the needed memset if you build a stand alone program, or even build a stand alone kernel module, but is not being able to find it when building the kernel itself. This implies to me that it is a difference in the use of flags, or linking/not linking with particular libraries that's causing the problem. Here is what I believe is happening: There exists an inline function called memset. This inline function _should_ replace any uses of memset within the function when compiled with optimization (-O or -O2). In any event that a call is not inlined, a local copy of memset should be emitted and used. This is what happens with -O, but not with -O2. This is clearly seen by an objdump at each optimization. For -O, a local copy of memset is emitted and used. For -O2, memset is still called, but the memset code is optimized away. This is a bug, IMHO, in various ways. 1) -O2 is being too agressive and eliminating memset when it shouldn't. 2) both optimized versions are not replacing the call to memset with the inline code. Here is one of several issues with the amd64 compiler used at -O2 vs. -O. There are others as well. Note: this comment inserted for the sole purpose of adding flame-bait :) You do not need to link to show this. In fact, since this is a standard program and memset is available in libc, you will not see the problem in a link. You need to look at the nm output and objdump to understand what is happening. I am also confused as to how an explicit call to memset works, when compiler generated call doesn't! Are we talking 2 different memset's here? Maybe a memset and an __memset? The problem is that the compiler is inserting the memset call. Either it is happening too late for inlining to occur or it is done in some fashion that doesn't lend to inlining by the compiler. The call inside the function is handled like all other code and is properly identified and inlined. We are not talking about 2 different memset functions, no. We are talking about 2 different mechanisms for using memset where one is not properly inlined and the other is. HTH, Sean ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
undefined reference to `memset'
If any kernel module has the following, or a similar line in it: - char x[100] = {0}; - building of the GENERIC kernel on FreeBSD 5 -STABLE for amd64 as of 03/19/05, fails with the following message at the time of linking: undefined reference to `memset'. The same problem is not seen on i386. The problem goes away if the above line is changed to: - char x[100]; memset(x, 0, 100); - Adding CFLAGS+=-fbuiltin, or CFLAGS+=-fno-builtin to /sys/conf/Makefile.amd64 does not help. Anyone knows what's happening? Thanks, Vinod. ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
On Wednesday 23 March 2005 01:48 pm, Vinod Kashyap wrote: If any kernel module has the following, or a similar line in it: - char x[100] = {0}; - building of the GENERIC kernel on FreeBSD 5 -STABLE for amd64 as of 03/19/05, fails with the following message at the time of linking: undefined reference to `memset'. The same problem is not seen on i386. The problem goes away if the above line is changed to: - char x[100]; memset(x, 0, 100); - Adding CFLAGS+=-fbuiltin, or CFLAGS+=-fno-builtin to /sys/conf/Makefile.amd64 does not help. Anyone knows what's happening? Something fishy is going on. I've tried this on both 5.x and 6.0 and both systems created a bss object called 'x', not something that called memset. For example: [EMAIL PROTECTED]:17pm]/home/src/sys/modules/twe-21# nm obj/twe.ko | grep x U busdma_lock_mutex U sysctl_ctx_free U sysctl_ctx_init 0080 b x [EMAIL PROTECTED]:17pm]/home/src/sys/modules/twe-22# nm obj/twe.ko | grep memset [EMAIL PROTECTED]:17pm]/home/src/sys/modules/twe-23# I wondered if it might be because of something like -O2 (don't do that) or no -O at all, but I couldn't make it happen even then. -- Peter Wemm - [EMAIL PROTECTED]; [EMAIL PROTECTED]; [EMAIL PROTECTED] All of this is for nothing if we don't go to the stars - JMS/B5 ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: undefined reference to `memset'
On Wed, 2005-Mar-23 13:48:04 -0800, Vinod Kashyap wrote: If any kernel module has the following, or a similar line in it: - char x[100] = {0}; - building of the GENERIC kernel on FreeBSD 5 -STABLE for amd64 as of 03/19/05, fails with the following message at the time of linking: undefined reference to `memset'. The same problem is not seen on i386. The problem goes away if the above line is changed to: - char x[100]; memset(x, 0, 100); - Can you post a complete (compilable) example please. Based on your second example, I suspect that you are putting the variable declaration inside a function definition - the second example doesn't make sense outside a function. If I add char x[100] = {0}; into a function on i386 and compile it as a kernel module on 5.3, a static memset symbol is generated - it's possible that the amd64 compiler gets confused about the implicit reference to memset that this code needs. -- Peter Jeremy ___ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to [EMAIL PROTECTED]