summaryrefslogtreecommitdiff
path: root/src/pal/src/include/pal/palinternal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/src/include/pal/palinternal.h')
-rw-r--r--src/pal/src/include/pal/palinternal.h696
1 files changed, 696 insertions, 0 deletions
diff --git a/src/pal/src/include/pal/palinternal.h b/src/pal/src/include/pal/palinternal.h
new file mode 100644
index 0000000000..7348192e6d
--- /dev/null
+++ b/src/pal/src/include/pal/palinternal.h
@@ -0,0 +1,696 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*++
+
+
+
+Module Name:
+
+ palinternal.h
+
+Abstract:
+
+ Rotor Platform Adaptation Layer (PAL) header file used by source
+ file part of the PAL implementation. This is a wrapper over
+ unix/inc/pal.h. It allows avoiding name collisions when including
+ system header files, and it allows redirecting calls to 'standard' functions
+ to their PAL counterpart
+
+Details :
+
+A] Rationale (see B] for the quick recipe)
+There are 2 types of namespace collisions that must be handled.
+
+1) standard functions declared in pal.h, which do not need to be
+ implemented in the PAL because the system's implementation is sufficient.
+
+ (examples : memcpy, strlen, fclose)
+
+ The problem with these is that a prototype for them is provided both in
+ pal.h and in a system header (stdio.h, etc). If a PAL file needs to
+ include the files containing both prototypes, the compiler may complain
+ about the multiple declarations.
+
+ To avoid this, the inclusion of pal.h must be wrapped in a
+ #define/#undef pair, which will effectiveily "hide" the pal.h
+ declaration by renaming it to something else. this is done by palinternal.h
+ in this way :
+
+ #define some_function DUMMY_some_function
+ #include <pal.h>
+ #undef some_function
+
+ when a PAL source file includes palinternal.h, it will see a prototype for
+ DUMMY_some_function instead of some_function; so when it includes the
+ system header with the "real" prototype, no collision occurs.
+
+ (note : technically, no functions should ever be treated this way, all
+ system functions should be wrapped according to method 2, so that call
+ logging through ENTRY macros is done for all functions n the PAL. However
+ this reason alone is not currently considered enough to warrant a wrapper)
+
+2) standard functions which must be reimplemented by the PAL, because the
+ system's implementation does not offer suitable functionnality.
+
+ (examples : widestring functions, networking)
+
+ Here, the problem is more complex. The PAL must provide functions with the
+ same name as system functions. Due to the nature of Unix dynamic linking,
+ if this is done, the PAL's implementation will effectively mask the "real"
+ function, so that all calls are directed to it. This makes it impossible for
+ a function to be implemented as calling its counterpart in the system, plus
+ some extra work, because instead of calling the system's implementation, the
+ function would only call itself in an infinitely recursing nightmare. Even
+ worse, if by bad luck the system libraries attempt to call the function for
+ which the PAL provides an implementation, it is the PAL's version that will
+ be called.
+ It is therefore necessary to give the PAL's implementation of such functions
+ a different name. However, PAL consumers (applications built on top of the
+ PAL) must be able to call the function by its 'official' name, not the PAL's
+ internal name.
+ This can be done with some more macro magic, by #defining the official name
+ to the internal name *in pal.h*. :
+
+ #define some_function PAL_some_function
+
+ This way, while PAL consumer code can use the official name, it is the
+ internal name that wil be seen at compile time.
+ However, one extra step is needed. While PAL consumers must use the PAL's
+ implementation of these functions, the PAL itself must still have access to
+ the "real" functions. This is done by #undefining in palinternal.h the names
+ #defined in pal.h :
+
+ #include <pal.h>
+ #undef some_function.
+
+ At this point, code in the PAL implementation can access *both* its own
+ implementation of the function (with PAL_some_function) *and* the system's
+ implementation (with some_function)
+
+ [side note : for the Win32 PAL, this can be accomplished without touching
+ pal.h. In Windows, symbols in in dynamic libraries are resolved at
+ compile time. if an application that uses some_function is only linked to
+ pal.dll, some_function will be resolved to the version in that DLL,
+ even if other DLLs in the system provide other implementations. In addition,
+ the function in the DLL can actually have a different name (e.g.
+ PAL_some_function), to which the 'official' name is aliased when the DLL
+ is compiled. All this is not possible with Unix dynamic linking, where
+ symbols are resolved at run-time in a first-found-first-used order. A
+ module may end up using the symbols from a module it was never linked with,
+ simply because that module was located somewhere in the dependency chain. ]
+
+ It should be mentionned that even if a function name is not documented as
+ being implemented in the system, it can still cause problems if it exists.
+ This is especially a problem for functions in the "reserved" namespace
+ (names starting with an underscore : _exit, etc). (We shouldn't really be
+ implementing functions with such a name, but we don't really have a choice)
+ If such a case is detected, it should be wrapped according to method 2
+
+ Note that for all this to work, it is important for the PAL's implementation
+ files to #include palinternal.h *before* any system files, and to never
+ include pal.h directly.
+
+B] Procedure for name conflict resolution :
+
+When adding a function to pal.h, which is implemented by the system and
+which does not need a different implementation :
+
+- add a #define function_name DUMMY_function_name to palinternal.h, after all
+ the other DUMMY_ #defines (above the #include <pal.h> line)
+- add the function's prototype to pal.h (if that isn't already done)
+- add a #undef function_name to palinternal.h near all the other #undefs
+ (after the #include <pal.h> line)
+
+When overriding a system function with the PAL's own implementation :
+
+- add a #define function_name PAL_function_name to pal.h, somewhere
+ before the function's prototype, inside a #ifndef _MSCVER/#endif pair
+ (to avoid affecting the Win32 build)
+- add a #undef function_name to palinternal.h near all the other #undefs
+ (after the #include <pal.h> line)
+- implement the function in the pal, naming it PAL_function_name
+- within the PAL, call PAL_function_name() to call the PAL's implementation,
+function_name() to call the system's implementation
+
+
+
+--*/
+
+#ifndef _PAL_INTERNAL_H_
+#define _PAL_INTERNAL_H_
+
+#define PAL_IMPLEMENTATION
+
+/* Include our configuration information so it's always present when
+ compiling PAL implementation files. */
+#include "config.h"
+
+#ifdef DEBUG
+#define _ENABLE_DEBUG_MESSAGES_ 1
+#else
+#define _ENABLE_DEBUG_MESSAGES_ 0
+#endif
+
+#ifdef PAL_PERF
+#include "pal_perf.h"
+#endif
+
+/* C runtime functions needed to be renamed to avoid duplicate definition
+ of those functions when including standard C header files */
+#define div DUMMY_div
+#define div_t DUMMY_div_t
+#if !defined(_DEBUG)
+#define memcpy DUMMY_memcpy
+#endif //!defined(_DEBUG)
+#define memcmp DUMMY_memcmp
+#define memset DUMMY_memset
+#define memmove DUMMY_memmove
+#define memchr DUMMY_memchr
+#define strlen DUMMY_strlen
+#define strnlen DUMMY_strnlen
+#define stricmp DUMMY_stricmp
+#define strstr DUMMY_strstr
+#define strcmp DUMMY_strcmp
+#define strcat DUMMY_strcat
+#define strncat DUMMY_strncat
+#define strcpy DUMMY_strcpy
+#define strcspn DUMMY_strcspn
+#define strncmp DUMMY_strncmp
+#define strncpy DUMMY_strncpy
+#define strchr DUMMY_strchr
+#define strrchr DUMMY_strrchr
+#define strpbrk DUMMY_strpbrk
+#define strtod DUMMY_strtod
+#define strspn DUMMY_strspn
+#if HAVE__SNPRINTF
+#define _snprintf DUMMY__snprintf
+#endif /* HAVE__SNPRINTF */
+#if HAVE__SNWPRINTF
+#define _snwprintf DUMMY__snwprintf
+#endif /* HAVE__SNWPRINTF */
+#define tolower DUMMY_tolower
+#define toupper DUMMY_toupper
+#define islower DUMMY_islower
+#define isupper DUMMY_isupper
+#define isprint DUMMY_isprint
+#define isdigit DUMMY_isdigit
+#define srand DUMMY_srand
+#define atoi DUMMY_atoi
+#define atof DUMMY_atof
+#define tm PAL_tm
+#define size_t DUMMY_size_t
+#define time_t PAL_time_t
+#define va_list DUMMY_va_list
+#define abs DUMMY_abs
+#define llabs DUMMY_llabs
+#define ceil DUMMY_ceil
+#define cos DUMMY_cos
+#define cosh DUMMY_cosh
+#define fabs DUMMY_fabs
+#define floor DUMMY_floor
+#define fmod DUMMY_fmod
+#define modf DUMMY_modf
+#define sin DUMMY_sin
+#define sinh DUMMY_sinh
+#define sqrt DUMMY_sqrt
+#define tan DUMMY_tan
+#define tanh DUMMY_tanh
+#define fabsf DUMMY_fabsf
+#define fmodf DUMMY_fmodf
+#define modff DUMMY_modff
+
+/* RAND_MAX needed to be renamed to avoid duplicate definition when including
+ stdlib.h header files. PAL_RAND_MAX should have the same value as RAND_MAX
+ defined in pal.h */
+#define PAL_RAND_MAX 0x7fff
+
+/* The standard headers define isspace and isxdigit as macros and functions,
+ To avoid redefinition problems, undefine those macros. */
+#ifdef isspace
+#undef isspace
+#endif
+#ifdef isxdigit
+#undef isxdigit
+#endif
+#ifdef isalpha
+#undef isalpha
+#endif
+#ifdef isalnum
+#undef isalnum
+#endif
+#define isspace DUMMY_isspace
+#define isxdigit DUMMY_isxdigit
+#define isalpha DUMMY_isalpha
+#define isalnum DUMMY_isalnum
+
+#ifdef stdin
+#undef stdin
+#endif
+#ifdef stdout
+#undef stdout
+#endif
+#ifdef stderr
+#undef stderr
+#endif
+
+#ifdef SCHAR_MIN
+#undef SCHAR_MIN
+#endif
+#ifdef SCHAR_MAX
+#undef SCHAR_MAX
+#endif
+#ifdef SHRT_MIN
+#undef SHRT_MIN
+#endif
+#ifdef SHRT_MAX
+#undef SHRT_MAX
+#endif
+#ifdef UCHAR_MAX
+#undef UCHAR_MAX
+#endif
+#ifdef USHRT_MAX
+#undef USHRT_MAX
+#endif
+#ifdef ULONG_MAX
+#undef ULONG_MAX
+#endif
+#ifdef LONG_MIN
+#undef LONG_MIN
+#endif
+#ifdef LONG_MAX
+#undef LONG_MAX
+#endif
+#ifdef RAND_MAX
+#undef RAND_MAX
+#endif
+#ifdef DBL_MAX
+#undef DBL_MAX
+#endif
+#ifdef FLT_MAX
+#undef FLT_MAX
+#endif
+#ifdef __record_type_class
+#undef __record_type_class
+#endif
+#ifdef __real_type_class
+#undef __real_type_class
+#endif
+
+// The standard headers define va_start and va_end as macros,
+// To avoid redefinition problems, undefine those macros.
+#ifdef va_start
+#undef va_start
+#endif
+#ifdef va_end
+#undef va_end
+#endif
+#ifdef va_copy
+#undef va_copy
+#endif
+
+
+#ifdef _VAC_
+#define wchar_16 wchar_t
+#else
+#define wchar_t wchar_16
+#endif // _VAC_
+
+#define ptrdiff_t PAL_ptrdiff_t
+#define intptr_t PAL_intptr_t
+#define uintptr_t PAL_uintptr_t
+#define timeval PAL_timeval
+#define FILE PAL_FILE
+
+#include "pal.h"
+#include "palprivate.h"
+
+#include "mbusafecrt.h"
+
+#ifdef _VAC_
+#undef CHAR_BIT
+#undef va_arg
+#endif
+
+#if !defined(_MSC_VER) && defined(FEATURE_PAL) && defined(_WIN64)
+#undef _BitScanForward64
+#endif
+
+/* pal.h defines alloca(3) as a compiler builtin.
+ Redefining it to native libc will result in undefined breakage because
+ a compiler is allowed to make assumptions about the stack and frame
+ pointers. */
+
+/* Undef all functions and types previously defined so those functions and
+ types could be mapped to the C runtime and socket implementation of the
+ native OS */
+#undef exit
+#undef atexit
+#undef div
+#undef div_t
+#if !defined(_DEBUG)
+#undef memcpy
+#endif //!defined(_DEBUG)
+#undef memcmp
+#undef memset
+#undef memmove
+#undef memchr
+#undef strlen
+#undef strnlen
+#undef stricmp
+#undef strstr
+#undef strcmp
+#undef strcat
+#undef strcspn
+#undef strncat
+#undef strcpy
+#undef strncmp
+#undef strncpy
+#undef strchr
+#undef strrchr
+#undef strpbrk
+#undef strtoul
+#undef strtod
+#undef strspn
+#undef strtok
+#undef strdup
+#undef tolower
+#undef toupper
+#undef islower
+#undef isupper
+#undef isprint
+#undef isdigit
+#undef isspace
+#undef iswdigit
+#undef iswxdigit
+#undef iswalpha
+#undef iswprint
+#undef isxdigit
+#undef isalpha
+#undef isalnum
+#undef atoi
+#undef atol
+#undef atof
+#undef malloc
+#undef realloc
+#undef free
+#undef qsort
+#undef bsearch
+#undef time
+#undef tm
+#undef localtime
+#undef mktime
+#undef FILE
+#undef fclose
+#undef setbuf
+#undef fopen
+#undef fread
+#undef feof
+#undef ferror
+#undef ftell
+#undef fflush
+#undef fwrite
+#undef fgets
+#undef fgetws
+#undef fputc
+#undef putchar
+#undef fputs
+#undef fseek
+#undef fgetpos
+#undef fsetpos
+#undef getcwd
+#undef getc
+#undef fgetc
+#undef ungetc
+#undef _flushall
+#undef setvbuf
+#undef mkstemp
+#undef rename
+#undef unlink
+#undef size_t
+#undef time_t
+#undef va_list
+#undef va_start
+#undef va_end
+#undef va_copy
+#undef stdin
+#undef stdout
+#undef stderr
+#undef abs
+#undef labs
+#undef llabs
+#undef acos
+#undef asin
+#undef atan
+#undef atan2
+#undef ceil
+#undef cos
+#undef cosh
+#undef exp
+#undef fabs
+#undef floor
+#undef fmod
+#undef log
+#undef log10
+#undef modf
+#undef pow
+#undef sin
+#undef sinh
+#undef sqrt
+#undef tan
+#undef tanh
+#undef fabsf
+#undef fmodf
+#undef modff
+#undef rand
+#undef srand
+#undef errno
+#undef getenv
+#undef wcsspn
+#undef open
+#undef glob
+
+#undef wchar_t
+#undef ptrdiff_t
+#undef intptr_t
+#undef uintptr_t
+#undef timeval
+
+
+#undef printf
+#undef fprintf
+#undef fwprintf
+#undef vfprintf
+#undef vfwprintf
+#undef vprintf
+#undef wprintf
+#undef sprintf
+#undef swprintf
+#undef _snprintf
+#if HAVE__SNWPRINTF
+#undef _snwprintf
+#endif /* HAVE__SNWPRINTF */
+#undef sscanf
+#undef wcstod
+#undef wcstol
+#undef wcstoul
+#undef _wcstoui64
+#undef wcscat
+#undef wcscpy
+#undef wcslen
+#undef wcsncmp
+#undef wcschr
+#undef wcsrchr
+#undef wsprintf
+#undef swscanf
+#undef wcspbrk
+#undef wcsstr
+#undef wcscmp
+#undef wcsncat
+#undef wcsncpy
+#undef wcstok
+#undef wcscspn
+#undef iswupper
+#undef iswspace
+#undef towlower
+#undef towupper
+#undef vsprintf
+#undef vswprintf
+#undef _vsnprintf
+#undef _vsnwprintf
+#undef vsnprintf
+#undef wvsnprintf
+
+#ifdef _AMD64_
+#undef _mm_getcsr
+#undef _mm_setcsr
+#endif // _AMD64_
+
+#undef ctime
+
+#undef SCHAR_MIN
+#undef SCHAR_MAX
+#undef UCHAR_MAX
+#undef SHRT_MIN
+#undef SHRT_MAX
+#undef USHRT_MAX
+#undef LONG_MIN
+#undef LONG_MAX
+#undef ULONG_MAX
+#undef RAND_MAX
+#undef DBL_MAX
+#undef FLT_MAX
+#undef __record_type_class
+#undef __real_type_class
+
+#if HAVE_CHAR_BIT
+#undef CHAR_BIT
+#endif
+
+// We need a sigsetjmp prototype in pal.h for the SEH macros, but we
+// can't use the "real" prototype (because we don't want to define sigjmp_buf).
+// So we must rename the "real" sigsetjmp to avoid redefinition errors.
+#define sigsetjmp REAL_sigsetjmp
+#define siglongjmp REAL_siglongjmp
+#include <setjmp.h>
+#undef sigsetjmp
+#undef siglongjmp
+
+#undef _SIZE_T_DEFINED
+#undef _WCHAR_T_DEFINED
+
+#define _DONT_USE_CTYPE_INLINE_
+#if HAVE_RUNETYPE_H
+#include <runetype.h>
+#endif
+#include <ctype.h>
+
+// Don't use C++ wrappers for stdlib.h
+// https://gcc.gnu.org/ml/libstdc++/2016-01/msg00025.html
+#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS 1
+
+#define _WITH_GETLINE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <glob.h>
+
+#ifdef __APPLE__
+
+#undef GetCurrentThread
+#include <CoreServices/CoreServices.h>
+
+#include <malloc/malloc.h>
+
+#endif // __APPLE__
+
+/* we don't really need this header here, but by including it we make sure
+ we'll catch any definition conflicts */
+#include <sys/socket.h>
+
+#if !HAVE_INFTIM
+#define INFTIM -1
+#endif // !HAVE_INFTIM
+
+#if (__GNUC__ >= 4)
+#define OffsetOf(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+#else
+#define OffsetOf(s, f) (INT)(SIZE_T)&(((s*)0)->f)
+#endif /* __GNUC__ version check*/
+
+#undef assert
+#define assert (Use__ASSERTE_instead_of_assert) assert
+
+#define PROCESS_PIPE_NAME_PREFIX ".dotnet-pal-processpipe"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+typedef enum _TimeConversionConstants
+{
+ tccSecondsToMillieSeconds = 1000, // 10^3
+ tccSecondsToMicroSeconds = 1000000, // 10^6
+ tccSecondsToNanoSeconds = 1000000000, // 10^9
+ tccMillieSecondsToMicroSeconds = 1000, // 10^3
+ tccMillieSecondsToNanoSeconds = 1000000, // 10^6
+ tccMicroSecondsToNanoSeconds = 1000, // 10^3
+ tccSecondsTo100NanoSeconds = 10000000, // 10^7
+ tccMicroSecondsTo100NanoSeconds = 10 // 10^1
+} TimeConversionConstants;
+
+#ifdef __cplusplus
+}
+
+/* This is duplicated in utilcode.h for CLR, with cooler type-traits */
+template <typename T>
+inline
+T* InterlockedExchangePointerT(
+ T* volatile *Target,
+ T* Value)
+{
+ return (T*)(InterlockedExchangePointer(
+ (PVOID volatile*)Target,
+ (PVOID)Value));
+}
+
+template <typename T>
+inline
+T* InterlockedCompareExchangePointerT(
+ T* volatile *destination,
+ T* exchange,
+ T* comparand)
+{
+ return (T*)(InterlockedCompareExchangePointer(
+ (PVOID volatile*)destination,
+ (PVOID)exchange,
+ (PVOID)comparand));
+}
+
+template <typename T>
+inline T* InterlockedExchangePointerT(
+ T* volatile * target,
+ int value) // When NULL is provided as argument.
+{
+ //STATIC_ASSERT(value == 0);
+ return InterlockedExchangePointerT(target, reinterpret_cast<T*>(value));
+}
+
+template <typename T>
+inline T* InterlockedCompareExchangePointerT(
+ T* volatile * destination,
+ int exchange, // When NULL is provided as argument.
+ T* comparand)
+{
+ //STATIC_ASSERT(exchange == 0);
+ return InterlockedCompareExchangePointerT(destination, reinterpret_cast<T*>(exchange), comparand);
+}
+
+template <typename T>
+inline T* InterlockedCompareExchangePointerT(
+ T* volatile * destination,
+ T* exchange,
+ int comparand) // When NULL is provided as argument.
+{
+ //STATIC_ASSERT(comparand == 0);
+ return InterlockedCompareExchangePointerT(destination, exchange, reinterpret_cast<T*>(comparand));
+}
+
+#undef InterlockedExchangePointer
+#define InterlockedExchangePointer InterlockedExchangePointerT
+#undef InterlockedCompareExchangePointer
+#define InterlockedCompareExchangePointer InterlockedCompareExchangePointerT
+
+#include "volatile.h"
+
+const char StackOverflowMessage[] = "Process is terminated due to StackOverflowException.\n";
+
+#endif // __cplusplus
+
+#endif /* _PAL_INTERNAL_H_ */