undefined reference to `memset'

Sean McNeil sean at mcneil.com
Thu Mar 24 15:44:25 PST 2005


On Thu, 2005-03-24 at 18:22 -0500, Jung-uk Kim wrote:
> On Thursday 24 March 2005 05:10 pm, Sean McNeil wrote:
> > On Thu, 2005-03-24 at 13:49 -0800, David O'Brien wrote:
> > > Please don't top-post -- it destroys context.  [Format recovered]
> > >
> > > On Thu, Mar 24, 2005 at 12:46:41PM -0800, Vinod Kashyap wrote:
> > > > > On Thu, Mar 24, 2005 at 06:05:17PM +1100, Peter Jeremy wrote:
> > > > > > 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.
> > > > >
> > > > > Vinod can you please post a complete compilable example?
> > > > > It is impossible to get anything done about your issue
> > > > > without stand alone test code.
> > > >
> > > > Ok, make sure you have 'device twa' in your kernel
> > > > configuration file, and apply these patches to
> > > > /sys/dev/twa/twa.c.
> > > > This patch causes the problem:
> > >
> > > "stand alone" means a single foo.c file that shows the problem
> > > you want fixed.
> > > I cannot submit a GCC bug report with a tarball of the entire
> > > FreeBSD kernel.
> >
> > I've taken the liberty to write up an example here.  Not sure if
> > this is a bug or not:
> >
> > cc -O -pipe -c -fno-builtin -ffreestanding memset_bug.c
> >
> > Take a look at what is generated:
> >
> > objdump --disassemble memset_bug.o
> >
> > You'll see that instead of performing the inline code generation
> > for memset, the compiler generates a call to memset in the case of
> > the assignment of {0}.
> 
> Have you tried -minline-all-stringops/-mno-inline-all-stringops?

No, I was just trying to be helpful.  Anyone can take the example I
provided and do whatever they wish with it.  I honestly do not have the
time to fiddle with this much more than I already have.  Sorry.  The
only concern I have with this is if gcc is doing the right thing here.
Should memset be checked and expanded as an inline function when used
within the initializer?  IMHO, yes.

All that being said, testing took less time that writing this email :)

so.....

with -mno-inline-all-stringops, no difference.

with -minline-all-stringops, wow!  memset inline function is gone and
the code is way smaller:

Disassembly of section .text:

0000000000000000 <bug>:
   0:   48 81 ec 98 01 00 00    sub    $0x198,%rsp
   7:   48 89 e7                mov    %rsp,%rdi
   a:   fc                      cld
   b:   b9 32 00 00 00          mov    $0x32,%ecx
  10:   b8 00 00 00 00          mov    $0x0,%eax
  15:   f3 48 ab                repz stos %rax,%es:(%rdi)
  18:   8b 34 24                mov    (%rsp),%esi
  1b:   bf 00 00 00 00          mov    $0x0,%edi
  20:   e8 00 00 00 00          callq  25 <bug+0x25>
  25:   48 81 c4 98 01 00 00    add    $0x198,%rsp
  2c:   c3                      retq

as opposed to (with -O):

Disassembly of section .text:

0000000000000000 <bug>:
   0:   48 81 ec 98 01 00 00    sub    $0x198,%rsp
   7:   48 89 e7                mov    %rsp,%rdi
   a:   ba 90 01 00 00          mov    $0x190,%edx
   f:   be 00 00 00 00          mov    $0x0,%esi
  14:   e8 27 00 00 00          callq  40 <memset>
  19:   8b 34 24                mov    (%rsp),%esi
  1c:   bf 00 00 00 00          mov    $0x0,%edi
  21:   b8 00 00 00 00          mov    $0x0,%eax
  26:   e8 00 00 00 00          callq  2b <bug+0x2b>
  2b:   48 81 c4 98 01 00 00    add    $0x198,%rsp
  32:   c3                      retq
  33:   66                      data16
  34:   66                      data16
  35:   66                      data16
  36:   90                      nop
  37:   66                      data16
  38:   66                      data16
  39:   90                      nop
  3a:   66                      data16
  3b:   66                      data16
  3c:   90                      nop
  3d:   66                      data16
  3e:   66                      data16
  3f:   90                      nop

0000000000000040 <memset>:
  40:   53                      push   %rbx
  41:   48 89 fb                mov    %rdi,%rbx
  44:   85 f6                   test   %esi,%esi
  46:   75 0f                   jne    57 <memset+0x17>
  48:   48 89 d6                mov    %rdx,%rsi
  4b:   b8 00 00 00 00          mov    $0x0,%eax
  50:   e8 00 00 00 00          callq  55 <memset+0x15>
  55:   eb 1b                   jmp    72 <memset+0x32>
  57:   48 89 f8                mov    %rdi,%rax
  5a:   48 ff ca                dec    %rdx
  5d:   48 83 fa ff             cmp    $0xffffffffffffffff,%rdx
  61:   74 0f                   je     72 <memset+0x32>
  63:   40 88 30                mov    %sil,(%rax)
  66:   48 ff c0                inc    %rax
  69:   48 ff ca                dec    %rdx
  6c:   48 83 fa ff             cmp    $0xffffffffffffffff,%rdx
  70:   75 f1                   jne    63 <memset+0x23>
  72:   48 89 d8                mov    %rbx,%rax
  75:   5b                      pop    %rbx
  76:   c3                      retq

Note, with -O (default for 5.x), a local version of memset is created,
so all is well.  As you can see with nm,

0000000000000000 T bug
                 U bzero
0000000000000040 t memset
                 U printf

With -O2 (default for -current), there is no local version of memset.
This could be considered a bug as well. nm shows

0000000000000000 T bug
                 U memset
                 U printf

Cheers,
Sean




More information about the freebsd-amd64 mailing list