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