In the kernel code, I cannot find the definition of the native_queued_spin_lock_slowpath function, __pv_queued_spin_lock_slowpath is the same, where are these functions defined? I searched all the kernel code, but in vain
The definition of native_queued_spin_lock_slowpath is in "kernel/locking/qspinlock.c", using a macro to change the name of queued_spin_lock_slowpath to native_queued_spin_lock_slowpath when CONFIG_PARAVIRT_SPINLOCKS is defined:
#ifdef CONFIG_PARAVIRT_SPINLOCKS
#define queued_spin_lock_slowpath native_queued_spin_lock_slowpath
#endif
…
void __lockfunc queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
{
The definition of __pv_queued_spin_lock_slowpath is also in "kernel/locking/qspinlock.c" using the same renaming macro trick with a twist — The "qspinlock.c" file includes itself once more, using a guard macro _GEN_PV_LOCK_SLOWPATH to avoid infinite recursive inclusion:
#if !defined(_GEN_PV_LOCK_SLOWPATH) && defined(CONFIG_PARAVIRT_SPINLOCKS)
#define _GEN_PV_LOCK_SLOWPATH
…
#undef queued_spin_lock_slowpath
#define queued_spin_lock_slowpath __pv_queued_spin_lock_slowpath
#include "qspinlock_paravirt.h"
#include "qspinlock.c"
…
#endif
I'm trying to boot a development board containing arm64 core using busybox, u-boot and linux-5.10.0-rc5. The boot process is almost complete but when it enters the shell program, it stops shortly after(with no kernel panic). It doesn't even show the '#' prompt (but with qemu model, the image and busybox works ok with normal shell at the end). I could see that before it stops, there are some system calls from the busybox coming to the kernel, and when it stopped, it was processing system call 73.
(You can follow from arch/arm64/kernel/syscall.c, do_el0_svc () -> el0_svc_common -> invoke_syscall -> __invoke_syscall -> syscall_fn
By examining the files I could see syscall 73 is sys_ppoll. (in include/uapi/asm-generic/unistd.h). I found in include/uapi/asm-generic/unistd.h,
/* fs/select.c */
#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
#define __NR_pselect6 72
__SC_COMP_3264(__NR_pselect6, sys_pselect6_time32, sys_pselect6, compat_sys_pselect6_time32)
#define __NR_ppoll 73
__SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, compat_sys_ppoll_time32)
#endif
The definition of __SC_COMP_3264 is at the first lines of the same file. To see what lines are selected and compiled by the #if/#endif macros, I tried adding a characters 'x' to cause compile error and I could see what lines are compiled. That is shown below.
#ifndef __SYSCALL
x <---- compile error, so compiled, and __SYSCALL(x,y) defined to be nothing?
#define __SYSCALL(x, y)
#endif
#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
x <--------- no compile error, so not compiled
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
#else
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
#endif
#ifdef __SYSCALL_COMPAT
x <-------------- no compile error, so not compiled
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
#else
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
#endif
So this means __SYSCALL(x, y) is defined to be doing nothing. But if that was true, all the other syscall would have done nothing and I figured __SYSCALL was defined previously and found in arch/arm64/kernel/sys.c
#undef __SYSCALL
#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);
#include <asm/unistd.h>
So the function definition becomes __arm64_sys_ppoll and I can see it in the System.map file.
But I couldn't find the definition of __arm64_sys_ppoll. Where can I find the source? My another question is, how can below line be compiled and make error when I do make -j28?
#ifndef __SYSCALL
x <---- compile error, so compiled, and __SYSCALL(x,y) defined to be nothing?
#define __SYSCALL(x, y)
#endif
By the way, this is what I see when I grep for sys_ppoll in the source(excluding all non-arm64 arch files).
./include/linux/compat.h:asmlinkage long compat_sys_ppoll_time32(struct pollfd __user *ufds,
./include/linux/compat.h:asmlinkage long compat_sys_ppoll_time64(struct pollfd __user *ufds,
./include/linux/syscalls.h:asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int,
./include/linux/syscalls.h:asmlinkage long sys_ppoll_time32(struct pollfd __user *, unsigned int,
./include/uapi/asm-generic/unistd.h:__SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, compat_sys_ppoll_time32)
./include/uapi/asm-generic/unistd.h:__SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64)
./tools/include/uapi/asm-generic/unistd.h:__SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, compat_sys_ppoll_time32)
./tools/include/uapi/asm-generic/unistd.h:__SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64)
./arch/arm64/include/asm/unistd32.h:__SYSCALL(__NR_ppoll, compat_sys_ppoll_time32)
./arch/arm64/include/asm/unistd32.h:__SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64)
Thanks for reading and sorry for the long question.
For SYSCALL_DEFINE0, ..., SYSCALL_DEFINE6, first see #Ian Abbott's comment to my original question.
In file include/uapi/asm-generic/unistd.h, you can see the syscall definitions.
For example if you want to see the source code for shmat, you can use grep to see in the file these lines,
/* ipc/shm.c */
#define __NR_shmget 194
__SYSCALL(__NR_shmget, sys_shmget)
#define __NR_shmctl 195
__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
#define __NR_shmat 196
__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
#define __NR_shmdt 197
__SYSCALL(__NR_shmdt, sys_shmdt)
So it says the definition is in file ipc/shm.c. There you can see these lines.
SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
{
unsigned long ret;
long err;
err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA);
if (err)
return err;
force_successful_syscall_return();
return (long)ret;
}
You can see the definition of shmat function with argments list.
I have type:
typedef struct
{
int x;
int y;
int z;
} sdf_test_t;
But when I try to compile the following:
offset = offsetof(sdf_test_t, z);
Visual Studio responds with:
c:\dataflash.c(542) : error C2143: syntax error : missing ')' before 'type'
c:\dataflash.c(542) : error C2059: syntax error : ')'
What is wrong here?
I am using:
Microsoft Visual Studio 2008 x86
Microsoft (R) Visual Studio Version 9.0.21022.8.
The offsetof macro is defined in <stddef.h> as follows:
/* Define offsetof macro */
#ifdef __cplusplus
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
#else
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
#endif
#else
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
#endif /* __cplusplus */
By elimination. I've established that the compiler uses:
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
I've made a simple program as it:
#include <stddef.h>
typedef struct
{
int x;
int y;
int z;
} sdf_test_t;
int main() {
size_t offset = offsetof(sdf_test_t, z);
return 0;
}
I don't have any problems, i think that you can try to isolate the code in another project and test it again.
I managed to fix it by adding the following line to my source file:
#include <stddef.h>
From this, it seems that Visual Studio silently includes header files if you don't include them explicitly. Even worse, It assumes that the source file is C++ by default.
If I don't include a header file with a symbol I use, I would expect the compiler to scream out and report an error, not just make up something...
I am trying to compile a library that has these lines:
#if AE_OS==AE_WINDOWS
#include windows.h
//stuff
#elif AE_OS==AE_POSIX
//other stuff
#endif
When I use cpp -DAE_OS=AE_POSIX I get
cpp/src/ap.cpp:63:21: fatal error: windows.h: No such file or directory
#include <windows.h>
^
Adding a space after the -D does not work, nor does putting AE_OS=AE_POSIX in single or double quotes, putting only AE_POSIX in single or double quotes, and trying all of these combinations with the quotes escaped.
Putting AE_POSIX in escaped single quotes at least does something different, but it is apparently still not correct:
cpp/src/ap.cpp:59:5: warning: character constant too long for its type [enabled by default]
#if AE_OS==AE_WINDOWS
^
I have also tried -D"AE_OS AE_POSIX" thinking that would be the same as #define "AE_OS AE_POSIX" but apparently it ignores the quotes since it defines AE_OS as 1:
<command-line>:0:16: error: missing binary operator before token "1"
cpp/src/ap.cpp:65:7: note: in expansion of macro ‘AE_OS’
#elif AE_OS==AE_POSIX
What is the correct way to do this?
The preprocessor understands expressions of integer type, not strings.
AE_POSIX and AE_WINDOWS are defined as different integers:
/*
* definitions
*/
#define AE_UNKNOWN 0
#define AE_MSVC 1
#define AE_GNUC 2
#define AE_SUNC 3
#define AE_INTEL 1
#define AE_SPARC 2
#define AE_WINDOWS 1
#define AE_POSIX 2
So for POSIX do this:
cpp -DAE_OS=2
I am trying to compile a relatively simple application that I obtained from the web..
When running make I get the following error:
In file included from main.cpp:2:0:
os.h: In function ‘void myOpenDir(const char*)’:
os.h:13:16: error: ‘chdir’ was not declared in this scope
The file os.h looks like this:
#ifndef OS_H
#define OS_H
#if defined(__GNUG__)
#define INT64 long long
#define UINT64 unsigned long long
#include <dirent.h>
#define SPRTR '/'
void myOpenDir(const char* dirpath)
{
chdir(dirpath);
}
#elif defined(_MSC_VER)
#define INT64 __int64
#define UINT64 unsigned __int64
#include <direct.h>
#define SPRTR '\\'
void myOpenDir(const char* dirpath)
{
_chdir(dirpath);
}
#else
#error "Platform not supported. Need to update source code"
#endif
#endif
Someone got an idea why it wont compile?
I also used a g++ compiler via g++-4.7.real -c main.cpp but so far no luck.
Add #include <unistd.h>, as per the chdir manual.