10分間カーネルソースリーティング(timeシステムコールその2、というよりシステムコールのマクロ)
今日は帰宅が遅かった。なので、あまりソースを読む時間がとれない。
昨日はtimeシステムコールが何をしていたのかを調べた。
ところで、SYSCALL_DEFINE1って何だろ?これを調べるためにinclude/linux/syscalls.hを覗いてみる。
#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
さらにSYSCALL_DEFINExを追いかける。
#ifdef CONFIG_FTRACE_SYSCALLS #define SYSCALL_DEFINEx(x, sname, ...) \ static const char *types_##sname[] = { \ __SC_STR_TDECL##x(__VA_ARGS__) \ }; \ static const char *args_##sname[] = { \ __SC_STR_ADECL##x(__VA_ARGS__) \ }; \ SYSCALL_METADATA(sname, x); \ __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) #else #define SYSCALL_DEFINEx(x, sname, ...) \ __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) #endif
今度は__SYSCALL_DEFINExを追う。
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS #define SYSCALL_DEFINE(name) static inline long SYSC_##name #define __SYSCALL_DEFINEx(x, name, ...) \ asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ { \ __SC_TEST##x(__VA_ARGS__); \ return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \ } \ SYSCALL_ALIAS(sys##name, SyS##name); \ static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)) #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ #define SYSCALL_DEFINE(name) asmlinkage long sys_##name #define __SYSCALL_DEFINEx(x, name, ...) \ asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */
まずは、例によってより簡単なCONFIG_FTRACE_SYSCALLS、CONFIG_HAVE_SYSCALL_WRAPPERS両者が定義されていない場合を追ってみる。
ここまでのところで分かっているマクロを置き換えると
asmlinkage long sys_time(__SC_DECL1(__VA_ARGS__))
となる。
さらに残りの定義を追う。
#define __SC_DECL1(t1, a1) t1 a1
__VA_ARGS__は可変長引数マクロなので、
asmlinkage long sys_time(__SC_DECL1(__VA_ARGS__))
は最終的に
asmlinkage long sys_time(time_t __user * tloc)
となる。
__userは__CHECKER__マクロの有無によって変化し、__CHECKER__マクロが有効な時はtlocがユーザ空間を指すポインタかどうかのチェックをsparseにより行うためのものである。
(kosakiさん情報ありがとう!)
#ifdef __CHECKER__ # define __user __attribute__((noderef, address_space(1))) (中略) #else # define __user
やはり、CONFIG_FTRACE_SYSCALLSとCONFIG_HAVE_SYSCALL_WRAPPERSが気になる。名前から察するに何らかのデバッグ機能かな?
この予想の元、ftraceをググってみると、http://www.atmarkit.co.jp/flinux/rensai/watch2009/watch03a.html
という情報が見つかった。
CONFIG_HAVE_SYSCALL_WRAPPERSはググったけれど有用な情報がなさげなので、読んでみるしかあるまい。
ということで、次回はCONFIG_FTRACE_SYSCALLSとCONFIG_HAVE_SYSCALL_WRAPPERSを見てみたい。(他の事に興味が湧いたらごめんね)