2011/4/20 Lennart Poettering <lenn...@poettering.net>: > On Wed, 20.04.11 09:15, fykc...@gmail.com (fykc...@gmail.com) wrote: > >> >> 2011/4/20 Lennart Poettering <lenn...@poettering.net> >> > >> > On Thu, 14.04.11 17:34, fykc...@gmail.com (fykc...@gmail.com) wrote: >> > >> > > diff --git a/src/missing.h b/src/missing.h >> > > index 35e209f..b367831 100644 >> > > --- a/src/missing.h >> > > +++ b/src/missing.h >> > > @@ -125,7 +125,12 @@ static inline int fanotify_init(unsigned int flags, >> > > unsigned int event_f_flags) >> > > >> > > static inline int fanotify_mark(int fanotify_fd, unsigned int flags, >> > > uint64_t mask, >> > > int dfd, const char *pathname) { >> > > - return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, >> > > dfd, pathname); >> > > + if (sizeof(void *) == 4) >> > > + return syscall(__NR_fanotify_mark, fanotify_fd, flags, >> > > + *((uint32_t *) &mask), *((uint32_t *) >> > > &mask + 1), >> > > + dfd, pathname); >> > > + else /* 64bit */ >> > > + return syscall(__NR_fanotify_mark, fanotify_fd, flags, >> > > mask, dfd, pathname); >> > > } >> > > >> > > #ifndef BTRFS_IOCTL_MAGIC >> > >> > Hmm, wouldn't this break x86-32? >> It works fine on my asus laptop with a 32bit CPU Pentium-M. >> >> We pass two 32bit arguments instead of one 64bit argument. syscall() >> doesn't know the prototype, I guess it will only fetch 9 native-width >> arguments(1 syscall number + 8 parameters) from the stack. Think it again, I find the above description isn't correct. I guess the syscall() works like following: 1. syscall() do indirect system call. 2. kernel system call entry handler fetch 8 arguments from some registers + user stack.
Note, the same system call can have 32bit and 64bit varieties. kernel will fetch arguments properly. e.g. all <32bit arguments are promoted to 32bit arguments, according to some arch ABI, kernel system call entry handler of 32bit variety fetches 8 32bit arguments, and then dispatches it to specific system call handler. In this example, in case of 64bit mips kernel + 32bit userland(o32 ABI): 1. syscall(__NR_fanotify_mark, fanotify_fd, flags, mask_low, mask_high, dfd, pathname) 2. kernel fetches 4 32bit arguments from register a0-a3, and 4 32bit arguments from user stack. see http://lxr.linux.no/linux+v2.6.38/arch/mips/kernel/scall64-o32.S. 3. Process indirect syscall (sys32_syscall), just do a shift, redirect to sys_32_fanotify_mark. 4. In sys_32_fanotify_mark, it merge_64(mask_low, merge_high), and calls sys_fanotify_mark. see http://lxr.linux.no/linux+v2.6.38/arch/mips/kernel/linux32.c#L346 > > Hmm, I am not sure I understand this? How is it possible that both ways > work on x86? There must be quite a difference between passing 6 or 7 > arguments to syscall. > > Or are you suggesting that the current invocation is broken even on x86, > just doesn't become visible since only the lower 32 bit of "mask" are > used? > >> > Also, I'd very much prefer if this could be done with compile time >> > checks instead of "if". i.e. >> > >> > #ifdef __mips__ >> Actually it's not only related to mips, but also to all arch that >> force 64-aligned for 64bit argument (Aurelien said this can also be >> reproduced on powerpc and arm). So what I want is: >> #if PTR_BYTES == 4 >> .... >> >> I tried to find some macro like PTR_BYTES or PTR_SIZE, but failed. Is >> such macro available? > > I think "#ifndef __LP64__" does what you want? Got it, thanks. -- Regards, - cee1 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel