Android9.0采用如下Tips3,4进行定位
Tips 1: 用户空间的方法xxx,对应系统调用层方法则是sys_xxx;
Tips 2: unistd.h文件记录着系统调用中断号的信息。(搜索__SYSCALL找到unistd.d文件位置)
/* kernel/signal.c */
__SYSCALL(__NR_kill, sys_kill)
Tips 3: 宏定义SYSCALL_DEFINEx(xxx,…),展开后对应的方法则是sys_xxx;
Tips 4: 方法参数的个数x,对应于SYSCALL_DEFINEx。
kill(int pid, int sig)方法共两个参数,则对应方法于SYSCALL_DEFINE2(kill,...),进入signal.c文件,再次搜索关键字,便能看到方法:
include/linux/syscalls.h
#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, ...) \
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
__attribute__((alias(__stringify(SyS##name)))); \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
{ \
long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
__MAP(x,__SC_TEST,__VA_ARGS__); \
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
} \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
fs/ioctl.c
#0 binder_ioctl (filp=0xffff8800618f6a00, cmd=3224396289, arg=3463711848)
at drivers/android/binder.c:4738
#1 0xffffffff803873fe in C_SYSC_ioctl (arg32=<optimized out>, cmd=<optimized out>,
fd=<optimized out>) at fs/compat_ioctl.c:1592
#2 compat_SyS_ioctl (fd=46, cmd=3224396289, arg32=3463711848) at fs/compat_ioctl.c:1544
#3 0xffffffff80201a69 in do_syscall_32_irqs_on (regs=<optimized out>) at arch/x86/entry/common.c:392
#4 do_fast_syscall_32 (regs=0xffff880052e33f58) at arch/x86/entry/common.c:459
#5 0xffffffff80941c75 in entry_SYSENTER_compat () at arch/x86/entry/entry_64_compat.S:126
#6 0x0000000000000000 in ?? ()
frame 2 compat_SyS_ioctl对应COMPAT_SYSCALL_DEFINE3(ioctl, …),实现和下述SYSCALL_DEFINE3类似
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
{
int error;
struct fd f = fdget(fd);
if (!f.file)
return -EBADF;
error = security_file_ioctl(f.file, cmd, arg);
if (!error)
error = do_vfs_ioctl(f.file, fd, cmd, arg);
fdput(f);
return error;
}
/**
* vfs_ioctl - call filesystem specific ioctl methods
* @filp: open file to invoke ioctl method on
* @cmd: ioctl command to execute
* @arg: command-specific argument for ioctl
*
* Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
* returns -ENOTTY.
*
* Returns 0 on success, -errno on error.
*/
static long vfs_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int error = -ENOTTY;
if (!filp->f_op->unlocked_ioctl)
goto out;
error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
if (error == -ENOIOCTLCMD)
error = -ENOTTY;
out:
return error;
}
drivers/android/binder.c
static const struct file_operations binder_fops = {
.owner = THIS_MODULE,
.poll = binder_poll,
.unlocked_ioctl = binder_ioctl,
.compat_ioctl = binder_ioctl,
.mmap = binder_mmap,
.open = binder_open,
.flush = binder_flush,
.release = binder_release,
};
drivers/staging/android/ashmem.c
static const struct file_operations ashmem_fops = {
.owner = THIS_MODULE,
.open = ashmem_open,
.release = ashmem_release,
.read = ashmem_read,
.llseek = ashmem_llseek,
.mmap = ashmem_mmap,
.unlocked_ioctl = ashmem_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_ashmem_ioctl,
#endif
};
static struct miscdevice ashmem_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "ashmem",
.fops = &ashmem_fops,
};
static int __init ashmem_init(void)
{
int ret;
ashmem_area_cachep = kmem_cache_create("ashmem_area_cache",
sizeof(struct ashmem_area),
0, 0, NULL);
ashmem_range_cachep = kmem_cache_create("ashmem_range_cache",
sizeof(struct ashmem_range),
0, 0, NULL);
ret = misc_register(&ashmem_misc);
register_shrinker(&ashmem_shrinker);
return 0;
}
device_initcall(ashmem_init);
fs/eventpoll.c
#0 ep_poll (ep=0xffff88006ac71180, events=0xcab7adb8, maxevents=16, timeout=0)
at fs/eventpoll.c:1599
#1 0xffffffff8037b095 in SYSC_epoll_wait (timeout=<optimized out>, maxevents=<optimized out>,
events=<optimized out>, epfd=<optimized out>) at fs/eventpoll.c:2009
#2 SyS_epoll_wait (epfd=<optimized out>, events=<optimized out>, maxevents=16,
timeout=<optimized out>) at fs/eventpoll.c:1974
#3 0xffffffff8037b148 in SYSC_epoll_pwait (sigsetsize=<optimized out>, sigmask=<optimized out>,
timeout=<optimized out>, maxevents=<optimized out>, events=<optimized out>, epfd=<optimized out>)
at fs/eventpoll.c:2040
#4 SyS_epoll_pwait (epfd=38, events=3401035192, maxevents=16, timeout=0, sigmask=0,
sigsetsize=<optimized out>) at fs/eventpoll.c:2020
#5 0xffffffff80201a69 in do_syscall_32_irqs_on (regs=<optimized out>) at arch/x86/entry/common.c:392
#6 do_fast_syscall_32 (regs=0xffff88006175bf58) at arch/x86/entry/common.c:459
#7 0xffffffff80941c75 in entry_SYSENTER_compat () at arch/x86/entry/entry_64_compat.S:126
#8 0x0000000000000000 in ?? ()
frame 2 SyS_epoll_wait对应下述方法:
/*
* Implement the event wait interface for the eventpoll file. It is the kernel
* part of the user space epoll_wait(2).
*/
SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,
int, maxevents, int, timeout)
{
include/linux/fs.h
struct file {
union {
struct llist_node fu_llist;
struct rcu_head fu_rcuhead;
} f_u;
struct path f_path;
struct inode *f_inode; /* cached value */
const struct file_operations *f_op;
/*
* Protects f_ep_links, f_flags.
* Must not be taken from IRQ context.
*/
spinlock_t f_lock;
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
struct mutex f_pos_lock;
loff_t f_pos;
struct fown_struct f_owner;
const struct cred *f_cred;
struct file_ra_state f_ra;
u64 f_version;
#ifdef CONFIG_SECURITY
void *f_security;
#endif
/* needed for tty driver, and maybe others */
void *private_data;
#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct list_head f_ep_links;
struct list_head f_tfile_llink;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */