Re: undefined reference to `memset'

2005-03-26 Thread Gary Jennejohn

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'

2005-03-25 Thread Vinod Kashyap
  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'

2005-03-24 Thread Bruce Evans
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'

2005-03-24 Thread Bruce Evans
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'

2005-03-24 Thread Nick Barnes
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'

2005-03-24 Thread =?iso-8859-1?q?Dag-Erling_Sm=F8rgrav?=
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'

2005-03-24 Thread Vinod Kashyap
 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'

2005-03-24 Thread Scott Long
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'

2005-03-24 Thread Matthias Buelow
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'

2005-03-24 Thread Peter Jeremy
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'

2005-03-24 Thread Scott Long
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'

2005-03-24 Thread Bruce Evans
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'

2005-03-24 Thread Bruce Evans
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'

2005-03-24 Thread Vinod Kashyap

 -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'

2005-03-24 Thread Sean McNeil
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'

2005-03-24 Thread Vinod Kashyap


 -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'

2005-03-24 Thread Sean McNeil
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'

2005-03-23 Thread Vinod Kashyap

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'

2005-03-23 Thread Peter Wemm
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'

2005-03-23 Thread Peter Jeremy
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]