I was testing the freshly installed gcc-2.96-21 on linux-2.4.0-test1. Here are the results: 1. gcc-2.96-21 issues a large number of warniongs which 2.95 does not. Examples: In file included from init/main.c:35: /usr/src/linux/include/linux/pci.h:214:60: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:215:61: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:217:61: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:218:62: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:219:70: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:220:37: warning: trigraph ??) ignored and gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -mpreferred-stack-boundary=2 -march=i686 -c -o aic7xxx.o aic7xxx.c In file included from aic7xxx.c:239: /usr/src/linux/include/linux/delay.h:19:44: warning: trigraph ??/ ignored In file included from aic7xxx.c:241: /usr/src/linux/include/linux/pci.h:214:60: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:215:61: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:217:61: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:218:62: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:219:70: warning: trigraph ??) ignored /usr/src/linux/include/linux/pci.h:220:37: warning: trigraph ??) ignored rm -f scsi.a ar rcs scsi.a scsi_n_syms.o hosts.o scsi_ioctl.o constants.o scsicam.o scsi_error.o scsi_obsolete.o scsi_queue.o scsi_lib.o scsi_merge.o scsi_proc.o scsi_dma.o scsi_scan.o st.o sd.o sr.o sr_ioctl.o sr_vendor.o sg.o aic7xxx.o This goes on until we reach the ld phase fro vmlinux; here: make[1]: Leaving directory `/reserve/kernel/linux/arch/i386/lib' ld -m elf_i386 -T /usr/src/linux/arch/i386/vmlinux.lds -e stext arch/i386/kernel/head.o arch/i386/kernel/init_task.o init/main.o init/version.o \ --start-group \ arch/i386/kernel/kernel.o arch/i386/mm/mm.o kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o \ drivers/block/block.a drivers/char/char.o drivers/misc/misc.o drivers/net/net.o drivers/parport/parport.a drivers/ide/ide.a drivers/scsi/scsi.a drivers/cdrom/cdrom.a drivers/pci/pci.a drivers/video/video.o \ net/network.a \ /usr/src/linux/arch/i386/lib/lib.a /usr/src/linux/lib/lib.a /usr/src/linux/arch/i386/lib/lib.a \ --end-group \ -o vmlinux drivers/scsi/scsi.a(aic7xxx.o): In function `aic7xxx_load_seeprom': aic7xxx.o(.text+0x11fee): undefined reference to `memcpy' make: *** [vmlinux] Error 1 I reverted to gcc-2.95.2-7mdk and the kernel compiles (and works!)with just a few trivial warnings of the kind {standard input}: Assembler messages: {standard input}:779: Warning: indirect lcall without `*' {standard input}:863: Warning: indirect lcall without `*' {standard input}:950: Warning: indirect lcall without `*' {standard input}:990: Warning: indirect lcall without `*'
This is a new "feature" introduced in 2.96 and should be corrected. Compiler generates a call to memcpy for structure assignments, even if it asked to inline actual memcpy calls. 2.95 and earlier versions always use inline memcpy for such assignments, and this was a right thing. This is critical to kernel, since it does not use libc where memcpy is defined, and shows on all kernels (not just 2.4, but 2.2 also). 2.96-33 also have this bug.
This is actually a kernel bug, if should provide (and export) memcpy/memset functions. gcc can decide whether it is worth inlining the call or taking it out of line.
For structure assignments, it is always ok to inline this operation, at least on x86. Size of structure is fixed; and generating call to memcpy is comparable in speed/size (well, almost equal) to inline version. Compiler should decide where to inline actual memcpy calls, but not assignments. Moreover, it should not be required to export any function(s) when using some compiler -- if it needs (and generates) them, it should provide them itself. In case with kernel where memcpy "always inlined" due to it's definition (as a macro), it is really a kernel bug -- real memcpy should not be inlined that "macro" way. And it should be possible for compiler to decide if it is ok to inline it or not. But, again, requiring presence of any symbol is a bug in compiler. Consider, for example, why some program can be compiled by, say, IBM's C compiler but not by gcc (with cause of missing memcpy as in the case). This will be gcc bug, not a program bug.
Note that you were compiling with -march=i686, and on PentiumPro the various string instructions are slower then using movs. If you're copying too large structure, it is really better to go out of line for cache trashing reasons. Anyway, Linus accepted my patch to export memcpy/memset a couple of 2.4 tests ago.
Probably you are right, and there are cases where it is better to call external routine instead of inlining assignments. Seemed to be that gcc does smarter then I can do ;)... Ok, let's close this bug. Thanks!