1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/types.h>  // Include something that will define __GLIBC__.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The entire file is wrapped in this #if. We do this so this .cc file can be
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// compiled, even on a non-glibc build.
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(__native_client__) && defined(__GLIBC__)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_wrap.h"
1258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <alloca.h>
144311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch#include <assert.h>
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <dirent.h>
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h>
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <irt.h>
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <irt_syscalls.h>
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <nacl_stat.h>
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h>
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/stat.h>
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include <sys/time.h>
2358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_intercept.h"
2558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "nacl_io/osmman.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void stat_to_nacl_stat(const struct stat* buf, nacl_abi_stat* nacl_buf) {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(nacl_buf, 0, sizeof(struct nacl_abi_stat));
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_dev = buf->st_dev;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_ino = buf->st_ino;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_mode = buf->st_mode;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_nlink = buf->st_nlink;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_uid = buf->st_uid;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_gid = buf->st_gid;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_rdev = buf->st_rdev;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_size = buf->st_size;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_blksize = buf->st_blksize;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_blocks = buf->st_blocks;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_atime = buf->st_atime;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_mtime = buf->st_mtime;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_buf->nacl_abi_st_ctime = buf->st_ctime;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void nacl_stat_to_stat(const nacl_abi_stat* nacl_buf, struct stat* buf) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(buf, 0, sizeof(struct stat));
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_dev = nacl_buf->nacl_abi_st_dev;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_ino = nacl_buf->nacl_abi_st_ino;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_mode = nacl_buf->nacl_abi_st_mode;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_nlink = nacl_buf->nacl_abi_st_nlink;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_uid = nacl_buf->nacl_abi_st_uid;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_gid = nacl_buf->nacl_abi_st_gid;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_rdev = nacl_buf->nacl_abi_st_rdev;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_size = nacl_buf->nacl_abi_st_size ;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_blksize = nacl_buf->nacl_abi_st_blksize;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_blocks = nacl_buf->nacl_abi_st_blocks;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_atime = nacl_buf->nacl_abi_st_atime;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_mtime = nacl_buf->nacl_abi_st_mtime;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf->st_ctime = nacl_buf->nacl_abi_st_ctime;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// From native_client/src/trusted/service_runtime/include/sys/dirent.h
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef nacl_abi___ino_t_defined
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define nacl_abi___ino_t_defined
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef int64_t nacl_abi___ino_t;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef nacl_abi___ino_t nacl_abi_ino_t;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef nacl_abi___off_t_defined
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define nacl_abi___off_t_defined
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef int64_t nacl_abi__off_t;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef nacl_abi__off_t nacl_abi_off_t;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* We need a way to define the maximum size of a name. */
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MAXNAMLEN
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# ifdef NAME_MAX
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#  define MAXNAMLEN NAME_MAX
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# else
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#  define MAXNAMLEN 255
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# endif
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct nacl_abi_dirent {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_abi_ino_t nacl_abi_d_ino;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_abi_off_t nacl_abi_d_off;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint16_t       nacl_abi_d_reclen;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char           nacl_abi_d_name[MAXNAMLEN + 1];
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int d_name_shift = offsetof (dirent, d_name) -
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  offsetof (struct nacl_abi_dirent, nacl_abi_d_name);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)EXTERN_C_BEGIN
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Macro to get the REAL function pointer
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define REAL(name) __nacl_irt_##name##_real
10358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
10458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Macro to get the WRAP function
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define WRAP(name) __nacl_irt_##name##_wrap
10658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
1074311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch// Declare REAL function pointer.
10858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#define DECLARE_REAL_PTR(name) \
1094311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch  typeof(__nacl_irt_##name) REAL(name);
1104311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch
1114311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch// Assign the REAL function pointer.
1124311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch#define ASSIGN_REAL_PTR(name) \
1134311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch  assert(__nacl_irt_##name != NULL); \
1144311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch  REAL(name) = __nacl_irt_##name;
11558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
11658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Switch IRT's pointer to the REAL pointer
11758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#define USE_REAL(name) \
11858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  __nacl_irt_##name = (typeof(__nacl_irt_##name)) REAL(name)
11958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
12058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Switch IRT's pointer to the WRAP function
12158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#define USE_WRAP(name) \
12258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  __nacl_irt_##name = (typeof(__nacl_irt_##name)) WRAP(name)
12358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
12458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
12558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#define EXPAND_SYMBOL_LIST_OPERATION(OP) \
12658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(chdir); \
12758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(close); \
12858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(dup); \
12958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(dup2);  \
13058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(fstat); \
13158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(getcwd);  \
13258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(getdents);  \
13358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(mkdir); \
13458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(open); \
1353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  OP(poll);\
13658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(read); \
13758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(rmdir); \
13858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(seek); \
13958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(stat); \
1403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  OP(select); \
14158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(write); \
14258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(mmap); \
14358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(munmap); \
14458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  OP(open_resource);
14558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
14658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochEXPAND_SYMBOL_LIST_OPERATION(DECLARE_REAL_PTR);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(chdir) (const char* pathname) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (ki_chdir(pathname)) ? errno : 0;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(close)(int fd) {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (ki_close(fd) < 0) ? errno : 0;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(dup)(int fd, int* newfd) NOTHROW {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *newfd = ki_dup(fd);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*newfd < 0) ? errno : 0;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(dup2)(int fd, int newfd) NOTHROW {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (ki_dup2(fd, newfd) < 0) ? errno : 0;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(fstat)(int fd, struct nacl_abi_stat *nacl_buf) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct stat buf;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&buf, 0, sizeof(struct stat));
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int res = ki_fstat(fd, &buf);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (res < 0)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return errno;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stat_to_nacl_stat(&buf, nacl_buf);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* WRAP(getcwd)(char* buf, size_t size) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ki_getcwd(buf, size);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(getdents)(int fd, dirent* nacl_buf, size_t nacl_count, size_t *nread) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int nacl_offset = 0;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // "buf" contains dirent(s); "nacl_buf" contains nacl_abi_dirent(s).
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // nacl_abi_dirent(s) are smaller than dirent(s), so nacl_count bytes buffer
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is enough
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char* buf = (char*)alloca(nacl_count);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int offset = 0;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  count = ki_getdents(fd, buf, nacl_count);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (count < 0)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return errno;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (offset < count) {
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirent* d = (dirent*)(buf + offset);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nacl_abi_dirent* nacl_d = (nacl_abi_dirent*)((char*)nacl_buf + nacl_offset);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nacl_d->nacl_abi_d_ino = d->d_ino;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nacl_d->nacl_abi_d_off = d->d_off;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nacl_d->nacl_abi_d_reclen = d->d_reclen - d_name_shift;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t d_name_len = d->d_reclen - offsetof(dirent, d_name);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(nacl_d->nacl_abi_d_name, d->d_name, d_name_len);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offset += d->d_reclen;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nacl_offset += nacl_d->nacl_abi_d_reclen;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *nread = nacl_offset;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochint WRAP(mkdir)(const char* pathname, mode_t mode) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (ki_mkdir(pathname, mode)) ? errno : 0;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(mmap)(void** addr, size_t length, int prot, int flags, int fd,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               off_t offset) {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (flags & MAP_ANONYMOUS)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return REAL(mmap)(addr, length, prot, flags, fd, offset);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *addr = ki_mmap(*addr, length, prot, flags, fd, offset);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return *addr == (void*)-1 ? errno : 0;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(munmap)(void* addr, size_t length) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Always let the real munmap run on the address range. It is not an error if
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // there are no mapped pages in that range.
225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ki_munmap(addr, length);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(munmap)(addr, length);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(open)(const char* pathname, int oflag, mode_t cmode, int* newfd) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *newfd = ki_open(pathname, oflag);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*newfd < 0) ? errno : 0;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(open_resource)(const char* file, int* fd) {
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *fd = ki_open_resource(file);
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*fd < 0) ? errno : 0;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint WRAP(poll)(struct pollfd *fds, nfds_t nfds, int timeout, int* count) {
2403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  *count = ki_poll(fds, nfds, timeout);
2413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return (*count < 0) ? errno : 0;
2423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(read)(int fd, void *buf, size_t count, size_t *nread) {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ki_is_initialized())
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return REAL(read)(fd, buf, count, nread);
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssize_t signed_nread = ki_read(fd, buf, count);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *nread = static_cast<size_t>(signed_nread);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (signed_nread < 0) ? errno : 0;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(rmdir)(const char* pathname) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (ki_rmdir(pathname) < 0) ? errno : 0;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(seek)(int fd, off_t offset, int whence, off_t* new_offset) {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *new_offset = ki_lseek(fd, offset, whence);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*new_offset < 0) ? errno : 0;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint WRAP(select)(int nfds, fd_set* readfds, fd_set* writefds,
2643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                 fd_set* exceptfds, struct timeval* timeout, int* count) {
2653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  *count = ki_select(nfds, readfds, writefds, exceptfds, timeout);
2663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return (*count < 0) ? errno : 0;
2673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int WRAP(stat)(const char *pathname, struct nacl_abi_stat *nacl_buf) {
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct stat buf;
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&buf, 0, sizeof(struct stat));
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int res = ki_stat(pathname, &buf);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (res < 0)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return errno;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stat_to_nacl_stat(&buf, nacl_buf);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint WRAP(write)(int fd, const void* buf, size_t count, size_t* nwrote) {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ki_is_initialized())
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return REAL(write)(fd, buf, count, nwrote);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssize_t signed_nwrote = ki_write(fd, buf, count);
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *nwrote = static_cast<size_t>(signed_nwrote);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (signed_nwrote < 0) ? errno : 0;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// "real" functions, i.e. the unwrapped original functions.
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_close(int fd) {
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(close)(fd);
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint _real_fstat(int fd, struct stat* buf) {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct nacl_abi_stat st;
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int err = REAL(fstat)(fd, &st);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (err) {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    errno = err;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return -1;
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl_stat_to_stat(&st, buf);
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint _real_getdents(int fd, void* buf, size_t count, size_t* nread) {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // "buf" contains dirent(s); "nacl_buf" contains nacl_abi_dirent(s).
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See WRAP(getdents) above.
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char* nacl_buf = (char*)alloca(count);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t offset = 0;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t nacl_offset = 0;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t nacl_nread;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int err = REAL(getdents)(fd, (dirent*)nacl_buf, count, &nacl_nread);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (err)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return err;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (nacl_offset < nacl_nread) {
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirent* d = (dirent*)((char*)buf + offset);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nacl_abi_dirent* nacl_d = (nacl_abi_dirent*)(nacl_buf + nacl_offset);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    d->d_ino = nacl_d->nacl_abi_d_ino;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    d->d_off = nacl_d->nacl_abi_d_off;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    d->d_reclen = nacl_d->nacl_abi_d_reclen + d_name_shift;
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t d_name_len = nacl_d->nacl_abi_d_reclen -
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        offsetof(nacl_abi_dirent, nacl_abi_d_name);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(d->d_name, nacl_d->nacl_abi_d_name, d_name_len);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offset += d->d_reclen;
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offset += nacl_d->nacl_abi_d_reclen;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *nread = offset;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_lseek(int fd, off_t offset, int whence, off_t* new_offset) {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(seek)(fd, offset, whence, new_offset);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_mkdir(const char* pathname, mode_t mode) {
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(mkdir)(pathname, mode);
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_mmap(void** addr, size_t length, int prot, int flags, int fd,
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               off_t offset) {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(mmap)(addr, length, prot, flags, fd, offset);
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_munmap(void* addr, size_t length) {
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(munmap)(addr, length);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_open(const char* pathname, int oflag, mode_t cmode, int* newfd) {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(open)(pathname, oflag, cmode, newfd);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_open_resource(const char* file, int* fd) {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(open_resource)(file, fd);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_read(int fd, void *buf, size_t count, size_t *nread) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(read)(fd, buf, count, nread);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_rmdir(const char* pathname) {
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(rmdir)(pathname);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int _real_write(int fd, const void *buf, size_t count, size_t *nwrote) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return REAL(write)(fd, buf, count, nwrote);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochuint64_t usec_since_epoch() {
373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  struct timeval tv;
374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  gettimeofday(&tv, NULL);
375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return tv.tv_usec + (tv.tv_sec * 1000000);
376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochstatic bool s_wrapped = false;
3794311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdochstatic bool s_assigned = false;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void kernel_wrap_init() {
38158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  if (!s_wrapped) {
3824311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch    if (!s_assigned) {
3834311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch      EXPAND_SYMBOL_LIST_OPERATION(ASSIGN_REAL_PTR)
3844311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch      s_assigned = true;
3854311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch    }
38658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    EXPAND_SYMBOL_LIST_OPERATION(USE_WRAP)
38758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    s_wrapped = true;
38858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
38958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}
39058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
39158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochvoid kernel_wrap_uninit() {
39258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  if (s_wrapped) {
39358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    EXPAND_SYMBOL_LIST_OPERATION(USE_REAL)
39458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    s_wrapped = false;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)EXTERN_C_END
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(__native_client__) && defined(__GLIBC__)
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
403