Failed to compile bindsnoop eBPF c code outside of kernel tree - c

I'm trying to build a BPF program written in C into the bpf bytecode. The program C code was taken from https://github.com/iovisor/bcc/blob/master/tools/bindsnoop.py (I used C code from bpf_text with some customizations).
I didn't want to use bcc python tools, my purpose is to write both kernel and user space code in C, and I would like to build a kernel program outside of the kernel tree.
I use Ubuntu 20.10 and here is uname -a output:
Linux bb-VirtualBox 5.8.0-63-generic #71-Ubuntu SMP Tue Jul 13 15:59:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Linux headers are installed, but for some reason I have two directories containing linux headers for 5.8.0-63:
/usr/src/linux-headers-5.8.0-63
and
/usr/src/linux-headers-5.8.0-63-generic
I used this post to create a makefile for my program: https://blogs.oracle.com/linux/post/bpf-in-depth-building-bpf-programs
so the makefile looks like below:
OBJS = kprobe_bindsnoop_kern.o
LLC ?= llc
CLANG ?= clang
INC_FLAGS = -nostdinc -isystem `$(CLANG) -print-file-name=include`
EXTRA_CFLAGS ?= -O2 -emit-llvm
linuxhdrsgen ?= /usr/src/linux-headers-5.8.0-63-generic
LINUXINCLUDE = -I$(linuxhdrsgen)/arch/x86/include \
-I$(linuxhdrsgen)/arch/x86/include/generated/uapi \
-I$(linuxhdrsgen)/arch/x86/include/generated \
-I$(linuxhdrsgen)/arch/x86/include/uapi \
-I$(linuxhdrsgen)/arch/x86/include/generated/uapi \
-I$(linuxhdrsgen)/include/uapi \
-I$(linuxhdrsgen)/include/generated/uapi \
-I$(linuxhdrsgen)/include \
-include ${linuxhdrsgen}/include/linux/kconfig.h
all: $(OBJS)
.PHONY: clean
clean:
rm -f $(OBJS)
INC_FLAGS = -nostdinc -isystem `$(CLANG) -print-file-name=include`
$(OBJS): %.o:%.c
$(CLANG) $(INC_FLAGS) \
-D__KERNEL__ -D__ASM_SYSREG_H \
-Wno-unused-value -Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Wno-gnu-variable-sized-type-not-at-end \
-Wno-address-of-packed-member -Wno-tautological-compare \
-Wno-unknown-warning-option \
-I../include $(LINUXINCLUDE) \
$(EXTRA_CFLAGS) -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $#
And kprobe_bindsnoop_kern.c starts from the following set of include files:
#include <uapi/linux/ptrace.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#include <net/sock.h>
#pragma clang diagnostic pop
#include <net/inet_sock.h>
#include <net/net_namespace.h>
#include <bcc/proto.h>
Below you can see the compilation output:
clang -nostdinc -isystem `clang -print-file-name=include` \
-D__KERNEL__ -D__ASM_SYSREG_H \
-Wno-unused-value -Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Wno-gnu-variable-sized-type-not-at-end \
-Wno-address-of-packed-member -Wno-tautological-compare \
-Wno-unknown-warning-option \
-I../include -I/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/ -I/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/generated/ -I/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.8.0-63-generic/include/uapi -I/usr/src/linux-headers-5.8.0-63-generic/include/generated/uapi -I/usr/src/linux-headers-5.8.0-63-generic/include -include /usr/src/linux-headers-5.8.0-63-generic/include/linux/kconfig.h \
-O2 -emit-llvm -c kprobe_bindsnoop_kern.c -o -| llc -march=bpf -filetype=obj -o kprobe_bindsnoop_kern.o
In file included from kprobe_bindsnoop_kern.c:22:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/uapi/linux/ptrace.h:143:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/ptrace.h:5:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/segment.h:6:
/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/alternative.h:59:2: error: unknown type name 's32'
s32 instr_offset; /* original instruction */
^
/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/alternative.h:60:2: error: unknown type name 's32'
s32 repl_offset; /* offset to replacement instruction */
^
/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/alternative.h:61:2: error: unknown type name 'u16'
u16 cpuid; /* cpuid bit set for replacement */
^
/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/alternative.h:62:2: error: unknown type name 'u8'
u8 instrlen; /* length of original instruction */
^
/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/alternative.h:63:2: error: unknown type name 'u8'
u8 replacementlen; /* length of new instruction */
^
/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/alternative.h:64:2: error: unknown type name 'u8'
u8 padlen; /* length of build-time padding */
^
/usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/alternative.h:85:8: error: unknown type name 'bool'
extern bool skip_smp_alternatives;
^
In file included from kprobe_bindsnoop_kern.c:22:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/uapi/linux/ptrace.h:143:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/ptrace.h:5:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/segment.h:169:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/cache.h:5:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/linux/linkage.h:7:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/linux/export.h:43:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/linux/compiler.h:266:
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:16:15: error: unknown type name 'bool'
static inline bool __kasan_check_read(const volatile void *p, unsigned int size)
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:18:9: error: use of undeclared identifier 'true'
return true;
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:20:15: error: unknown type name 'bool'
static inline bool __kasan_check_write(const volatile void *p, unsigned int size)
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:22:9: error: use of undeclared identifier 'true'
return true;
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:34:15: error: unknown type name 'bool'
static inline bool kasan_check_read(const volatile void *p, unsigned int size)
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:36:9: error: use of undeclared identifier 'true'
return true;
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:38:15: error: unknown type name 'bool'
static inline bool kasan_check_write(const volatile void *p, unsigned int size)
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kasan-checks.h:40:9: error: use of undeclared identifier 'true'
return true;
^
In file included from kprobe_bindsnoop_kern.c:22:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/uapi/linux/ptrace.h:143:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/ptrace.h:5:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/segment.h:169:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/cache.h:5:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/linux/linkage.h:7:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/linux/export.h:43:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/linux/compiler.h:267:
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kcsan-checks.h:148:67: error: unknown type name 'size_t'
static inline void __kcsan_check_access(const volatile void *ptr, size_t size,
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kcsan-checks.h:164:53: error: unknown type name 'size_t'
kcsan_begin_scoped_access(const volatile void *ptr, size_t size, int type,
^
/usr/src/linux-headers-5.8.0-63-generic/include/linux/kcsan-checks.h:184:65: error: unknown type name 'size_t'
static inline void kcsan_check_access(const volatile void *ptr, size_t size,
^
In file included from kprobe_bindsnoop_kern.c:22:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/uapi/linux/ptrace.h:143:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/ptrace.h:6:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/page_types.h:7:
In file included from /usr/src/linux-headers-5.8.0-63-generic/include/linux/mem_encrypt.h:17:
In file included from /usr/src/linux-headers-5.8.0-63-generic/arch/x86/include/asm/mem_encrypt.h:15:
/usr/src/linux-headers-5.8.0-63-generic/include/linux/init.h:155:8: error: unknown type name 'bool'
extern bool rodata_enabled;
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
I tried to add
#include <linux/types.h> or
#include <asm/types.h>
but it doesn't help.
I checked many posts, like this
Error compiling eBPF C code out of kernel tree
and this
how to build BPF program out of the kernel tree
but still failed to get answer.
What am I missing?
Any help will be greatly appreciated ))

Thanks to everyone who tried to help me!
Finally the issue was sooooo simple - just needed to change an order of the include directories specified in the makefile.
Just moved "-I$(linuxhdrsgen)/include" to be the first in the list and it solved the issue.
Meaning, now the list of include dirs looks as follows:
LINUXINCLUDE = -I$(linuxhdrsgen)/include
-I$(linuxhdrsgen)/arch/x86/include
-I$(linuxhdrsgen)/arch/x86/include/generated/uapi
-I$(linuxhdrsgen)/arch/x86/include/generated
-I$(linuxhdrsgen)/arch/x86/include/uapi
-I$(linuxhdrsgen)/arch/x86/include/generated/uapi
-I$(linuxhdrsgen)/include/uapi
-I$(linuxhdrsgen)/include/generated/uapi
-include ${linuxhdrsgen}/include/linux/kconfig.h

Related

No warnings for headers included by headers in non-current directories

How can I let gcc and clang generate warnings for header files included by header files in non-current directories?
I'm using gcc 4.9.2 and clang 3.6.0.
For example, assume that ./include_a.c includes ./dir/a.h, ./dir/a.h includes ./b.h, and ./b.h is expected to generate a warning for -Wconversion; then, gcc and clang with -Wconversion DO NOT generate the expected warning when they compile include_a.c. With -Wconversion -Wsystem-headers, the expected warning is generated, but it often comes with many useless warnings for system headers. When ./b.h is directly included from a source file in the current directory (such as ./include_b.c), the expected warning is generated without -Wsystem-headers.
The following shell script reproduces this example (the case of clang is omitted):
#!/bin/sh
mkdir dir
echo '#include "b.h"' >dir/a.h
echo 'void f() {int a = 0; char b = a;}' >b.h
echo '#include "dir/a.h"' >include_a.c
echo '#include "b.h"' >include_b.c
set -x
gcc -c include_a.c -Wconversion # DOES NOT generate a warning
gcc -c include_a.c -Wconversion -Wsystem-headers # generate a warning
gcc -c include_b.c -Wconversion # generate a warning
Output:
+ gcc -c include_a.c -Wconversion
+ gcc -c include_a.c -Wconversion -Wsystem-headers
In file included from dir/a.h:1:0,
from include_a.c:1:
./b.h: In function ‘f’:
./b.h:1:31: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
void f() {int a = 0; char b = a;}
^
+ gcc -c include_b.c -Wconversion
In file included from include_b.c:1:0:
b.h: In function ‘f’:
b.h:1:31: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
void f() {int a = 0; char b = a;}
^
This behavior seems not to be a bug because gcc and clang perform in the same way, but how can I obtain warnings from all the my source files?

Cannot place kernel's prototype in header

io.cuh:
#ifndef IO_CUH
#define IO_CUH
#include <cuda.h>
typedef struct{
unsigned width;
unsigned height;
unsigned char *image; //RGBA
}rgb_image;
__global__ void transformToGrayKernel(rgb_image *img);
void decodeTwoSteps(const char* filename, rgb_image *img);
void encodeOneStep(const char* filename, rgb_image *img);
void processImage(const char *filename, rgb_image *img);
#endif // IO_CUH
I'm trying to compile simple program using the following makefile:
lodepng.o: lodepng.h
cc -c lodepng.c -o lodepng.o
io.o: io.cuh lodepng.o
nvcc -c io.cu -o io.o
main: io.o
nvcc main.c io.o -o main
'main.c' uses one function from io.cu, which is dependent on lodepng.c.
After some minor warnings that reference to the code, I got the following error:
nvcc main.c io.o -o main nvcc warning : The 'compute_10' and 'sm_10'
architectures are deprecated, and may be removed in a future release.
In file included from main.c:1:0: io.cuh:12:12: error: expected ‘=’,
‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘void’ global void
transformToGrayKernel(rgb_image *img);
^ makefile:6: recipe for target 'main' failed make: *** [main] Error 1
The error is caused by the key word __global__, not your kernel's prototype.
That's because the compiler nvcc will interpret its input file, and choose the corresponding rule to compile it. Although you use the nvcc to compile the "main.c", but it will be treated as a C source file, not a CUDA source code. So the compiler can not recognize the CUDA key word __global__ when it compile the file "main.c".
You can change the file type from "main.c" to "main.cu", and it will be treated as a CUDA source code. Then the compiler can recognize the key word __global__.

Macro defined in main.c not visible in another included file

I have multiple C and H files
In main.c I defined a macro, and in ws_driver.c I want to use it.
ws_driver.h is included in main.c.
main.c
#define WS_PORT PORT_D8
#define WS_BIT D8
#define WS_DDR DDR_D8
#include "ws_driver.h"
In ws_dirver.c I have two checks:
ws_driver.c
#include "ws_driver.h"
#ifndef WS_PORT
# error "WS_PORT not defined!"
#endif
#ifndef WS_BIT
# error "WS_BIT not defined!"
#endif
Both are failing.
$ avr-gcc -std=gnu99 -mmcu=atmega328p -DF_CPU=16000000UL -Os -I. -I -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wno-main -Wno-strict-prototypes -Wno-comment -g2 -ggdb -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax -std=gnu99 main.c ws_driver.c --output main.elf
ws_driver.c:10:3: error: #error "WS_PORT not defined!"
# error "WS_PORT not defined!"
^
ws_driver.c:14:3: error: #error "WS_BIT not defined!"
# error "WS_BIT not defined!"
^
ws_driver.c: In function 'ws_show':
ws_driver.c:23:20: error: 'WS_PORT' undeclared (first use in this function)
#define bus_low() (WS_PORT) &= ~(1 << WS_BIT)
^
ws_driver.c:37:2: note: in expansion of macro 'bus_low'
bus_low();
^
ws_driver.c:23:20: note: each undeclared identifier is reported only once for each function it appears in
#define b......
What am I doing wrong? Please ask if you want to see some other part of the code.
You have to define the macros in a header file, not in the .c file if you want to use them in multiple places.
When the compiler compiles ws_driver.c it only includes ws_driver.h and the macro is not there. It does not include main.c. Each .c file is compiled separately.
Move the macro definitions in say config.h and include it everywhere you need it.
You can also use the compiler's define -DWS_BIT=123 -DOTHER=SMTH. The value you pass will be in the generated object file and can not be changed without recompiling.
If you want to compile only once, then pass these as parameters or create a configure_my_library() function...

Error: could not insert module. Unknown symbol in module

I'm trying to port RR0D Rasta Ring0 Debugger from 32-bit Linux to 64-bit Linux. I have converted 32-bit gcc inline assembly to 64-bit using vim regex as mentioned in my question: How to convert Linux 32-bit gcc inline assembly to 64-bit code?
I'm using gcc with -m64 flag. The target environment is Linux x86-64, custom kernel version 3.5.5.
The Makefile is the following:
EXTRA_CFLAGS += -O2 -Wall -DLINUX_26 -m64
OBJ := module_nux.o breakpoint.o buffering.o command.o disasmbak.o idt.o
OBJ += keyboard.o page.o video.o utils.o import_symb.o core_rr0d.o pci.o
MODULE := rr0d.o
obj-m := $(MODULE)
rr0d-objs := $(OBJ)
default:
make -C /lib/modules/`uname -r`/build/ SUBDIRS=`pwd` modules
clean:
rm -f *.o .*.o.cmd .*.ko.cmd *.mod.c *~
rm -rf .tmp_versions
mrproper:
make clean
rm -f *.ko
make gives a lot of warnings like warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] and warning: cast from pointer to integer of different size [-Wpointer-to-int-cast], but these are probably irrelevant to the topic.
The last rows of the output of make are probably the important ones:
/home/user/code/rr0d/0.3/core_rr0d.c: In function ‘cleanup_rr0d’:
/home/user/code/rr0d/0.3/core_rr0d.c:1938:36: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
CC [M] /home/user/code/rr0d/0.3/pci.o
LD [M] /home/user/code/rr0d/0.3/rr0d.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "RING_HOOO_SEGMENT" [/home/user/code/rr0d/0.3/rr0d.ko] undefined!
CC /home/user/code/rr0d/0.3/rr0d.mod.o
LD [M] /home/user/code/rr0d/0.3/rr0d.ko
make[1]: Leaving directory `/home/user/code/kernel/linux-3.5.5'
So, RING_HOOO_SEGMENT is undefined.
When I try to insmod the module with insmod ./rr0d.ko as root, I get:
Error: could not insert module ./rr0d.ko: Unknown symbol in module
Checking with dmesg | tail -n 1 gives the following output:
[15975.412346] rr0d: Unknown symbol RING_HOOO_SEGMENT (err 0)
So, the unknown symbol definitively is RING_HOOO_SEGMENT.
RING_HOOO_SEGMENT is a constant created with #define in vars.h, that is included in several .c files with #include "vars.h".
The essential #ifdef block of vars.h with #define RING_HOOO_SEGMENT is this one:
#ifdef LINUX_26
#define fake_naked
#if defined(__GNUC__)
// the line below is the important one.
#define RING_HOOO_SEGMENT "$0x7b"
//#define RING_HOOO_SEGMENT "$0x60"
#elif defined(_MSC_VER)
#define RING_HOOO_SEGMENT 0x7b
#endif
#else /* LINUX_24 */
#define fake_naked _asm_("\t" \
"add $0x08, %esp\n\t" \
"popl %ebp\n" \
);
#if defined(__GNUC__)
#define RING_HOOO_SEGMENT "$0x18"
#elif defined(_MSC_VER)
#define RING_HOOO_SEGMENT 0x18
#endif
#define RING_HOOO_SEGMENT_VALUE 0x18
#endif /* LINUX_26 */
Obviously if #define RING_HOOO_SEGMENT "$0x7b" (in #if defined(__GNUC__) inside #ifdef LINUX_26) is commented out, the code won't compile, so it's clear that RING_HOOO_SEGMENT gets defined.
Grepping for RING_HOOO_SEGMENT gives the following matches:
$ grep 'RING_HOOO_SEGMENT' *.c *.o *.ko
core_rr0d.c: "movq RING_HOOO_SEGMENT, %rax\n\t"\
core_rr0d.c: __asm{ movq RING_HOOO_SEGMENT, %rax}\
Binary file rr0d.ko matches
Both core_rr0d.c rows are inline assembly. core_rr0d.c contains #include "vars.h" so that should be fine.
Also the binary module rr0d.ko matches, so it contains the string RING_HOOO_SEGMENT (in some form), even if insmod ./rr0d.ko fails with Error: could not insert module ./rr0d.ko: Unknown symbol in module.
Any ideas what might the reason for this problem and how to proceed to be able to insmod the module?
core_rr0d.c: "movq RING_HOOO_SEGMENT, %rax\n\t"\
Here RING_HOOO_SEGMENT is in a string (probably part of an inline assembler block). As such, the preprocessor will not substitute RING_HOOO_SEGMENT, and it gets passed as-is to the assembler, where the definition of RING_HOOO_SEGMENT is not available.
Fortunately, RING_HOOO_SEGMENT is itself defined as the string "$0x7b", so we can use compile-time string concatenation:
"movq " RING_HOOO_SEGMENT ", %rax\n\t"\
The preprocessor will substitute RING_HOOO_SEGMENT for "$0x7b", then GCC will concatenate these strings before passing it down to the assembler.

Howto resolve a function name conflict when compiling a kernel module

I'm trying to compile a 3rd party kernel module for RHEL 5.6 and it is failing due to function name conflicts with mutex_acquire and mutex_release. This kernel module compiles cleanly on RHEL 4.7 so something changed between kernels 2.6.9 and 2.6.18. Sadly, this kernel module is no longer supported by the vendor but I do have the source code for mutex.c and mutex.h which define these functions. Unfortunately there is an object file nivxi.o upon which no source code is distributed and this object file is calling mutex_acquire and mutex_release so I cannot just simply alter their names.
As an aside, I originally attempted to just modify the names slightly and the compile errors went away but when it went to make the .ko kernel module it complained that it couldn't find mutex_acquire or mutex_release; presumably due to nivxi.o
How do I force the compiler/linker to use the function definitions in my local .c/.h files even though they trounce over like-named functions elsewhere?
mutex.h
NIVXICC void mutex_acquire(mutex_t *mutex);
NIVXICC void mutex_release(mutex_t *mutex);
nivxicc.h (just incase this is pertinent)
#ifndef NIVXICC_H
#define NIVXICC_H
#define NIVXICC __attribute__((regparm(0))) __attribute__((cdecl))
#endif
/usr/include/lockdep.h (conflicting definition)
#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
The problem will not be in your object file as macros have file-scope and are replaced by the preprocessor. Thus after being compiled, the macro no longer exists as far as your nivxi.o file is concerned.
The issue is probably in your mutex.h file. I would look at the top and you will likely see an #include <lockdep.h> line. Thus once the preprocessor gets down to your function definition, it treats mutex_acquire as a token to be replaced (with the wrong number of arguments).
The easiest way to solve your problem will be to #undef mutex_acquire and #undef mutex_release at the beginning of mutex.h. This will prevent the preprocessor from replacing the tokens in your mutex.h. Since defines have file-scope, you don't need to worry about this propagating beyond your application

Resources