libc: Add ftruncate64 and improve 64-bit parameter syscall handling.

This patch improves the handling of 64-bit parameters in syscalls on ARM.
The ARM EABI mandates that 64-bit quantities be passed in even/odd register
pairs, which requires special treatment.

This allows us to simplify our implementations of pread() and pwrite()
and remove the C stubs for pread64() and pwrite64().

Also add ftruncate64() to <unistd.h>

Change-Id: I407e2fd223ba0093dd2d0b04c6152fadfc9ce3ef

Bug 3107933
diff --git a/libc/Android.mk b/libc/Android.mk
index 8a22918..6361ad9 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -39,12 +39,10 @@
 	unistd/perror.c \
 	unistd/popen.c \
 	unistd/pread.c \
-	unistd/pread64.c \
 	unistd/pselect.c \
 	unistd/ptsname.c \
 	unistd/ptsname_r.c \
 	unistd/pwrite.c \
-	unistd/pwrite64.c \
 	unistd/raise.c \
 	unistd/reboot.c \
 	unistd/recv.c \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 3023b13..5653c3c 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -85,8 +85,8 @@
 # file descriptors
 ssize_t     read (int, void*, size_t)        3
 ssize_t     write (int, const void*, size_t)       4
-ssize_t     __pread64:pread64 (int, void *, size_t, off_t, off_t) 180
-ssize_t     __pwrite64:pwrite64 (int, void *, size_t, off_t, off_t) 181
+ssize_t     pread64 (int, void *, size_t, off64_t) 180
+ssize_t     pwrite64 (int, void *, size_t, off64_t) 181
 int         __open:open (const char*, int, mode_t)  5
 int         __openat:openat (int, const char*, int, mode_t)  322,295
 int         close (int)                      6
@@ -116,6 +116,7 @@
 int         dup2(int, int)   63
 int         select:_newselect(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *)  142
 int         ftruncate(int, off_t)  93
+int         ftruncate64(int, off64_t) 194
 int         getdents:getdents64(unsigned int, struct dirent *, unsigned int)   217,220
 int         fsync(int)  118
 int         fdatasync(int) 148
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index e25bb31..5210d6c 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -41,8 +41,8 @@
 syscall_src += arch-arm/syscalls/acct.S
 syscall_src += arch-arm/syscalls/read.S
 syscall_src += arch-arm/syscalls/write.S
-syscall_src += arch-arm/syscalls/__pread64.S
-syscall_src += arch-arm/syscalls/__pwrite64.S
+syscall_src += arch-arm/syscalls/pread64.S
+syscall_src += arch-arm/syscalls/pwrite64.S
 syscall_src += arch-arm/syscalls/__open.S
 syscall_src += arch-arm/syscalls/__openat.S
 syscall_src += arch-arm/syscalls/close.S
@@ -70,6 +70,7 @@
 syscall_src += arch-arm/syscalls/dup2.S
 syscall_src += arch-arm/syscalls/select.S
 syscall_src += arch-arm/syscalls/ftruncate.S
+syscall_src += arch-arm/syscalls/ftruncate64.S
 syscall_src += arch-arm/syscalls/getdents.S
 syscall_src += arch-arm/syscalls/fsync.S
 syscall_src += arch-arm/syscalls/fdatasync.S
diff --git a/libc/arch-arm/syscalls/ftruncate64.S b/libc/arch-arm/syscalls/ftruncate64.S
new file mode 100644
index 0000000..37b4744
--- /dev/null
+++ b/libc/arch-arm/syscalls/ftruncate64.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type ftruncate64, #function
+    .globl ftruncate64
+    .align 4
+    .fnstart
+
+ftruncate64:
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_ftruncate64
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+    .fnend
diff --git a/libc/arch-arm/syscalls/__pread64.S b/libc/arch-arm/syscalls/pread64.S
similarity index 85%
rename from libc/arch-arm/syscalls/__pread64.S
rename to libc/arch-arm/syscalls/pread64.S
index ea645e1..a54084c 100644
--- a/libc/arch-arm/syscalls/__pread64.S
+++ b/libc/arch-arm/syscalls/pread64.S
@@ -2,12 +2,12 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pread64, #function
-    .globl __pread64
+    .type pread64, #function
+    .globl pread64
     .align 4
     .fnstart
 
-__pread64:
+pread64:
     mov     ip, sp
     .save   {r4, r5, r6, r7}
     stmfd   sp!, {r4, r5, r6, r7}
diff --git a/libc/arch-arm/syscalls/__pwrite64.S b/libc/arch-arm/syscalls/pwrite64.S
similarity index 85%
rename from libc/arch-arm/syscalls/__pwrite64.S
rename to libc/arch-arm/syscalls/pwrite64.S
index d1263be..f9d56b2 100644
--- a/libc/arch-arm/syscalls/__pwrite64.S
+++ b/libc/arch-arm/syscalls/pwrite64.S
@@ -2,12 +2,12 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, #function
-    .globl __pwrite64
+    .type pwrite64, #function
+    .globl pwrite64
     .align 4
     .fnstart
 
-__pwrite64:
+pwrite64:
     mov     ip, sp
     .save   {r4, r5, r6, r7}
     stmfd   sp!, {r4, r5, r6, r7}
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index 493f437..9575905 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -45,8 +45,8 @@
 syscall_src += arch-sh/syscalls/acct.S
 syscall_src += arch-sh/syscalls/read.S
 syscall_src += arch-sh/syscalls/write.S
-syscall_src += arch-sh/syscalls/__pread64.S
-syscall_src += arch-sh/syscalls/__pwrite64.S
+syscall_src += arch-sh/syscalls/pread64.S
+syscall_src += arch-sh/syscalls/pwrite64.S
 syscall_src += arch-sh/syscalls/__open.S
 syscall_src += arch-sh/syscalls/__openat.S
 syscall_src += arch-sh/syscalls/close.S
@@ -73,6 +73,7 @@
 syscall_src += arch-sh/syscalls/dup2.S
 syscall_src += arch-sh/syscalls/select.S
 syscall_src += arch-sh/syscalls/ftruncate.S
+syscall_src += arch-sh/syscalls/ftruncate64.S
 syscall_src += arch-sh/syscalls/getdents.S
 syscall_src += arch-sh/syscalls/fsync.S
 syscall_src += arch-sh/syscalls/fdatasync.S
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/ftruncate64.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/ftruncate64.S
index a722242..f4c7c1e 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/ftruncate64.S
@@ -2,22 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type ftruncate64, @function
+    .globl ftruncate64
     .align 4
 
-__pwrite64:
-
-    /* get ready for additonal arg */
-    mov.l   @r15, r0
+ftruncate64:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(5 + 0x10)
+    trapa   #(3 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_pwrite64_end
+    bt      __NR_ftruncate64_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -26,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_pwrite64_end:
+__NR_ftruncate64_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_pwrite64
+0:  .long   __NR_ftruncate64
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/__pread64.S b/libc/arch-sh/syscalls/pread64.S
similarity index 89%
rename from libc/arch-sh/syscalls/__pread64.S
rename to libc/arch-sh/syscalls/pread64.S
index 474add3..702a402 100644
--- a/libc/arch-sh/syscalls/__pread64.S
+++ b/libc/arch-sh/syscalls/pread64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pread64, @function
-    .globl __pread64
+    .type pread64, @function
+    .globl pread64
     .align 4
 
-__pread64:
+pread64:
 
     /* get ready for additonal arg */
     mov.l   @r15, r0
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/pwrite64.S
similarity index 89%
rename from libc/arch-sh/syscalls/__pwrite64.S
rename to libc/arch-sh/syscalls/pwrite64.S
index a722242..3f6c192 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/pwrite64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type pwrite64, @function
+    .globl pwrite64
     .align 4
 
-__pwrite64:
+pwrite64:
 
     /* get ready for additonal arg */
     mov.l   @r15, r0
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index c210b21..e8c6a77 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -44,8 +44,8 @@
 syscall_src += arch-x86/syscalls/acct.S
 syscall_src += arch-x86/syscalls/read.S
 syscall_src += arch-x86/syscalls/write.S
-syscall_src += arch-x86/syscalls/__pread64.S
-syscall_src += arch-x86/syscalls/__pwrite64.S
+syscall_src += arch-x86/syscalls/pread64.S
+syscall_src += arch-x86/syscalls/pwrite64.S
 syscall_src += arch-x86/syscalls/__open.S
 syscall_src += arch-x86/syscalls/__openat.S
 syscall_src += arch-x86/syscalls/close.S
@@ -73,6 +73,7 @@
 syscall_src += arch-x86/syscalls/dup2.S
 syscall_src += arch-x86/syscalls/select.S
 syscall_src += arch-x86/syscalls/ftruncate.S
+syscall_src += arch-x86/syscalls/ftruncate64.S
 syscall_src += arch-x86/syscalls/getdents.S
 syscall_src += arch-x86/syscalls/fsync.S
 syscall_src += arch-x86/syscalls/fdatasync.S
diff --git a/libc/arch-x86/syscalls/ftruncate64.S b/libc/arch-x86/syscalls/ftruncate64.S
new file mode 100644
index 0000000..66835ab
--- /dev/null
+++ b/libc/arch-x86/syscalls/ftruncate64.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type ftruncate64, @function
+    .globl ftruncate64
+    .align 4
+
+ftruncate64:
+    pushl   %ebx
+    pushl   %ecx
+    pushl   %edx
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
+    mov     24(%esp), %edx
+    movl    $__NR_ftruncate64, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
diff --git a/libc/arch-x86/syscalls/__pread64.S b/libc/arch-x86/syscalls/pread64.S
similarity index 90%
rename from libc/arch-x86/syscalls/__pread64.S
rename to libc/arch-x86/syscalls/pread64.S
index 3114673..eb004a9 100644
--- a/libc/arch-x86/syscalls/__pread64.S
+++ b/libc/arch-x86/syscalls/pread64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pread64, @function
-    .globl __pread64
+    .type pread64, @function
+    .globl pread64
     .align 4
 
-__pread64:
+pread64:
     pushl   %ebx
     pushl   %ecx
     pushl   %edx
diff --git a/libc/arch-x86/syscalls/__pwrite64.S b/libc/arch-x86/syscalls/pwrite64.S
similarity index 90%
rename from libc/arch-x86/syscalls/__pwrite64.S
rename to libc/arch-x86/syscalls/pwrite64.S
index 28f6536..01389f8 100644
--- a/libc/arch-x86/syscalls/__pwrite64.S
+++ b/libc/arch-x86/syscalls/pwrite64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type pwrite64, @function
+    .globl pwrite64
     .align 4
 
-__pwrite64:
+pwrite64:
     pushl   %ebx
     pushl   %ecx
     pushl   %edx
diff --git a/libc/docs/CHANGES.TXT b/libc/docs/CHANGES.TXT
index 8e23c0e..3fbbee0 100644
--- a/libc/docs/CHANGES.TXT
+++ b/libc/docs/CHANGES.TXT
@@ -14,6 +14,8 @@
 - <sched.h>: Add sched_getcpu(), sched_getaffinity(), sched_setaffinity(),
   cpu_set_t and related macros (e.g. CPU_SETSIZE, CPU_ZERO, CPU_SET, ...)
 
+- <unistd.h>: Add ftruncate64().
+
 -------------------------------------------------------------------------------
 Differences between Android 2.3 and Android 2.2:
 
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 35729ae..cb4d5e5 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -71,6 +71,7 @@
 #define __NR_dup2                         (__NR_SYSCALL_BASE + 63)
 #define __NR__newselect                   (__NR_SYSCALL_BASE + 142)
 #define __NR_ftruncate                    (__NR_SYSCALL_BASE + 93)
+#define __NR_ftruncate64                  (__NR_SYSCALL_BASE + 194)
 #define __NR_fsync                        (__NR_SYSCALL_BASE + 118)
 #define __NR_fdatasync                    (__NR_SYSCALL_BASE + 148)
 #define __NR_fchown32                     (__NR_SYSCALL_BASE + 207)
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index 4a61724..f706d00c 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -52,8 +52,8 @@
 int              acct (const char*  filepath);
 ssize_t          read (int, void*, size_t);
 ssize_t          write (int, const void*, size_t);
-ssize_t          __pread64 (int, void *, size_t, off_t, off_t);
-ssize_t          __pwrite64 (int, void *, size_t, off_t, off_t);
+ssize_t          pread64 (int, void *, size_t, off64_t);
+ssize_t          pwrite64 (int, void *, size_t, off64_t);
 int              __open (const char*, int, mode_t);
 int              __openat (int, const char*, int, mode_t);
 int              close (int);
@@ -83,6 +83,7 @@
 int              dup2 (int, int);
 int              select (int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *);
 int              ftruncate (int, off_t);
+int              ftruncate64 (int, off64_t);
 int              getdents (unsigned int, struct dirent *, unsigned int);
 int              fsync (int);
 int              fdatasync (int);
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index aa236bd..4534fb9 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -145,6 +145,7 @@
 extern int fsync(int);
 extern int fdatasync(int);
 extern int ftruncate(int, off_t);
+extern int ftruncate64(int, off64_t);
 
 extern int pause(void);
 extern unsigned int alarm(unsigned int);
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 41c9500..0535e56 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -245,6 +245,59 @@
 """
 
 
+def param_uses_64bits(param):
+    """Returns True iff a syscall parameter description corresponds
+       to a 64-bit type."""
+    param = param.strip()
+    # First, check that the param type begins with one of the known
+    # 64-bit types.
+    if not ( \
+       param.startswith("int64_t") or param.startswith("uint64_t") or \
+       param.startswith("loff_t") or param.startswith("off64_t") or \
+       param.startswith("long long") or param.startswith("unsigned long long") or
+       param.startswith("signed long long") ):
+           return False
+
+    # Second, check that there is no pointer type here
+    if param.find("*") >= 0:
+            return False
+
+    # Ok
+    return True
+
+def count_arm_param_registers(params):
+    """This function is used to count the number of register used
+       to pass parameters when invoking a thumb or ARM system call.
+       This is because the ARM EABI mandates that 64-bit quantities
+       must be passed in an even+odd register pair. So, for example,
+       something like:
+
+             foo(int fd, off64_t pos)
+
+       would actually need 4 registers:
+             r0 -> int
+             r1 -> unused
+             r2-r3 -> pos
+   """
+    count = 0
+    for param in params:
+        if param_uses_64bits(param):
+            if (count & 1) != 0:
+                count += 1
+            count += 2
+        else:
+            count += 1
+    return count
+
+def count_generic_param_registers(params):
+    count = 0
+    for param in params:
+        if param_uses_64bits(param):
+            count += 2
+        else:
+            count += 1
+    return count
+
 class State:
     def __init__(self):
         self.old_stubs = []
@@ -370,25 +423,28 @@
             syscall_name   = t["name"]
 
             if t["id"] >= 0:
+                num_regs = count_arm_param_registers(syscall_params)
                 if gen_thumb_stubs:
-                    t["asm-thumb"] = self.thumb_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                    t["asm-thumb"] = self.thumb_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
                 else:
                     if gen_eabi_stubs:
-                        t["asm-arm"]   = self.arm_eabi_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                        t["asm-arm"]   = self.arm_eabi_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
                     else:
-                        t["asm-arm"]   = self.arm_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                        t["asm-arm"]   = self.arm_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
 
             if t["id2"] >= 0:
+                num_regs = count_generic_param_registers(syscall_params)
                 if t["cid"] >= 0:
-                    t["asm-x86"] = self.x86_genstub_cid(syscall_func, len(syscall_params), "__NR_"+syscall_name, t["cid"])
+                    t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, "__NR_"+syscall_name, t["cid"])
                 else:
-                    t["asm-x86"] = self.x86_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                    t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, "__NR_"+syscall_name)
             elif t["cid"] >= 0:
                 E("cid for dispatch syscalls is only supported for x86 in "
                   "'%s'" % syscall_name)
                 return
             if t["id3"] >= 0:
-                t["asm-sh"] = self.superh_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                num_regs = count_generic_param_registers(syscall_params)
+                t["asm-sh"] = self.superh_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
 
 
 
diff --git a/libc/unistd/pread.c b/libc/unistd/pread.c
index ec4691a..42fc3bc 100644
--- a/libc/unistd/pread.c
+++ b/libc/unistd/pread.c
@@ -28,10 +28,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-extern int __pread64(int fd, void *buf, size_t nbytes, loff_t offset);
-
 ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset)
 {
-    return __pread64(fd, buf, nbytes, offset);
+    return pread64(fd, buf, nbytes, (off64_t)offset);
 }
 
diff --git a/libc/unistd/pread64.c b/libc/unistd/pread64.c
deleted file mode 100644
index 2a4e08c..0000000
--- a/libc/unistd/pread64.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include <sys/types.h>
-#include <unistd.h>
-
-extern int __pread64(int fd, void *buf, size_t nbytes, loff_t offset);
-
-ssize_t pread64(int fd, void *buf, size_t nbytes, off64_t offset)
-{
-    return __pread64(fd, buf, nbytes, offset);
-}
-
diff --git a/libc/unistd/pwrite.c b/libc/unistd/pwrite.c
index 223e1b3..f106cb3 100644
--- a/libc/unistd/pwrite.c
+++ b/libc/unistd/pwrite.c
@@ -28,10 +28,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-extern int __pwrite64(int fd, const void *buf, size_t nbytes, loff_t offset);
-
 ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset)
 {
-    return __pwrite64(fd, buf, nbytes, offset);
+    return pwrite64(fd, buf, nbytes, (off64_t)offset);
 }
 
diff --git a/libc/unistd/pwrite64.c b/libc/unistd/pwrite64.c
deleted file mode 100644
index b084650..0000000
--- a/libc/unistd/pwrite64.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include <sys/types.h>
-#include <unistd.h>
-
-extern int __pwrite64(int fd, const void *buf, size_t nbytes, loff_t offset);
-
-ssize_t pwrite64(int fd, const void *buf, size_t nbytes, off64_t offset)
-{
-    return __pwrite64(fd, buf, nbytes, offset);
-}
-