LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - sel_ldr-inl.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 39 26 66.7 %
Date: 2012-02-16 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*******************************************************************************
       8                 :  *
       9                 :  * DO NOT INCLUDE EXCEPT FROM sel_ldr.h
      10                 :  *
      11                 :  ******************************************************************************/
      12                 : 
      13                 : /*
      14                 :  * Routines to translate addresses between user and "system" or
      15                 :  * service runtime addresses.  the *Addr* versions will return
      16                 :  * kNaClBadAddress if the user address is outside of the user address
      17                 :  * space, e.g., if the input addresses for *UserToSys* is outside of
      18                 :  * (1<<nap->addr_bits), and correspondingly for *SysToUser* if the
      19                 :  * input system address does not correspond to a user address.
      20                 :  * Generally, the *Addr* versions are used when the addresses come
      21                 :  * from untrusted usre code, and kNaClBadAddress would translate to an
      22                 :  * EINVAL return from a syscall.  The *Range code ensures that the
      23                 :  * entire address range is in the user address space.
      24                 :  *
      25                 :  * Note that just because an address is within the address space, it
      26                 :  * doesn't mean that it is safe to acceess the memory: the page may be
      27                 :  * protected against access.
      28                 :  *
      29                 :  * The non-*Addr* versions abort the program rather than return an
      30                 :  * error indication.
      31                 :  */
      32                 : 
      33                 : /*
      34                 :  * address translation routines.  after a NaClApp is started, the
      35                 :  * member variables accessed by these routines are read-only, so no
      36                 :  * locking is needed to use these functions, as long as the NaClApp
      37                 :  * structure doesn't get destructed/deallocated.
      38                 :  *
      39                 :  * the first is used internally when a NULL pointer is okay, typically
      40                 :  * for address manipulation.
      41                 :  *
      42                 :  * the next two are for syscalls to do address translation, e.g., for
      43                 :  * system calls; -1 indicates an error, so the syscall can return
      44                 :  * EINVAL or EFAULT or whatever is appropriate.
      45                 :  *
      46                 :  * the latter two interfaces are for use everywhere else in the loader
      47                 :  * / service runtime and will log a fatal error and abort the process
      48                 :  * when an error is detected.  (0 is not a good error indicator, since
      49                 :  * 0 is a valid user address.)
      50                 :  */
      51                 : 
      52                 : static INLINE uintptr_t NaClUserToSysAddrNullOkay(struct NaClApp  *nap,
      53               0 :                                                   uintptr_t       uaddr) {
      54               0 :   if (((uintptr_t) 1U << nap->addr_bits <= uaddr)) {
      55               0 :     return kNaClBadAddress;
      56                 :   }
      57               0 :   return uaddr + nap->mem_start;
      58                 : }
      59                 : 
      60                 : static INLINE uintptr_t NaClUserToSysAddr(struct NaClApp  *nap,
      61              42 :                                           uintptr_t       uaddr) {
      62              42 :   if (0 == uaddr || ((uintptr_t) 1U << nap->addr_bits) <= uaddr) {
      63               3 :     return kNaClBadAddress;
      64                 :   }
      65              39 :   return uaddr + nap->mem_start;
      66                 : }
      67                 : 
      68                 : static INLINE int NaClIsUserAddr(struct NaClApp  *nap,
      69               0 :                                  uintptr_t       sysaddr) {
      70               0 :   return nap->mem_start <= sysaddr &&
      71                 :          sysaddr < nap->mem_start + ((uintptr_t) 1U << nap->addr_bits);
      72                 : }
      73                 : 
      74                 : static INLINE uintptr_t NaClUserToSysAddrRange(struct NaClApp  *nap,
      75                 :                                                uintptr_t       uaddr,
      76             198 :                                                size_t          count) {
      77                 :   uintptr_t end_addr;
      78                 : 
      79             198 :   if (0 == uaddr) {
      80               0 :     return kNaClBadAddress;
      81                 :   }
      82             198 :   end_addr = uaddr + count;
      83             198 :   if (end_addr < uaddr) {
      84                 :     /* unsigned wraparound */
      85               3 :     return kNaClBadAddress;
      86                 :   }
      87             195 :   if (((uintptr_t) 1U << nap->addr_bits) < end_addr) {
      88               3 :     return kNaClBadAddress;
      89                 :   }
      90             192 :   return uaddr + nap->mem_start;
      91                 : }
      92                 : 
      93                 : static INLINE uintptr_t NaClUserToSys(struct NaClApp  *nap,
      94            1153 :                                       uintptr_t       uaddr) {
      95            1153 :   if (0 == uaddr || ((uintptr_t) 1U << nap->addr_bits) <= uaddr) {
      96               0 :     NaClLog(LOG_FATAL,
      97                 :             "NaClUserToSys: uaddr 0x%08"NACL_PRIxPTR", "
      98                 :             "addr space %"NACL_PRId8" bits\n",
      99                 :             uaddr, nap->addr_bits);
     100                 :   }
     101            1153 :   return uaddr + nap->mem_start;
     102                 : }
     103                 : 
     104                 : static INLINE uintptr_t NaClSysToUser(struct NaClApp  *nap,
     105             358 :                                       uintptr_t       sysaddr) {
     106             358 :   if (sysaddr < nap->mem_start ||
     107                 :       nap->mem_start + ((uintptr_t) 1U << nap->addr_bits) <= sysaddr) {
     108               0 :     NaClLog(LOG_FATAL,
     109                 :             ("NaclSysToUser: sysaddr 0x%08"NACL_PRIxPTR","
     110                 :              " mem_start 0x%08"NACL_PRIxPTR","
     111                 :              " addr space %"NACL_PRId8" bits\n"),
     112                 :             sysaddr, nap->mem_start, nap->addr_bits);
     113                 :   }
     114             358 :   return sysaddr - nap->mem_start;
     115                 : }
     116                 : 
     117                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
     118                 : /*
     119                 :  * For x86-64 sandboxing, %rsp and %rbp are system addresses already.
     120                 :  */
     121                 : static INLINE uintptr_t NaClUserToSysStackAddr(struct NaClApp *nap,
     122                 :                                                uintptr_t      stackaddr) {
     123                 :   UNREFERENCED_PARAMETER(nap);
     124                 :   return stackaddr;
     125                 : }
     126                 : 
     127                 : static INLINE uintptr_t NaClSysToUserStackAddr(struct NaClApp *nap,
     128                 :                                                uintptr_t      stackaddr) {
     129                 :   UNREFERENCED_PARAMETER(nap);
     130                 :   return stackaddr;
     131                 : }
     132                 : 
     133                 : #else
     134                 : 
     135                 : static INLINE uintptr_t NaClUserToSysStackAddr(struct NaClApp *nap,
     136            1124 :                                                uintptr_t      stackaddr) {
     137            1124 :   return NaClUserToSys(nap, stackaddr);
     138                 : }
     139                 : 
     140                 : static INLINE uintptr_t NaClSysToUserStackAddr(struct NaClApp *nap,
     141               6 :                                                uintptr_t      stackaddr) {
     142               6 :   return NaClSysToUser(nap, stackaddr);
     143                 : }
     144                 : 
     145                 : #endif
     146                 : 
     147               9 : static INLINE uintptr_t NaClEndOfStaticText(struct NaClApp *nap) {
     148               9 :   return nap->static_text_end;
     149                 : }
     150                 : 
     151                 : static INLINE uintptr_t NaClSandboxCodeAddr(struct NaClApp *nap,
     152             559 :                                             uintptr_t addr) {
     153                 : #if NACL_DANGEROUS_DEBUG_ONLY_NO_SANDBOX_RETURNS
     154                 :   UNREFERENCED_PARAMETER(nap);
     155                 :   return addr;
     156                 : #else
     157                 : # if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
     158                 : #  if NACL_BUILD_SUBARCH == 32
     159             559 :   return addr & ~(((uintptr_t) nap->bundle_size) - 1);
     160                 : #  elif NACL_BUILD_SUBARCH == 64
     161                 :   return (((addr & ~(((uintptr_t) nap->bundle_size) - 1))
     162                 :            & ((((uintptr_t) 1) << 32) - 1))
     163                 :           + nap->mem_start);
     164                 : #  else
     165                 : #   error "What kind of x86 are we on anyway?!?"
     166                 : #  endif
     167                 : # elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
     168                 : #  if defined(NACL_TARGET_ARM_THUMB2_MODE)
     169                 :   return ((addr & ~(((uintptr_t) nap->bundle_size) - 1)) & ~0xF0000000) | 0xF;
     170                 : #  else
     171                 :   /*
     172                 :    * TODO(cbiffle): this hardcodes the size of code memory, and needs to become
     173                 :    * a parameter in NaClApp.  The simplest way to do this is with the change
     174                 :    * suggested in issue 244.  Then we could fold ARM and x86 impls together.
     175                 :    */
     176                 : 
     177                 :   return (addr & ~(((uintptr_t) nap->bundle_size) - 1)) & ~0xF0000000;
     178                 : #  endif  /* defined(NACL_TARGET_ARM_THUMB2_MODE) */
     179                 : # else
     180                 : #  error "What architecture are we on?!?"
     181                 : # endif
     182                 : #endif
     183                 : }
     184                 : 
     185                 : static INLINE int NaClIsValidJumpTarget(struct NaClApp *nap,
     186               0 :                                         uintptr_t addr) {
     187               0 :   if (0 != (addr & (((uintptr_t) nap->bundle_size) - 1))) {
     188               0 :     return 0;
     189                 :   }
     190               0 :   return addr < nap->dynamic_text_end;
     191                 : }

Generated by: LCOV version 1.7