赞
踩
系统调用最大参数是6,由下面这个宏定义,位于文件include\linux\syscalls.h
#define SYSCALL_DEFINE_MAXARGS 6
SYSCALL_DEFINE0(fork)
fork:系统调用名。
SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
set_tid_address:系统调用名
int __user *:第一个参数类型
tidptr:第一个参数。
注意参数类型和参数名之间是用逗号隔开的。后面的2-6也是如此。
- COMPAT_SYSCALL_DEFINE2(stat64, const char __user *, filename,
- struct compat_stat64 __user *, statbuf)
- SYSCALL_DEFINE3(cacheflush,
- void __user *, addr,
- unsigned long, bytes,
- int, cache)
- /*
- * The following function implements the controller interface for
- * the eventpoll file that enables the insertion/removal/change of
- * file descriptors inside the interest set.
- */
- SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
- struct epoll_event __user *, event)
- SYSCALL_DEFINE5(fsconfig,
- int, fd,
- unsigned int, cmd,
- const char __user *, _key,
- const void __user *, _value,
- int, aux)
- SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
- unsigned long, prot, unsigned long, flags,
- unsigned long, fd, unsigned long, off)
- #define SYSCALL_DEFINE0(sname) \
- SYSCALL_METADATA(_##sname, 0); \
- asmlinkage long sys_##sname(void); \
- ALLOW_ERROR_INJECTION(sys_##sname, ERRNO); \
- asmlinkage long sys_##sname(void)
- #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
-
- #define SYSCALL_DEFINEx(x, sname, ...) \
- SYSCALL_METADATA(sname, x, __VA_ARGS__) \
- __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
- #define __SYSCALL_DEFINEx(x, name, ...) \
- __diag_push(); \
- __diag_ignore(GCC, 8, "-Wattribute-alias", \
- "Type aliasing is used to sanitize syscall arguments");\
- asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
- __attribute__((alias(__stringify(__se_sys##name)))); \
- ALLOW_ERROR_INJECTION(sys##name, ERRNO); \
- static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
- asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
- asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
- { \
- long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\
- __MAP(x,__SC_TEST,__VA_ARGS__); \
- __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
- return ret; \
- } \
- __diag_pop(); \
- static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
然后看看__MAP宏系列宏
- /*
- * __MAP - apply a macro to syscall arguments
- * __MAP(n, m, t1, a1, t2, a2, ..., tn, an) will expand to
- * m(t1, a1), m(t2, a2), ..., m(tn, an)
- * The first argument must be equal to the amount of type/name
- * pairs given. Note that this list of pairs (i.e. the arguments
- * of __MAP starting at the third one) is in the same format as
- * for SYSCALL_DEFINE<n>/COMPAT_SYSCALL_DEFINE<n>
- */
- #define __MAP0(m,...)
- #define __MAP1(m,t,a,...) m(t,a)
- #define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
- #define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
- #define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
- #define __MAP5(m,t,a,...) m(t,a), __MAP4(m,__VA_ARGS__)
- #define __MAP6(m,t,a,...) m(t,a), __MAP5(m,__VA_ARGS__)
- #define __MAP(n,...) __MAP##n(__VA_ARGS__)
__PROTECT宏
#define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
asmlinkage_protect宏位于文件include\linux\linkage.h
- #ifndef __ASSEMBLY__
- #ifndef asmlinkage_protect
- # define asmlinkage_protect(n, ret, args...) do { } while (0)
- #endif
- #endif
SYSCALL_METADATA宏
这个宏由CONFIG_FTRACE_SYSCALLS决定,定义如下
- #ifdef CONFIG_FTRACE_SYSCALLS
- #define __SC_STR_ADECL(t, a) #a
- #define __SC_STR_TDECL(t, a) #t
-
- extern struct trace_event_class event_class_syscall_enter;
- extern struct trace_event_class event_class_syscall_exit;
- extern struct trace_event_functions enter_syscall_print_funcs;
- extern struct trace_event_functions exit_syscall_print_funcs;
-
- #define SYSCALL_TRACE_ENTER_EVENT(sname) \
- static struct syscall_metadata __syscall_meta_##sname; \
- static struct trace_event_call __used \
- event_enter_##sname = { \
- .class = &event_class_syscall_enter, \
- { \
- .name = "sys_enter"#sname, \
- }, \
- .event.funcs = &enter_syscall_print_funcs, \
- .data = (void *)&__syscall_meta_##sname,\
- .flags = TRACE_EVENT_FL_CAP_ANY, \
- }; \
- static struct trace_event_call __used \
- __attribute__((section("_ftrace_events"))) \
- *__event_enter_##sname = &event_enter_##sname;
-
- #define SYSCALL_TRACE_EXIT_EVENT(sname) \
- static struct syscall_metadata __syscall_meta_##sname; \
- static struct trace_event_call __used \
- event_exit_##sname = { \
- .class = &event_class_syscall_exit, \
- { \
- .name = "sys_exit"#sname, \
- }, \
- .event.funcs = &exit_syscall_print_funcs, \
- .data = (void *)&__syscall_meta_##sname,\
- .flags = TRACE_EVENT_FL_CAP_ANY, \
- }; \
- static struct trace_event_call __used \
- __attribute__((section("_ftrace_events"))) \
- *__event_exit_##sname = &event_exit_##sname;
-
- #define SYSCALL_METADATA(sname, nb, ...) \
- static const char *types_##sname[] = { \
- __MAP(nb,__SC_STR_TDECL,__VA_ARGS__) \
- }; \
- static const char *args_##sname[] = { \
- __MAP(nb,__SC_STR_ADECL,__VA_ARGS__) \
- }; \
- SYSCALL_TRACE_ENTER_EVENT(sname); \
- SYSCALL_TRACE_EXIT_EVENT(sname); \
- static struct syscall_metadata __used \
- __syscall_meta_##sname = { \
- .name = "sys"#sname, \
- .syscall_nr = -1, /* Filled in at boot */ \
- .nb_args = nb, \
- .types = nb ? types_##sname : NULL, \
- .args = nb ? args_##sname : NULL, \
- .enter_event = &event_enter_##sname, \
- .exit_event = &event_exit_##sname, \
- .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \
- }; \
- static struct syscall_metadata __used \
- __attribute__((section("__syscalls_metadata"))) \
- *__p_syscall_meta_##sname = &__syscall_meta_##sname;
-
- static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
- {
- return tp_event->class == &event_class_syscall_enter ||
- tp_event->class == &event_class_syscall_exit;
- }
-
- #else
- #define SYSCALL_METADATA(sname, nb, ...)
-
- static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
- {
- return 0;
- }
- #endif
CONFIG_FTRACE_SYSCALLS从名字上看应该是和trace命令相关的功能。
查看它对应的配置:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。