From 54cabefc753cc72417bb610cb9f7873f4389e9f5 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 3 Mar 2014 23:09:47 +0000 Subject: Fix fcntl decoding Assume that F_SETLK64, F_SETLKW64, and F_GETLK64 are either defined or not defined altogether. Do not assume that sizeof(off_t) < sizeof(long long) when F_SETLK64 is undefined. This change fixes build with musl libc on x86. * configure.ac: Define SIZEOF_OFF_T. * desc.c (USE_PRINTFLOCK64): New macro. (struct flock64, printflock64): Do not define on X32. (printflock): Replace X32 specific workaround with SIZEOF_OFF_T check. Fix printing off_t members of struct flock. (sys_fcntl): Use USE_PRINTFLOCK64. --- configure.ac | 1 + desc.c | 84 ++++++++++++++++++++++++------------------------------------ 2 files changed, 34 insertions(+), 51 deletions(-) diff --git a/configure.ac b/configure.ac index caa5aed..682f54e 100644 --- a/configure.ac +++ b/configure.ac @@ -297,6 +297,7 @@ AC_CACHE_CHECK([for BLKGETSIZE64], [ac_cv_have_blkgetsize64], AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([long long]) +AC_CHECK_SIZEOF([off_t],,[#include ]) AC_CHECK_SIZEOF([rlim_t],,[#include ]) AC_CACHE_CHECK([for SA_RESTORER], [st_cv_sa_restorer], diff --git a/desc.c b/desc.c index d6d0e47..0686bf4 100644 --- a/desc.c +++ b/desc.c @@ -214,35 +214,26 @@ static const struct xlat perf_event_open_flags[] = { XLAT_END }; +/* + * Assume that F_SETLK64, F_SETLKW64, and F_GETLK64 are either defined + * or not defined altogether. + */ #if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK -# define HAVE_F_SETLK64 1 -#else -# define HAVE_F_SETLK64 0 -#endif - -#if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW -# define HAVE_F_SETLKW64 1 -#else -# define HAVE_F_SETLKW64 0 -#endif - -#if defined(F_GETLK64) && F_GETLK64+0 != F_GETLK -# define HAVE_F_GETLK64 1 +# define USE_PRINTFLOCK64 1 #else -# define HAVE_F_GETLK64 0 +# define USE_PRINTFLOCK64 0 #endif -#if defined(X32) || HAVE_F_SETLK64 || HAVE_F_SETLKW64 || HAVE_F_GETLK64 +#if USE_PRINTFLOCK64 -#ifndef HAVE_STRUCT_FLOCK64 +# ifndef HAVE_STRUCT_FLOCK64 struct flock64 { short int l_type, l_whence; int64_t l_start, l_len; int l_pid; }; -#endif +# endif -/* fcntl/lockf */ static void printflock64(struct tcb *tcp, long addr, int getlk) { @@ -262,22 +253,20 @@ printflock64(struct tcb *tcp, long addr, int getlk) else tprints("}"); } -#endif +#endif /* USE_PRINTFLOCK64 */ -/* fcntl/lockf */ static void printflock(struct tcb *tcp, long addr, int getlk) { struct flock fl; + int r; #if SUPPORTED_PERSONALITIES > 1 -# ifdef X32 - if (current_personality == 0) { - printflock64(tcp, addr, getlk); - return; - } -# endif - if (current_wordsize != sizeof(fl.l_start)) { + if ( +# if SIZEOF_OFF_T > SIZEOF_LONG + current_personality > 0 && +#endif + current_wordsize != sizeof(fl.l_start)) { if (current_wordsize == 4) { /* 32-bit x86 app on x86_64 and similar cases */ struct { @@ -287,15 +276,14 @@ printflock(struct tcb *tcp, long addr, int getlk) int32_t l_len; /* off_t */ int32_t l_pid; /* pid_t */ } fl32; - if (umove(tcp, addr, &fl32) < 0) { - tprints("{...}"); - return; + r = umove(tcp, addr, &fl32); + if (r >= 0) { + fl.l_type = fl32.l_type; + fl.l_whence = fl32.l_whence; + fl.l_start = fl32.l_start; + fl.l_len = fl32.l_len; + fl.l_pid = fl32.l_pid; } - fl.l_type = fl32.l_type; - fl.l_whence = fl32.l_whence; - fl.l_start = fl32.l_start; - fl.l_len = fl32.l_len; - fl.l_pid = fl32.l_pid; } else { /* let people know we have a problem here */ tprintf("", @@ -305,16 +293,17 @@ printflock(struct tcb *tcp, long addr, int getlk) } else #endif { - if (umove(tcp, addr, &fl) < 0) { - tprints("{...}"); - return; - } + r = umove(tcp, addr, &fl); + } + if (r < 0) { + tprints("{...}"); + return; } tprints("{type="); printxval(lockfcmds, fl.l_type, "F_???"); tprints(", whence="); printxval(whence_codes, fl.l_whence, "SEEK_???"); -#ifdef X32 +#if SIZEOF_OFF_T > SIZEOF_LONG tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len); #else tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len); @@ -351,19 +340,12 @@ sys_fcntl(struct tcb *tcp) tprints(", "); printflock(tcp, tcp->u_arg[2], 0); break; -#if HAVE_F_SETLK64 || HAVE_F_SETLKW64 - /* Linux glibc defines SETLK64 as SETLK, - even though the kernel has different values - as does Solaris. */ -#if HAVE_F_SETLK64 - case F_SETLK64: -#endif -#if HAVE_F_SETLKW64 - case F_SETLKW64: -#endif +#if USE_PRINTFLOCK64 + case F_SETLK64: case F_SETLKW64: tprints(", "); printflock64(tcp, tcp->u_arg[2], 0); break; -#endif /* HAVE_F_SETLK64 || HAVE_F_SETLKW64 */ +#endif /* USE_PRINTFLOCK64 */ #ifdef F_NOTIFY case F_NOTIFY: tprints(", "); @@ -408,7 +390,7 @@ sys_fcntl(struct tcb *tcp) tprints(", "); printflock(tcp, tcp->u_arg[2], 1); break; -#if HAVE_F_GETLK64 +#if USE_PRINTFLOCK64 case F_GETLK64: tprints(", "); printflock64(tcp, tcp->u_arg[2], 1); -- cgit v1.2.3