tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

_solaris.h (15047B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef nspr_solaris_defs_h___
      7 #define nspr_solaris_defs_h___
      8 
      9 /*
     10 * Internal configuration macros
     11 */
     12 
     13 #define PR_LINKER_ARCH  "solaris"
     14 #define _PR_SI_SYSNAME  "SOLARIS"
     15 #ifdef sparc
     16 #define _PR_SI_ARCHITECTURE "sparc"
     17 #elif defined(__x86_64)
     18 #define _PR_SI_ARCHITECTURE "x86-64"
     19 #elif defined(i386)
     20 #define _PR_SI_ARCHITECTURE "x86"
     21 #else
     22 #error unknown processor
     23 #endif
     24 #define PR_DLL_SUFFIX       ".so"
     25 
     26 #define _PR_VMBASE      0x30000000
     27 #define _PR_STACK_VMBASE    0x50000000
     28 #define _MD_DEFAULT_STACK_SIZE  (2*65536L)
     29 #define _MD_MMAP_FLAGS          MAP_SHARED
     30 
     31 #undef  HAVE_STACK_GROWING_UP
     32 
     33 #ifndef HAVE_WEAK_IO_SYMBOLS
     34 #define HAVE_WEAK_IO_SYMBOLS
     35 #endif
     36 
     37 #undef  HAVE_WEAK_MALLOC_SYMBOLS
     38 #define HAVE_DLL
     39 #define USE_DLFCN
     40 #define NEED_STRFTIME_LOCK
     41 
     42 /*
     43 * Intel x86 has atomic instructions.
     44 *
     45 * Sparc v8 does not have instructions to efficiently implement
     46 * atomic increment/decrement operations.  We use the default
     47 * atomic routine implementation in pratom.c.
     48 *
     49 * 64-bit Solaris requires sparc v9, which has atomic instructions.
     50 */
     51 #if defined(i386) || defined(IS_64)
     52 #define _PR_HAVE_ATOMIC_OPS
     53 #endif
     54 
     55 #define _PR_POLL_AVAILABLE
     56 #define _PR_USE_POLL
     57 #define _PR_STAT_HAS_ST_ATIM
     58 #ifdef SOLARIS2_5
     59 #define _PR_HAVE_SYSV_SEMAPHORES
     60 #define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
     61 #else
     62 #define _PR_HAVE_POSIX_SEMAPHORES
     63 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
     64 #endif
     65 #define _PR_HAVE_GETIPNODEBYNAME
     66 #define _PR_HAVE_GETIPNODEBYADDR
     67 #define _PR_HAVE_GETADDRINFO
     68 #define _PR_INET6_PROBE
     69 #define _PR_ACCEPT_INHERIT_NONBLOCK
     70 #ifdef _PR_INET6
     71 #define _PR_HAVE_INET_NTOP
     72 #else
     73 #define AF_INET6 26
     74 struct addrinfo {
     75    int ai_flags;
     76    int ai_family;
     77    int ai_socktype;
     78    int ai_protocol;
     79    size_t ai_addrlen;
     80    char *ai_canonname;
     81    struct sockaddr *ai_addr;
     82    struct addrinfo *ai_next;
     83 };
     84 #define AI_CANONNAME 0x0010
     85 #define AI_V4MAPPED 0x0001
     86 #define AI_ALL      0x0002
     87 #define AI_ADDRCONFIG   0x0004
     88 #define _PR_HAVE_MD_SOCKADDR_IN6
     89 /* isomorphic to struct in6_addr on Solaris 8 */
     90 struct _md_in6_addr {
     91    union {
     92        PRUint8  _S6_u8[16];
     93        PRUint32 _S6_u32[4];
     94        PRUint32 __S6_align;
     95    } _S6_un;
     96 };
     97 /* isomorphic to struct sockaddr_in6 on Solaris 8 */
     98 struct _md_sockaddr_in6 {
     99    PRUint16 sin6_family;
    100    PRUint16 sin6_port;
    101    PRUint32 sin6_flowinfo;
    102    struct _md_in6_addr sin6_addr;
    103    PRUint32 sin6_scope_id;
    104    PRUint32 __sin6_src_id;
    105 };
    106 #endif
    107 #if defined(_PR_PTHREADS)
    108 #define _PR_HAVE_GETHOST_R
    109 #define _PR_HAVE_GETHOST_R_POINTER
    110 #endif
    111 
    112 #include "prinrval.h"
    113 #define _MD_INTERVAL_INIT()
    114 NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);
    115 #define _MD_GET_INTERVAL                  _MD_Solaris_GetInterval
    116 NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void);
    117 #define _MD_INTERVAL_PER_SEC              _MD_Solaris_TicksPerSecond
    118 
    119 #if defined(_PR_HAVE_ATOMIC_OPS)
    120 /*
    121 ** Atomic Operations
    122 */
    123 #define _MD_INIT_ATOMIC()
    124 
    125 NSPR_API(PRInt32) _MD_AtomicIncrement(PRInt32 *val);
    126 #define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement
    127 
    128 NSPR_API(PRInt32) _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val);
    129 #define _MD_ATOMIC_ADD _MD_AtomicAdd
    130 
    131 NSPR_API(PRInt32) _MD_AtomicDecrement(PRInt32 *val);
    132 #define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement
    133 
    134 NSPR_API(PRInt32) _MD_AtomicSet(PRInt32 *val, PRInt32 newval);
    135 #define _MD_ATOMIC_SET _MD_AtomicSet
    136 #endif /* _PR_HAVE_ATOMIC_OPS */
    137 
    138 #if defined(_PR_PTHREADS)
    139 
    140 NSPR_API(void)      _MD_EarlyInit(void);
    141 
    142 #define _MD_EARLY_INIT      _MD_EarlyInit
    143 #define _MD_FINAL_INIT      _PR_UnixInit
    144 
    145 #else /* _PR_PTHREADS */
    146 
    147 /*
    148 * _PR_LOCAL_THREADS_ONLY implementation on Solaris
    149 */
    150 
    151 #include "prthread.h"
    152 
    153 #include <errno.h>
    154 #include <ucontext.h>
    155 #include <sys/stack.h>
    156 #include <synch.h>
    157 
    158 /*
    159 ** Initialization Related definitions
    160 */
    161 
    162 NSPR_API(void)              _MD_EarlyInit(void);
    163 NSPR_API(void)              _MD_SolarisInit();
    164 #define _MD_EARLY_INIT      _MD_EarlyInit
    165 #define _MD_FINAL_INIT      _MD_SolarisInit
    166 #define _MD_INIT_THREAD     _MD_InitializeThread
    167 
    168 #ifdef USE_SETJMP
    169 
    170 #include <setjmp.h>
    171 
    172 #define _PR_CONTEXT_TYPE    jmp_buf
    173 
    174 #ifdef sparc
    175 #define _MD_GET_SP(_t)      (_t)->md.context[2]
    176 #else
    177 #define _MD_GET_SP(_t)      (_t)->md.context[4]
    178 #endif
    179 
    180 #define PR_NUM_GCREGS       _JBLEN
    181 #define CONTEXT(_thread)    (_thread)->md.context
    182 
    183 #else  /* ! USE_SETJMP */
    184 
    185 #ifdef sparc
    186 #define _PR_CONTEXT_TYPE    ucontext_t
    187 #define _MD_GET_SP(_t)      (_t)->md.context.uc_mcontext.gregs[REG_SP]
    188 /*
    189 ** Sparc's use register windows. the _MD_GetRegisters for the sparc's
    190 ** doesn't actually store anything into the argument buffer; instead the
    191 ** register windows are homed to the stack. I assume that the stack
    192 ** always has room for the registers to spill to...
    193 */
    194 #define PR_NUM_GCREGS       0
    195 #else
    196 #define _PR_CONTEXT_TYPE    unsigned int edi; sigset_t oldMask, blockMask; ucontext_t
    197 #define _MD_GET_SP(_t)      (_t)->md.context.uc_mcontext.gregs[USP]
    198 #define PR_NUM_GCREGS       _JBLEN
    199 #endif
    200 
    201 #define CONTEXT(_thread)    (&(_thread)->md.context)
    202 
    203 #endif /* ! USE_SETJMP */
    204 
    205 #include <time.h>
    206 /*
    207 * Because clock_gettime() on Solaris/x86 always generates a
    208 * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
    209 * which is implemented using gettimeofday().
    210 */
    211 #ifdef i386
    212 #define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
    213 #else
    214 #define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
    215 #endif  /* i386 */
    216 
    217 #define _MD_SAVE_ERRNO(_thread)         (_thread)->md.errcode = errno;
    218 #define _MD_RESTORE_ERRNO(_thread)      errno = (_thread)->md.errcode;
    219 
    220 #ifdef sparc
    221 
    222 #ifdef USE_SETJMP
    223 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status)         \
    224    PR_BEGIN_MACRO                    \
    225    int *context = (_thread)->md.context;         \
    226    *status = PR_TRUE;              \
    227    (void) setjmp(context);               \
    228    (_thread)->md.context[1] = (int) ((_sp) - 64); \
    229    (_thread)->md.context[2] = (int) _main;       \
    230    (_thread)->md.context[3] = (int) _main + 4; \
    231    _thread->no_sched = 0; \
    232    PR_END_MACRO
    233 
    234 #define _MD_SWITCH_CONTEXT(_thread)    \
    235    if (!setjmp(CONTEXT(_thread))) { \
    236    _MD_SAVE_ERRNO(_thread)    \
    237    _MD_SET_LAST_THREAD(_thread);    \
    238    _MD_SET_CURRENT_THREAD(_thread);     \
    239    _PR_Schedule();          \
    240    }
    241 
    242 #define _MD_RESTORE_CONTEXT(_newThread)     \
    243 {                    \
    244    _MD_RESTORE_ERRNO(_newThread)       \
    245    _MD_SET_CURRENT_THREAD(_newThread); \
    246    longjmp(CONTEXT(_newThread), 1);    \
    247 }
    248 
    249 #else
    250 /*
    251 ** Initialize the thread context preparing it to execute _main.
    252 */
    253 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status)                   \
    254    PR_BEGIN_MACRO                                                      \
    255    ucontext_t *uc = CONTEXT(_thread);                                  \
    256    *status = PR_TRUE;                                                  \
    257    getcontext(uc);                                                     \
    258    uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);  \
    259    uc->uc_stack.ss_size = _thread->stack->stackSize;                   \
    260    uc->uc_stack.ss_flags = 0;              /* ? */                     \
    261    uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp;  \
    262    uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main;               \
    263    uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4;   \
    264    uc->uc_flags = UC_ALL;                                              \
    265    _thread->no_sched = 0;                                              \
    266    PR_END_MACRO
    267 
    268 /*
    269 ** Switch away from the current thread context by saving its state and
    270 ** calling the thread scheduler. Reload cpu when we come back from the
    271 ** context switch because it might have changed.
    272 */
    273 #define _MD_SWITCH_CONTEXT(_thread)                 \
    274    PR_BEGIN_MACRO                                  \
    275        if (!getcontext(CONTEXT(_thread))) {        \
    276            _MD_SAVE_ERRNO(_thread);                \
    277            _MD_SET_LAST_THREAD(_thread);           \
    278            _PR_Schedule();                         \
    279        }                                           \
    280    PR_END_MACRO
    281 
    282 /*
    283 ** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
    284 ** initialized by _MD_INIT_CONTEXT.
    285 */
    286 #define _MD_RESTORE_CONTEXT(_newThread)                     \
    287    PR_BEGIN_MACRO                                          \
    288        ucontext_t *uc = CONTEXT(_newThread);               \
    289        uc->uc_mcontext.gregs[11] = 1;                      \
    290        _MD_RESTORE_ERRNO(_newThread);                      \
    291        _MD_SET_CURRENT_THREAD(_newThread);                 \
    292        setcontext(uc);                                     \
    293    PR_END_MACRO
    294 #endif
    295 
    296 #else  /* x86 solaris */
    297 
    298 #ifdef USE_SETJMP
    299 
    300 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
    301    PR_BEGIN_MACRO \
    302    *status = PR_TRUE; \
    303    if (setjmp(CONTEXT(_thread))) _main(); \
    304    _MD_GET_SP(_thread) = (int) ((_sp) - 64); \
    305    PR_END_MACRO
    306 
    307 #define _MD_SWITCH_CONTEXT(_thread) \
    308    if (!setjmp(CONTEXT(_thread))) { \
    309        _MD_SAVE_ERRNO(_thread) \
    310        _PR_Schedule(); \
    311    }
    312 
    313 #define _MD_RESTORE_CONTEXT(_newThread) \
    314 { \
    315    _MD_RESTORE_ERRNO(_newThread) \
    316    _MD_SET_CURRENT_THREAD(_newThread); \
    317    longjmp(CONTEXT(_newThread), 1); \
    318 }
    319 
    320 #else /* USE_SETJMP */
    321 
    322 #define WINDOWSIZE      0
    323 
    324 int getedi(void);
    325 void setedi(int);
    326 
    327 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status)         \
    328    PR_BEGIN_MACRO                  \
    329    ucontext_t *uc = CONTEXT(_thread);      \
    330        *status = PR_TRUE;              \
    331    getcontext(uc);                 \
    332    /* Force sp to be double aligned! */        \
    333        uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8); \
    334    uc->uc_mcontext.gregs[PC] = (int) _main;    \
    335    (_thread)->no_sched = 0; \
    336    PR_END_MACRO
    337 
    338 /* getcontext() may return 1, contrary to what the man page says */
    339 #define _MD_SWITCH_CONTEXT(_thread)         \
    340    PR_BEGIN_MACRO                  \
    341    ucontext_t *uc = CONTEXT(_thread);      \
    342    PR_ASSERT(_thread->no_sched);           \
    343    sigfillset(&((_thread)->md.blockMask));     \
    344    sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask),  \
    345        &((_thread)->md.oldMask));      \
    346    (_thread)->md.edi = getedi();           \
    347    if (! getcontext(uc)) {             \
    348        sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
    349        uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi; \
    350        _MD_SAVE_ERRNO(_thread)         \
    351            _MD_SET_LAST_THREAD(_thread);           \
    352        _PR_Schedule();             \
    353    } else {                    \
    354        sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
    355        setedi((_thread)->md.edi);      \
    356        PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
    357        _MD_LAST_THREAD()->no_sched = 0;    \
    358    }                       \
    359    PR_END_MACRO
    360 
    361 /*
    362 ** Restore a thread context, saved by _PR_SWITCH_CONTEXT
    363 */
    364 #define _MD_RESTORE_CONTEXT(_newthread)         \
    365    PR_BEGIN_MACRO                  \
    366    ucontext_t *uc = CONTEXT(_newthread);       \
    367    uc->uc_mcontext.gregs[EAX] = 1;         \
    368    _MD_RESTORE_ERRNO(_newthread)           \
    369    _MD_SET_CURRENT_THREAD(_newthread);     \
    370    (_newthread)->no_sched = 1;         \
    371    setcontext(uc);                 \
    372    PR_END_MACRO
    373 #endif /* USE_SETJMP */
    374 
    375 #endif /* sparc */
    376 
    377 struct _MDLock {
    378    PRInt8 notused;
    379 };
    380 
    381 struct _MDCVar {
    382    PRInt8 notused;
    383 };
    384 
    385 struct _MDSemaphore {
    386    PRInt8 notused;
    387 };
    388 
    389 struct _MDThread {
    390    _PR_CONTEXT_TYPE context;
    391    int errcode;
    392    int id;
    393 };
    394 
    395 struct _MDThreadStack {
    396    PRInt8 notused;
    397 };
    398 
    399 struct _MDSegment {
    400    PRInt8 notused;
    401 };
    402 
    403 /*
    404 * md-specific cpu structure field
    405 */
    406 #define _PR_MD_MAX_OSFD FD_SETSIZE
    407 
    408 struct _MDCPU_Unix {
    409    PRCList ioQ;
    410    PRUint32 ioq_timeout;
    411    PRInt32 ioq_max_osfd;
    412    PRInt32 ioq_osfd_cnt;
    413 #ifndef _PR_USE_POLL
    414    fd_set fd_read_set, fd_write_set, fd_exception_set;
    415    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
    416            fd_exception_cnt[_PR_MD_MAX_OSFD];
    417 #else
    418    struct pollfd *ioq_pollfds;
    419    int ioq_pollfds_size;
    420 #endif  /* _PR_USE_POLL */
    421 };
    422 
    423 #define _PR_IOQ(_cpu)           ((_cpu)->md.md_unix.ioQ)
    424 #define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
    425 #define _PR_FD_READ_SET(_cpu)       ((_cpu)->md.md_unix.fd_read_set)
    426 #define _PR_FD_READ_CNT(_cpu)       ((_cpu)->md.md_unix.fd_read_cnt)
    427 #define _PR_FD_WRITE_SET(_cpu)      ((_cpu)->md.md_unix.fd_write_set)
    428 #define _PR_FD_WRITE_CNT(_cpu)      ((_cpu)->md.md_unix.fd_write_cnt)
    429 #define _PR_FD_EXCEPTION_SET(_cpu)  ((_cpu)->md.md_unix.fd_exception_set)
    430 #define _PR_FD_EXCEPTION_CNT(_cpu)  ((_cpu)->md.md_unix.fd_exception_cnt)
    431 #define _PR_IOQ_TIMEOUT(_cpu)       ((_cpu)->md.md_unix.ioq_timeout)
    432 #define _PR_IOQ_MAX_OSFD(_cpu)      ((_cpu)->md.md_unix.ioq_max_osfd)
    433 #define _PR_IOQ_OSFD_CNT(_cpu)      ((_cpu)->md.md_unix.ioq_osfd_cnt)
    434 #define _PR_IOQ_POLLFDS(_cpu)       ((_cpu)->md.md_unix.ioq_pollfds)
    435 #define _PR_IOQ_POLLFDS_SIZE(_cpu)  ((_cpu)->md.md_unix.ioq_pollfds_size)
    436 
    437 #define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)  32
    438 
    439 struct _MDCPU {
    440    struct _MDCPU_Unix md_unix;
    441 };
    442 
    443 #define _MD_INIT_LOCKS()
    444 #define _MD_NEW_LOCK(lock)              PR_SUCCESS
    445 #define _MD_FREE_LOCK(lock)
    446 #define _MD_LOCK(lock)
    447 #define _MD_UNLOCK(lock)
    448 #define _MD_INIT_IO()
    449 #define _MD_IOQ_LOCK()
    450 #define _MD_IOQ_UNLOCK()
    451 
    452 #define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
    453 #define _MD_INIT_THREAD                 _MD_InitializeThread
    454 #define _MD_EXIT_THREAD(thread)
    455 #define _MD_SUSPEND_THREAD(thread)
    456 #define _MD_RESUME_THREAD(thread)
    457 #define _MD_CLEAN_THREAD(_thread)
    458 
    459 extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout);
    460 extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *);
    461 extern void     _MD_YIELD(void);
    462 extern PRStatus _MD_InitializeThread(PRThread *thread);
    463 extern void     _MD_SET_PRIORITY(struct _MDThread *thread,
    464                                 PRThreadPriority newPri);
    465 extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *),
    466                                  PRThreadPriority priority, PRThreadScope scope, PRThreadState state,
    467                                  PRUint32 stackSize);
    468 
    469 /* The following defines the unwrapped versions of select() and poll(). */
    470 extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
    471                   fd_set *exceptfds, struct timeval *timeout);
    472 #define _MD_SELECT  _select
    473 
    474 #include <stropts.h>
    475 #include <poll.h>
    476 #define _MD_POLL _poll
    477 extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
    478 
    479 PR_BEGIN_EXTERN_C
    480 
    481 /*
    482 ** Missing function prototypes
    483 */
    484 extern int gethostname (char *name, int namelen);
    485 
    486 PR_END_EXTERN_C
    487 
    488 #endif /* _PR_PTHREADS */
    489 
    490 extern void _MD_solaris_map_sendfile_error(int err);
    491 
    492 #endif /* nspr_solaris_defs_h___ */