This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Undefined references to 'memcpy' when compiling Linux Kernel


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(&current->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(&current->blocked);  /* Mask all signals */
                recalc_sigpending(current);
                spin_unlock_irqrestore(&current->sigmask_lock, flags);

                call = nlmclnt_alloc_call();
                if (!call) {
                        status = -ENOMEM;
                        goto out_restore;
                }
                call->a_flags = RPC_TASK_ASYNC;
        } else {
                spin_unlock_irqrestore(&current->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(&current->sigmask_lock, flags);
        current->blocked = oldset;
        recalc_sigpending(current);
        spin_unlock_irqrestore(&current->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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]