diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c
new file mode 100644
index 0000000..80bf277
--- /dev/null
+++ b/posix/tst-truncate-common.c
@@ -0,0 +1,88 @@
+/* Common f{truncate} tests definitions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static void do_prepare (void);
+#define PREPARE(argc, argv)     do_prepare ()
+static int do_test (void);
+#define TEST_FUNCTION           do_test ()
+
+#include <test-skeleton.c>
+
+static char *temp_filename;
+static int temp_fd;
+
+static void
+do_prepare (void)
+{
+  temp_fd = create_temp_file ("tst-trucate.", &temp_filename);
+  if (temp_fd == -1)
+    {
+      printf ("cannot create temporary file: %m\n");
+      exit (1);
+    }
+}
+
+#define FAIL(str) \
+  do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0)
+
+static int
+do_test_with_offset (off_t offset)
+{
+  struct stat st;
+  char buf[1000];
+
+  memset (buf, 0xcf, sizeof (buf));
+
+  if (pwrite (temp_fd, buf, sizeof (buf), offset) != sizeof (buf))
+    FAIL ("write failed");
+  if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + sizeof (buf)))
+    FAIL ("initial size wrong");
+
+  if (ftruncate (temp_fd, offset + 800) < 0)
+    FAIL ("size reduction with ftruncate failed");
+  if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
+    FAIL ("size after reduction with ftruncate is incorrect");
+
+  /* The following test covers more than POSIX.  POSIX does not require
+     that ftruncate() can increase the file size.  But we are testing
+     Unix systems.  */
+  if (ftruncate (temp_fd, offset + 1200) < 0)
+    FAIL ("size increate with ftruncate failed");
+  if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
+    FAIL ("size after increase is incorrect");
+
+  if (truncate (temp_filename, offset + 800) < 0)
+    FAIL ("size reduction with truncate failed");
+  if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
+    FAIL ("size after reduction with truncate incorrect");
+
+  /* The following test covers more than POSIX.  POSIX does not require
+     that truncate() can increase the file size.  But we are testing
+     Unix systems.  */
+  if (truncate (temp_filename, (offset + 1200)) < 0)
+    FAIL ("size increase with truncate failed");
+  if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
+    FAIL ("size increase with truncate is incorrect");
+
+  return 0;
+}
diff --git a/posix/tst-truncate.c b/posix/tst-truncate.c
index 99bddb3..3166c3b 100644
--- a/posix/tst-truncate.c
+++ b/posix/tst-truncate.c
@@ -17,116 +17,10 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <error.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
+#include "tst-truncate-common.c"
 
-
-/* Allow testing of the 64-bit versions as well.  */
-#ifndef TRUNCATE
-# define TRUNCATE truncate
-# define FTRUNCATE ftruncate
-#endif
-
-#define STRINGIFY(s) STRINGIFY2 (s)
-#define STRINGIFY2(s) #s
-
-/* Prototype for our test function.  */
-extern void do_prepare (int argc, char *argv[]);
-extern int do_test (int argc, char *argv[]);
-
-/* We have a preparation function.  */
-#define PREPARE do_prepare
-
-/* We might need a bit longer timeout.  */
-#define TIMEOUT 20 /* sec */
-
-/* This defines the `main' function and some more.  */
-#include <test-skeleton.c>
-
-/* These are for the temporary file we generate.  */
-char *name;
-int fd;
-
-void
-do_prepare (int argc, char *argv[])
+static int
+do_test (void)
 {
-   size_t name_len;
-
-#define FNAME FNAME2(TRUNCATE)
-#define FNAME2(s) "/" STRINGIFY(s) "XXXXXX"
-
-   name_len = strlen (test_dir);
-   name = xmalloc (name_len + sizeof (FNAME));
-   mempcpy (mempcpy (name, test_dir, name_len), FNAME, sizeof (FNAME));
-   add_temp_file (name);
-
-   /* Open our test file.   */
-   fd = mkstemp (name);
-   if (fd == -1)
-     error (EXIT_FAILURE, errno, "cannot open test file `%s'", name);
-}
-
-
-int
-do_test (int argc, char *argv[])
-{
-  struct stat st;
-  char buf[1000];
-
-  memset (buf, '\0', sizeof (buf));
-
-  if (write (fd, buf, sizeof (buf)) != sizeof (buf))
-    error (EXIT_FAILURE, errno, "during write");
-
-  if (fstat (fd, &st) < 0 || st.st_size != sizeof (buf))
-    error (EXIT_FAILURE, 0, "initial size wrong");
-
-
-  if (FTRUNCATE (fd, 800) < 0)
-    error (EXIT_FAILURE, errno, "size reduction with %s failed",
-	   STRINGIFY (FTRUNCATE));
-
-  if (fstat (fd, &st) < 0 || st.st_size != 800)
-    error (EXIT_FAILURE, 0, "size after reduction with %s incorrect",
-	   STRINGIFY (FTRUNCATE));
-
-  /* The following test covers more than POSIX.  POSIX does not require
-     that ftruncate() can increase the file size.  But we are testing
-     Unix systems.  */
-  if (FTRUNCATE (fd, 1200) < 0)
-    error (EXIT_FAILURE, errno, "size increase with %s failed",
-	   STRINGIFY (FTRUNCATE));
-
-  if (fstat (fd, &st) < 0 || st.st_size != 1200)
-    error (EXIT_FAILURE, 0, "size after increase with %s incorrect",
-	   STRINGIFY (FTRUNCATE));
-
-
-  if (TRUNCATE (name, 800) < 0)
-    error (EXIT_FAILURE, errno, "size reduction with %s failed",
-	   STRINGIFY (TRUNCATE));
-
-  if (fstat (fd, &st) < 0 || st.st_size != 800)
-    error (EXIT_FAILURE, 0, "size after reduction with %s incorrect",
-	   STRINGIFY (TRUNCATE));
-
-  /* The following test covers more than POSIX.  POSIX does not require
-     that truncate() can increase the file size.  But we are testing
-     Unix systems.  */
-  if (TRUNCATE (name, 1200) < 0)
-    error (EXIT_FAILURE, errno, "size increase with %s failed",
-	   STRINGIFY (TRUNCATE));
-
-  if (fstat (fd, &st) < 0 || st.st_size != 1200)
-    error (EXIT_FAILURE, 0, "size after increase with %s incorrect",
-	   STRINGIFY (TRUNCATE));
-
-
-  close (fd);
-  unlink (name);
-
-  return 0;
+  return do_test_with_offset (0);
 }
diff --git a/posix/tst-truncate64.c b/posix/tst-truncate64.c
index 64eb0a4..08c4942 100644
--- a/posix/tst-truncate64.c
+++ b/posix/tst-truncate64.c
@@ -17,7 +17,22 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define TRUNCATE truncate64
-#define FTRUNCATE ftruncate64
+#define _FILE_OFFSET_BITS 64
+#include "tst-truncate-common.c"
 
-#include "tst-truncate.c"
+static int
+do_test (void)
+{
+  int ret;
+
+  ret = do_test_with_offset (0);
+  if (ret == -1)
+    return -1;
+
+  off_t base_offset = UINT32_MAX + 512LL;
+  ret = do_test_with_offset (base_offset);
+  if (ret == -1)
+    return 1;
+
+  return 0;
+}
diff --git a/sysdeps/unix/sysv/linux/arm/ftruncate64.c b/sysdeps/unix/sysv/linux/arm/ftruncate64.c
deleted file mode 100644
index 0e8d8ba..0000000
--- a/sysdeps/unix/sysv/linux/arm/ftruncate64.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <endian.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Truncate the file FD refers to to LENGTH bytes.  */
-int
-__ftruncate64 (int fd, off64_t length)
-{
-  unsigned int low = length & 0xffffffff;
-  unsigned int high = length >> 32;
-  int result = INLINE_SYSCALL (ftruncate64, 4, fd, 0,
-			       __LONG_LONG_PAIR (high, low));
-  return result;
-}
-weak_alias (__ftruncate64, ftruncate64)
diff --git a/sysdeps/unix/sysv/linux/ftruncate.c b/sysdeps/unix/sysv/linux/ftruncate.c
new file mode 100644
index 0000000..a70de65
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ftruncate.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <sysdep.h>
+#include <errno.h>
+
+#ifndef __OFF_T_MATCHES_OFF64_T
+/* Truncate the file FD refers to LENGTH bytes.  */
+int
+__ftruncate (int fd, off_t length)
+{
+  return INLINE_SYSCALL_CALL (ftruncate, fd, length);
+}
+weak_alias (__ftruncate, ftruncate)
+#endif
diff --git a/sysdeps/unix/sysv/linux/ftruncate64.c b/sysdeps/unix/sysv/linux/ftruncate64.c
index a6bf878..914ce67 100644
--- a/sysdeps/unix/sysv/linux/ftruncate64.c
+++ b/sysdeps/unix/sysv/linux/ftruncate64.c
@@ -15,22 +15,23 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sys/types.h>
-#include <errno.h>
-#include <endian.h>
 #include <unistd.h>
-
 #include <sysdep.h>
-#include <sys/syscall.h>
+#include <errno.h>
+
+#ifndef __NR_ftruncate64
+# define __NR_ftruncate64 __NR_ftruncate
+#endif
 
 /* Truncate the file referenced by FD to LENGTH bytes.  */
 int
 __ftruncate64 (int fd, off64_t length)
 {
-  unsigned int low = length & 0xffffffff;
-  unsigned int high = length >> 32;
-  int result = INLINE_SYSCALL (ftruncate64, 3, fd,
-			       __LONG_LONG_PAIR (high, low));
-  return result;
+  return INLINE_SYSCALL_CALL (ftruncate64, fd,
+			      __ALIGNMENT_ARG SYSCALL_LL64 (length));
 }
 weak_alias (__ftruncate64, ftruncate64)
+
+#ifdef __OFF_T_MATCHES_OFF64_T
+weak_alias (__ftruncate64, ftruncate);
+#endif
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/ftruncate.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/ftruncate.c
deleted file mode 100644
index e1b500d..0000000
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/ftruncate.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-/* Truncate the file FD refers to to LENGTH bytes.  */
-int
-__ftruncate (int fd, off_t length)
-{
-  return INLINE_SYSCALL (ftruncate64, __ALIGNMENT_COUNT (3, 4), fd,
-                         __ALIGNMENT_ARG
-                         __LONG_LONG_PAIR (length >> 31, length));
-}
-weak_alias (__ftruncate, ftruncate)
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/ftruncate64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/ftruncate64.c
deleted file mode 100644
index 946f05a..0000000
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/ftruncate64.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-/* Truncate the file FD refers to to LENGTH bytes.  */
-int
-__ftruncate64 (int fd, off64_t length)
-{
-  unsigned int low = length & 0xffffffff;
-  unsigned int high = length >> 32;
-  return INLINE_SYSCALL (ftruncate64, __ALIGNMENT_COUNT (3, 4), fd,
-                         __ALIGNMENT_ARG __LONG_LONG_PAIR (high, low));
-}
-weak_alias (__ftruncate64, ftruncate64)
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ftruncate64.c b/sysdeps/unix/sysv/linux/mips/mips32/ftruncate64.c
deleted file mode 100644
index 0e8d8ba..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips32/ftruncate64.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <endian.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Truncate the file FD refers to to LENGTH bytes.  */
-int
-__ftruncate64 (int fd, off64_t length)
-{
-  unsigned int low = length & 0xffffffff;
-  unsigned int high = length >> 32;
-  int result = INLINE_SYSCALL (ftruncate64, 4, fd, 0,
-			       __LONG_LONG_PAIR (high, low));
-  return result;
-}
-weak_alias (__ftruncate64, ftruncate64)
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/ftruncate64.c b/sysdeps/unix/sysv/linux/mips/mips64/ftruncate64.c
deleted file mode 100644
index 6e25b02..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips64/ftruncate64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* Empty.  */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c
deleted file mode 100644
index 9eee1d7..0000000
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Truncate the file referenced by FD to LENGTH bytes.  */
-int
-__ftruncate64 (int fd, off64_t length)
-{
-  /* On PPC32 64bit values are aligned in odd/even register pairs.  */
-  int result = INLINE_SYSCALL (ftruncate64, 4, fd, 0,
-			       (long) (length >> 32),
-			       (long) length);
-
-  return result;
-}
-weak_alias (__ftruncate64, ftruncate64)
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/ftruncate64.c b/sysdeps/unix/sysv/linux/wordsize-64/ftruncate64.c
deleted file mode 100644
index 673a8b5..0000000
--- a/sysdeps/unix/sysv/linux/wordsize-64/ftruncate64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* ftruncate64 is the same as ftruncate. */
