【问题标题】:Howto resolve a function name conflict when compiling a kernel module编译内核模块时如何解决函数名冲突
【发布时间】:2011-02-15 08:40:09
【问题描述】:

我正在尝试为 RHEL 5.6 编译第 3 方内核模块,但由于函数名称与 mutex_acquiremutex_release 冲突而失败。这个内核模块在 RHEL 4.7 上编译干净,所以内核 2.6.9 和 2.6.18 之间发生了一些变化。遗憾的是,供应商不再支持这个内核模块,但我确实有定义这些函数的mutex.cmutex.h 的源代码。不幸的是,有一个目标文件nivxi.o 没有分发任何源代码,并且该目标文件正在调用mutex_acquiremutex_release,所以我不能简单地更改它们的名称。

顺便说一句,我最初尝试只是稍微修改名称并且编译错误消失了,但是当它去制作 .ko 内核模块时它抱怨它找不到mutex_acquiremutex_release;大概是因为nivxi.o

我如何强制编译器/链接器使用我本地 .c/.h 文件中的函数定义,即使它们在其他地方优于同名函数?

mutex.h

NIVXICC void mutex_acquire(mutex_t *mutex);
NIVXICC void mutex_release(mutex_t *mutex);

nivxicc.h(以防万一这是相关的)

#ifndef NIVXICC_H
#define NIVXICC_H
#define NIVXICC __attribute__((regparm(0))) __attribute__((cdecl))
#endif

/usr/include/lockdep.h(定义冲突)

#ifdef CONFIG_DEBUG_LOCK_ALLOC
# ifdef CONFIG_PROVE_LOCKING
#  define mutex_acquire(l, s, t, i)             lock_acquire(l, s, t, 0, 2, i)
# else
#  define mutex_acquire(l, s, t, i)             lock_acquire(l, s, t, 0, 1, i)
# endif
# define mutex_release(l, n, i)                 lock_release(l, n, i)
#else
# define mutex_acquire(l, s, t, i)              do { } while (0)
# define mutex_release(l, n, i)                 do { } while (0)
#endif

错误

# make
make -C /lib/modules/2.6.18-238.el5/build SUBDIRS=/usr/local/nivxi/src KBUILD_VERBOSE=1 modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-238.el5-i686'
test -e include/linux/autoconf.h -a -e include/config/auto.conf || (            \
        echo;                                                           \
        echo "  ERROR: Kernel configuration is invalid.";               \
        echo "         include/linux/autoconf.h or include/config/auto.conf are missing.";      \
        echo "         Run 'make oldconfig && make prepare' on kernel src to fix it.";  \
        echo;                                                           \
        /bin/false)
mkdir -p /usr/local/nivxi/src/.tmp_versions
rm -f /usr/local/nivxi/src/.tmp_versions/*
make -f scripts/Makefile.build obj=/usr/local/nivxi/src
gcc -m32 -Wp,-MD,/usr/local/nivxi/src/.vxi.o.d  -nostdinc -isystem \
/usr/lib/gcc/i386-redhat-linux/4.1.2/include -D__KERNEL__ -Iinclude \
-include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes \
-Wno-trigraphs -fno-strict-aliasing -fno-common -Wstrict-prototypes \
-Wundef -Werror-implicit-function-declaration \
-fno-delete-null-pointer-checks -fwrapv -Os -pipe -msoft-float \
-fno-builtin-sprintf -fno-builtin-log2 -fno-builtin-puts \
-mpreferred-stack-boundary=2  -march=i686 -mtune=generic -mtune=generic \
-mregparm=3 -ffreestanding -Iinclude/asm-i386/mach-generic \
-Iinclude/asm-i386/mach-default -fomit-frame-pointer -g -fno-stack-protector \
-Wdeclaration-after-statement -Wno-pointer-sign -DVXI_MAJOR=0 \
-DREMAP_PAGE_RANGE_VMA -D__DEBUG__ -DMODULE -D"KBUILD_STR(s)=#s" \
-D"KBUILD_BASENAME=KBUILD_STR(vxi)" -D"KBUILD_MODNAME=KBUILD_STR(vximod)" \
-c -o /usr/local/nivxi/src/.tmp_vxi.o /usr/local/nivxi/src/vxi.c

    In file included from /usr/local/nivxi/src/vxi.c:13:
    /usr/local/nivxi/src/mutex.h:59:42: error: macro "mutex_acquire" requires 4 arguments, but only 1 given
    In file included from /usr/local/nivxi/src/vxi.c:13:
    /usr/local/nivxi/src/mutex.h:59: warning: ‘regparm’ attribute only applies to function types
    /usr/local/nivxi/src/mutex.h:59: warning: ‘cdecl’ attribute only applies to function types
    /usr/local/nivxi/src/mutex.h:61:42: error: macro "mutex_release" requires 3 arguments, but only 1 given
    /usr/local/nivxi/src/mutex.h:61: warning: ‘regparm’ attribute only applies to function types
    /usr/local/nivxi/src/mutex.h:61: warning: ‘cdecl’ attribute only applies to function types
    /usr/local/nivxi/src/vxi.c:128:31: error: macro "mutex_acquire" requires 4 arguments, but only 1 given
    /usr/local/nivxi/src/vxi.c:133:31: error: macro "mutex_release" requires 3 arguments, but only 1 given
    /usr/local/nivxi/src/vxi.c:146:31: error: macro "mutex_acquire" requires 4 arguments, but only 1 given
    /usr/local/nivxi/src/vxi.c:158:31: error: macro "mutex_release" requires 3 arguments, but only 1 given
    /usr/local/nivxi/src/vxi.c: In function ‘vxi_mmap’:
    /usr/local/nivxi/src/vxi.c:243: error: implicit declaration of function ‘remap_page_range’
    make[2]: *** [/usr/local/nivxi/src/vxi.o] Error 1
    make[1]: *** [_module_/usr/local/nivxi/src] Error 2
    make[1]: Leaving directory `/usr/src/kernels/2.6.18-238.el5-i686'
    make: *** [default] Error 2

【问题讨论】:

  • 重命名 nivxicc 的互斥函数(并在其整个源代码中这样做,而不仅仅是 .h 文件)并且应该这样做。
  • @user 不能,请参阅我的问题的第 1 段的最后一句和第 2 段的所有内容

标签: c linux-kernel kernel kernel-module


【解决方案1】:

问题不会出现在您的目标文件中,因为宏具有文件范围并被预处理器替换。因此,在编译后,就您的nivxi.o 文件而言,宏不再存在。

问题可能在您的mutex.h 文件中。我会查看顶部,您可能会看到#include <lockdep.h> 行。因此,一旦预处理器深入到您的函数定义,它会将mutex_acquire 视为要替换的标记(使用错误数量的参数)。

解决您的问题的最简单方法是在mutex.h 的开头发送#undef mutex_acquire#undef mutex_release。这将防止预处理器替换您的mutex.h 中的令牌。由于定义具有文件范围,因此您无需担心这种传播超出您的应用程序

【讨论】:

  • 感谢您的回复。不幸的是,#undef CONFIG_DEBUG_LOCK_ALLOC 不起作用,因为您会注意到 #else 子句仍然定义了 mutex_acquiremutex_release 无论如何。此外,虽然这些是<linux/lockdep.h> 标头中的宏,但它们是“mutex.h”中的一流函数声明,这就是nivxi.o 将它们链接并抱怨的原因。到目前为止,我发现的唯一解决方法是更改​​ <linux/lockdep.h> 并用 #ifndef NOLOCKDEP 包装该宏块,然后发出 -DNOLOCKDEP 作为编译器标志。
  • 啊,我错过了嵌套定义。我已经编辑了上面的解决方案。这应该使您的修改包含在您的模块中
  • 谢谢,这成功了,无需更改 <linux/lockdep.h> 标头
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多