Как разрешить конфликт имен функций при компиляции модуля ядра - PullRequest
3 голосов
/ 15 февраля 2011

Я пытаюсь скомпилировать сторонний модуль ядра для RHEL 5.6, и он терпит неудачу из-за конфликтов имен функций с mutex_acquire и mutex_release. Этот модуль ядра аккуратно компилируется в RHEL 4.7, поэтому что-то изменилось между ядрами 2.6.9 и 2.6.18. К сожалению, этот модуль ядра больше не поддерживается поставщиком, но у меня есть исходный код для mutex.c и mutex.h, который определяет эти функции. К сожалению, существует объектный файл nivxi.o, на который не распространяется исходный код, и этот объектный файл вызывает mutex_acquire и mutex_release, поэтому я не могу просто изменить их имена.

Кроме того, я первоначально попытался просто слегка изменить имена, и ошибки компиляции исчезли, но когда он сделал модуль ядра .ko, он пожаловался, что не может найти mutex_acquire или mutex_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

Error

# 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

1 Ответ

3 голосов
/ 15 февраля 2011

Проблема не будет в вашем объектном файле, поскольку макросы имеют область видимости и заменяются препроцессором.Таким образом, после компиляции макрос больше не существует в том, что касается вашего файла nivxi.o.

Возможно, проблема в вашем файле mutex.h.Я бы посмотрел сверху, и вы, скорее всего, увидите линию #include <lockdep.h>.Таким образом, как только препроцессор переходит к определению вашей функции, он обрабатывает mutex_acquire как токен, подлежащий замене (с неправильным числом аргументов).

Самый простой способ решить вашу проблему - это #undef mutex_acquireи #undef mutex_release в начале mutex.h.Это не позволит препроцессору заменить токены в вашем mutex.h.Поскольку определения имеют область действия с файлом, вам не нужно беспокоиться об этом за пределами вашего приложения

...