This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Undefined references to 'memcpy' when compiling Linux Kernel
- To: gcc at gcc dot gnu dot org
- Subject: Undefined references to 'memcpy' when compiling Linux Kernel
- From: Byron Stanoszek <gandalf at winds dot org>
- Date: Fri, 16 Jun 2000 09:49:10 -0400 (EDT)
- cc: linux-kernel at vger dot rutgers dot edu
Using the latest CVS snapshot for gcc 2.96, I find that 5 functions in the
Linux Kernel (2.4.0) contain 'memcpy' statements that are not correctly
converted into assembly using the compiler's builtin function list.
Instead, the code resulting for these functions is a 'call memcpy', a
function that doesn't exist in the kernel. A -fbuiltin-functions or -O3 does
not seem to solve the problem.
Output of the error:
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/idedriver.o
drivers/cdrom/cdrom.a drivers/pci/pci.a drivers/video/video.o \
net/network.o \
/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
fs/fs.o: In function `nfs_fhget':
fs/fs.o(.text+0x32d4a): undefined reference to `memcpy'
fs/fs.o: In function `nlmclnt_proc':
fs/fs.o(.text+0x3ae08): undefined reference to `memcpy'
fs/fs.o: In function `nlmclnt_reclaim':
fs/fs.o(.text+0x3b4af): undefined reference to `memcpy'
fs/fs.o: In function `nlmclnt_cancel':
fs/fs.o(.text+0x3b71d): undefined reference to `memcpy'
fs/fs.o: In function `nlm_lookup_file':
fs/fs.o(.text+0x3e92d): undefined reference to `memcpy'
make: *** [vmlinux] Error 1
...in /usr/src/linux/fs/nfs:
gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2
-fomit-frame-pointer -fno-strict-aliasing -pipe -mpreferred-stack-boundary=2
-march=i586 -c -o inode.o inode.c
...containing this function:
struct inode *
nfs_fhget(struct dentry *dentry, struct nfs_fh *fhandle,
struct nfs_fattr *fattr)
{
struct super_block *sb = dentry->d_sb;
dprintk("NFS: nfs_fhget(%s/%s fileid=%Ld)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
(long long)fattr->fileid);
/* Install the file handle in the dentry */
*((struct nfs_fh *) dentry->d_fsdata) = *fhandle;
#ifdef CONFIG_NFS_SNAPSHOT
/*
* Check for NetApp snapshot dentries, and get an
* unhashed inode to avoid aliasing problems.
*/
if ((dentry->d_parent->d_inode->u.nfs_i.flags & NFS_IS_SNAPSHOT) ||
(dentry->d_name.len == 9 &&
memcmp(dentry->d_name.name, ".snapshot", 9) == 0)) {
struct inode *inode = get_empty_inode();
if (!inode)
goto out;
inode->i_sb = sb;
inode->i_dev = sb->s_dev;
inode->i_flags = 0;
inode->i_ino = nfs_fattr_to_ino_t(fattr);
nfs_read_inode(inode);
nfs_fill_inode(inode, fattr);
inode->u.nfs_i.flags |= NFS_IS_SNAPSHOT;
dprintk("NFS: nfs_fhget(snapshot ino=%ld)\n", inode->i_ino);
out:
return inode;
}
#endif
return __nfs_fhget(sb, fattr);
}
---
While there is no reference to 'memcpy' in the above code, it is possible that
the compiler is inserting a 'memcpy' statement as a substitution for an
optimization of some sort.
...The output of the nfs_fhget function in inode.s:
.LC32:
.string "NFS: nfs_fhget(%s/%s fileid=%Ld)\n"
.LC33:
.string ".snapshot"
.align 32
.LC34:
.string "NFS: nfs_fhget(snapshot ino=%ld)\n"
.text
.align 16
.globl nfs_fhget
.type nfs_fhget,@function
nfs_fhget:
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
pushl %ebp
movl 24(%esp), %ebx
movl 32(%esp), %eax
movl %eax, (%esp)
movl 28(%esp), %esi
movl 84(%ebx), %ebp
testb $1, nfs_debug
je .L2072
movl %eax, %ecx
movl 80(%ecx), %edi
pushl %edi
movl 76(%ecx), %edx
pushl %edx
movl 64(%ebx), %eax
pushl %eax
movl 12(%ebx), %eax
movl 64(%eax), %edi
pushl %edi
pushl $.LC32
call printk
addl $20, %esp
.L2072:
pushl $66
pushl %esi
movl 92(%ebx), %esi
pushl %esi
call memcpy <-------------------------------
movl 12(%ebx), %eax
addl $12, %esp
movl 8(%eax), %eax
testb $16, 280(%eax)
jne .L2077
cmpl $9, 68(%ebx)
jne .L2076
cld
movl 64(%ebx), %esi
movl $.LC33, %edi
movl $9, %ecx
repz
cmpsb
seta %dl
setb %al
cmpb %al, %dl
jne .L2076
.L2077:
call get_empty_inode
movl %eax, %ebx
testl %ebx, %ebx
je .L2079
movl %ebp, 164(%ebx)
movl 8(%ebp), %eax
movw %ax, 40(%ebx)
movl $0, 244(%ebx)
movl (%esp), %ecx
movl 76(%ecx), %eax
movl 80(%ecx), %edx
movl %eax, %ecx
movl %edx, %eax
xorl %eax, %ecx
movl %ecx, 32(%ebx)
movl 12(%ebp), %eax
movl %eax, 80(%ebx)
movw $0, 42(%ebx)
movw $0, 56(%ebx)
movl $0, 272(%ebx)
movl $0, 276(%ebx)
movl $0, 264(%ebx)
movl $0, 268(%ebx)
leal 336(%ebx), %eax
movl %eax, 336(%ebx)
movl %eax, 340(%ebx)
leal 344(%ebx), %eax
movl %eax, 344(%ebx)
movl %eax, 348(%ebx)
leal 352(%ebx), %eax
movl %eax, 352(%ebx)
movl %eax, 356(%ebx)
leal 360(%ebx), %eax
movl %eax, 360(%ebx)
movl %eax, 364(%ebx)
movl $0, 368(%ebx)
movl $0, 372(%ebx)
movl $0, 376(%ebx)
movl $0, 380(%ebx)
movl jiffies, %eax
movl 228(%ebp), %ecx
subl %ecx, %eax
decl %eax
movl %eax, 284(%ebx)
xorl %eax, %eax
andl $61440, %eax
cmpw $16384, %ax
jne .L2089
movl %ebp, %eax
movl 232(%eax), %eax
jmp .L2090
.p2align 4,,7
.L2089:
movl 164(%ebx), %eax
movl 224(%eax), %eax
.L2090:
movl %eax, 320(%ebx)
movl jiffies, %eax
movl %eax, 324(%ebx)
movl (%esp), %edx
pushl %edx
pushl %ebx
call nfs_fill_inode
orw $16, 280(%ebx)
popl %ebp
popl %eax
testb $1, nfs_debug
je .L2079
movl 32(%ebx), %edi
pushl %edi
pushl $.LC34
call printk
popl %ecx
popl %esi
.L2079:
popl %edx
movl %ebx, %eax
popl %ebx
popl %esi
popl %edi
popl %ebp
ret
.p2align 4,,7
.L2076:
movl (%esp), %eax
movl %ebp, 24(%esp)
movl %eax, 28(%esp)
popl %eax
popl %ebx
popl %esi
popl %edi
popl %ebp
jmp __nfs_fhget
---
Another function, for comparison, has this same problem with memcpy:
...in /usr/src/linux/fs/nfs/clntproc.c:
/*
* This is the main entry point for the NLM client.
*/
int
nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
{
struct nfs_server *nfssrv = NFS_SERVER(inode);
struct nlm_host *host;
struct nlm_rqst reqst, *call = &reqst;
sigset_t oldset;
unsigned long flags;
int status, proto, vers;
vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1;
if (NFS_PROTO(inode)->version > 3) {
printk(KERN_NOTICE "NFSv4 file locking not implemented!\n");
return -ENOLCK;
}
/* Retrieve transport protocol from NFS client */
proto = NFS_CLIENT(inode)->cl_xprt->prot;
if (!(host = nlmclnt_lookup_host(NFS_ADDR(inode), proto, vers)))
return -ENOLCK;
/* Create RPC client handle if not there, and copy soft
* and intr flags from NFS client. */
if (host->h_rpcclnt == NULL) {
struct rpc_clnt *clnt;
/* Bind an rpc client to this host handle (does not
* perform a portmapper lookup) */
if (!(clnt = nlm_bind_host(host))) {
status = -ENOLCK;
goto done;
}
clnt->cl_softrtry = nfssrv->client->cl_softrtry;
clnt->cl_intr = nfssrv->client->cl_intr;
clnt->cl_chatty = nfssrv->client->cl_chatty;
}
/* Keep the old signal mask */
spin_lock_irqsave(¤t->sigmask_lock, flags);
oldset = current->blocked;
/* If we're cleaning up locks because the process is exiting,
* perform the RPC call asynchronously. */
if ((cmd == F_SETLK || cmd == F_SETLKW)
&& fl->fl_type == F_UNLCK
&& (current->flags & PF_EXITING)) {
sigfillset(¤t->blocked); /* Mask all signals */
recalc_sigpending(current);
spin_unlock_irqrestore(¤t->sigmask_lock, flags);
call = nlmclnt_alloc_call();
if (!call) {
status = -ENOMEM;
goto out_restore;
}
call->a_flags = RPC_TASK_ASYNC;
} else {
spin_unlock_irqrestore(¤t->sigmask_lock, flags);
call->a_flags = 0;
}
call->a_host = host;
/* Set up the argument struct */
nlmclnt_setlockargs(call, fl);
if (cmd == F_GETLK) {
status = nlmclnt_test(call, fl);
} else if ((cmd == F_SETLK || cmd == F_SETLKW)
&& fl->fl_type == F_UNLCK) {
status = nlmclnt_unlock(call, fl);
} else if (cmd == F_SETLK || cmd == F_SETLKW) {
call->a_args.block = (cmd == F_SETLKW)? 1 : 0;
status = nlmclnt_lock(call, fl);
} else {
status = -EINVAL;
}
if (status < 0 && (call->a_flags & RPC_TASK_ASYNC))
kfree(call);
out_restore:
spin_lock_irqsave(¤t->sigmask_lock, flags);
current->blocked = oldset;
recalc_sigpending(current);
spin_unlock_irqrestore(¤t->sigmask_lock, flags);
done:
dprintk("lockd: clnt proc returns %d\n", status);
nlm_release_host(host);
return status;
}
...And its assembled output:
.LC22:
.string "<5>NFSv4 file locking not implemented!\n"
.LC23:
.string "lockd: clnt proc returns %d\n"
.text
.align 16
.globl nlmclnt_proc
.type nlmclnt_proc,@function
nlmclnt_proc:
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $508, %esp
movl 528(%esp), %eax
leal 12(%esp), %ebp
movl 164(%eax), %ebx
movl 192(%ebx), %eax
movl (%eax), %edx
xorl %eax, %eax
cmpl $3, %edx
sete %al
leal 1(%eax,%eax,2), %ecx
jle .L1773
pushl $.LC22
call printk
popl %edi
movl $-37, %eax
jmp .L1770
.p2align 4,,7
.L1773:
movl 188(%ebx), %eax
movl 4(%eax), %eax
pushl %ecx
movl 48(%eax), %esi
pushl %esi
movl 188(%ebx), %eax
movl 4(%eax), %eax
addl $32, %eax
pushl %eax
call nlmclnt_lookup_host
movl %eax, 20(%esp)
addl $12, %esp
testl %eax, %eax
jne .L1774
movl $-37, %eax
jmp .L1770
.p2align 4,,7
.L1774:
movl 8(%esp), %eax
movl 24(%eax), %ecx
testl %ecx, %ecx
jne .L1775
pushl %eax
call nlm_bind_host
movl %eax, %ecx
popl %edx
movl $-37, %esi
testl %ecx, %ecx
je .L1777
movl 188(%ebx), %eax
movb 32(%eax), %dl
movb 32(%ecx), %al
andl $1, %edx
andl $254, %eax
orl %edx, %eax
movb %al, 32(%ecx)
andl $-3, %eax
movl 188(%ebx), %edx
movb 32(%edx), %dl
andl $2, %edx
orl %edx, %eax
movb %al, 32(%ecx)
andl $-5, %eax
movl 188(%ebx), %edx
movb 32(%edx), %dl
andl $4, %edx
orl %edx, %eax
movb %al, 32(%ecx)
.L1775:
#APP
pushfl ; popl %ebx ; cli
#NO_APP
movl $-8192, %edx
#APP
andl %esp,%edx;
#NO_APP
movl 532(%esp), %eax
movl 956(%edx), %esi
movl 960(%edx), %edi
movl %esi, (%esp)
subl $6, %eax
movl %edi, 4(%esp)
cmpl $1, %eax
ja .L1784
movl 536(%esp), %edi
cmpb $2, 53(%edi)
jne .L1784
testb $4, 4(%edx)
je .L1784
movl $-1, 960(%edx)
movl $-1, 956(%edx)
movl $0, 8(%edx)
#APP
pushl %ebx ; popfl
#NO_APP
call nlmclnt_alloc_call
movl $-12, %esi
movl %eax, %ebp
testl %ebp, %ebp
je .L1802
movl $2, (%ebp)
jmp .L1803
.p2align 4,,7
.L1784:
#APP
pushl %ebx ; popfl
#NO_APP
movl $0, (%ebp)
.L1803:
movl 8(%esp), %eax
leal 8(%ebp), %edx
movl %eax, 4(%ebp)
xorl %eax, %eax
leal 20(%ebp), %ebx
movl $53, %ecx
movl %edx, %edi
#APP
rep ; stosl
#NO_APP
movl nlm_cookie, %eax
movl %eax, 8(%ebp)
movl $0, 12(%ebp)
movl nlm_cookie, %eax
incl %eax
movl $4, 8(%edx)
movl %eax, nlm_cookie
movl nsm_local_state, %eax
movl %eax, 196(%edx)
movl 536(%esp), %edx
movl 48(%edx), %eax
leal 24(%ebp), %edx
movl 8(%eax), %eax
pushl $66
movl 92(%eax), %edi
pushl %edi
leal 100(%ebp), %edi
pushl %edx
call memcpy <-----------------------------
leal 412(%ebp), %edx
movl $-8192, %eax
movl $system_utsname+65, 20(%ebp)
#APP
andl %esp,%eax;
#NO_APP
movl %edx, 76(%ebx)
pushl $system_utsname+65
movl 104(%eax), %esi
pushl %esi
pushl $.LC21
pushl %edx
call sprintf
cld
movl %eax, 72(%ebx)
movl $24, %ecx
movl 564(%esp), %esi
addl $28, %esp
rep
movsl
cmpl $5, 532(%esp)
jne .L1835
movl 536(%esp), %ebx
pushl %ebx
pushl %ebp
call nlmclnt_test
jmp .L1865
.p2align 4,,7
.L1835:
movl 532(%esp), %eax
subl $6, %eax
cmpl $1, %eax
ja .L1837
movl 536(%esp), %esi
cmpb $2, 53(%esi)
jne .L1837
pushl %esi
pushl %ebp
call nlmclnt_unlock
popl %edi
movl %eax, %esi
popl %eax
jmp .L1836
.p2align 4,,7
.L1837:
movl 532(%esp), %eax
subl $6, %eax
cmpl $1, %eax
ja .L1839
xorl %eax, %eax
cmpl $7, 532(%esp)
sete %al
movl %eax, 196(%ebp)
movl 536(%esp), %ebx
pushl %ebx
pushl %ebp
call nlmclnt_lock
.L1865:
popl %edx
movl %eax, %esi
popl %ecx
jmp .L1836
.p2align 4,,7
.L1839:
movl $-22, %esi
.L1836:
testl %esi, %esi
jns .L1802
testl $2, (%ebp)
je .L1802
pushl %ebp
call kfree
popl %eax
.L1802:
#APP
pushfl ; popl %ebx ; cli
#NO_APP
movl $-8192, %ecx
#APP
andl %esp,%ecx;
#NO_APP
movl 4(%esp), %edx
movl (%esp), %eax
movl %edx, 960(%ecx)
movl %eax, 956(%ecx)
movl 960(%ecx), %edx
movl 956(%ecx), %eax
xorl $-1, %edx
movl 952(%ecx), %ebp
xorl $-1, %eax
movl 948(%ecx), %edi
andl %ebp, %edx
andl %edi, %eax
orl %eax, %edx
xorl %eax, %eax
testl %edx, %edx
setne %al
movl %eax, 8(%ecx)
#APP
pushl %ebx ; popfl
#NO_APP
.L1777:
testb $2, nlm_debug
je .L1861
pushl %esi
pushl $.LC23
call printk
popl %edx
popl %ecx
.L1861:
movl 8(%esp), %eax
pushl %eax
call nlm_release_host
popl %ebp
movl %esi, %eax
.L1770:
addl $508, %esp
popl %ebx
popl %esi
popl %edi
popl %ebp
ret
Any ideas?
--
Byron Stanoszek Ph: (330) 644-3059
Systems Programmer Fax: (330) 644-8110
Commercial Timesharing Inc. Email: bstanoszek@comtime.com