diff options
Diffstat (limited to 'src/pal/src')
41 files changed, 416 insertions, 2164 deletions
diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt index 28ee83a77c..16c9d8bd6f 100644 --- a/src/pal/src/CMakeLists.txt +++ b/src/pal/src/CMakeLists.txt @@ -23,20 +23,37 @@ include_directories(include) # Compile options -if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL AMD64) - set(PAL_CMAKE_PLATFORM_ARCH_AMD64 1) - add_definitions(-D_AMD64_) -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l) - set(PAL_CMAKE_PLATFORM_ARCH_ARM 1) - add_definitions(-D_ARM_) -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) - set(PAL_CMAKE_PLATFORM_ARCH_ARM64 1) - add_definitions(-D_ARM64_) -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686) - set(CLR_CMAKE_PLATFORM_ARCH_I386 1) - add_definitions(-D_X86_) +if(CLR_CROSS_COMPONENTS_BUILD) + if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL amd64) + if(CLR_CMAKE_TARGET_ARCH STREQUAL "arm") + set(PAL_CMAKE_PLATFORM_ARCH_I386 1) + add_definitions(-D_X86_) + else() + set(PAL_CMAKE_PLATFORM_ARCH_AMD64 1) + add_definitions(-D_AMD64_) + endif() + elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL i686) + set(PAL_CMAKE_PLATFORM_ARCH_I386 1) + add_definitions(-D_X86_) + else() + message(FATAL_ERROR "Only AMD64, I386 host for cross-architecture component is supported") + endif() else() - message(FATAL_ERROR "Only ARM and AMD64 is supported") + if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL AMD64) + set(PAL_CMAKE_PLATFORM_ARCH_AMD64 1) + add_definitions(-D_AMD64_) + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l) + set(PAL_CMAKE_PLATFORM_ARCH_ARM 1) + add_definitions(-D_ARM_) + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) + set(PAL_CMAKE_PLATFORM_ARCH_ARM64 1) + add_definitions(-D_ARM64_) + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686) + set(PAL_CMAKE_PLATFORM_ARCH_I386 1) + add_definitions(-D_X86_) + else() + message(FATAL_ERROR "Only ARM, AMD64, ARM64 and I386 is supported") + endif() endif() if(CMAKE_SYSTEM_NAME STREQUAL Darwin) @@ -65,7 +82,7 @@ elseif(PAL_CMAKE_PLATFORM_ARCH_ARM) elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64) add_definitions(-DBIT64=1) add_definitions(-D_WIN64=1) -elseif(CLR_CMAKE_PLATFORM_ARCH_I386) +elseif(PAL_CMAKE_PLATFORM_ARCH_I386) add_definitions(-DBIT32=1) endif() @@ -105,7 +122,7 @@ elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64) arch/arm64/exceptionhelper.S arch/arm64/processor.cpp ) -elseif(CLR_CMAKE_PLATFORM_ARCH_I386) +elseif(PAL_CMAKE_PLATFORM_ARCH_I386) set(ARCH_SOURCES arch/i386/context2.S arch/i386/debugbreak.S @@ -264,31 +281,73 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux) find_library(UNWIND_ARCH NAMES unwind-arm) endif() + if(PAL_CMAKE_PLATFORM_ARCH_ARM64) + find_library(UNWIND_ARCH NAMES unwind-aarch64) + endif() + if(PAL_CMAKE_PLATFORM_ARCH_AMD64) find_library(UNWIND_ARCH NAMES unwind-x86_64) endif() - if(CLR_CMAKE_PLATFORM_ALPINE_LINUX) + if(CLR_CMAKE_PLATFORM_ALPINE_LINUX OR CLR_CMAKE_PLATFORM_ANDROID) find_library(INTL intl) endif() - find_library(UNWIND NAMES unwind) + # On Android, we don't need to link with gcc_s, pthread and rt + if(NOT CLR_CMAKE_PLATFORM_ANDROID) + target_link_libraries(coreclrpal + gcc_s + pthread + rt + ) + endif() + + if(CLR_CMAKE_PLATFORM_ANDROID) + target_link_libraries(coreclrpal + gnustl_shared + android-support + android-glob) + endif() + + if(NOT CLR_CMAKE_PLATFORM_ANDROID) + find_library(UNWIND NAMES unwind) + + if(UNWIND STREQUAL UNWIND-NOTFOUND) + message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8-dev and libunwind8.") + endif(UNWIND STREQUAL UNWIND-NOTFOUND) + + target_link_libraries(coreclrpal ${UNWIND}) + endif() + + if(CLR_MAKE_PLATFORM_ANDROID) + find_library(ANDROID_SUPPORT NAMES android-support) + find_library(ANDROID_GLOB NAMES android-glob) + find_library(INTL NAMES intl) + + if(UNWIND_ARCH STREQUAL UNWIND_ARCH-NOTFOUND) + message(FATAL_ERROR "Cannot find libunwind.") + endif() + + if(ANDROID_SUPPORT STREQUAL ANDROID_SUPPORT-NOTFOUND) + message(FATAL_ERROR "Cannot find android-support.") + endif() + + if(ANDROID_GLOB STREQUAL ANDROID_GLOB-NOTFOUND) + message(FATAL_ERROR "Cannot find android-glob.") + endif() + + if(INTL STREQUAL INTL-NOTFOUND) + message(FATAL_ERROR "Cannot find libintl.") + endif() + endif() + find_library(UNWIND_GENERIC NAMES unwind-generic) target_link_libraries(coreclrpal - gcc_s - pthread - rt dl uuid ) - if(UNWIND STREQUAL UNWIND-NOTFOUND) - message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8-dev and libunwind8.") - endif(UNWIND STREQUAL UNWIND-NOTFOUND) - - target_link_libraries(coreclrpal ${UNWIND}) - if(NOT UNWIND_GENERIC STREQUAL UNWIND_GENERIC-NOTFOUND) target_link_libraries(coreclrpal ${UNWIND_GENERIC}) endif(NOT UNWIND_GENERIC STREQUAL UNWIND_GENERIC-NOTFOUND) diff --git a/src/pal/src/arch/amd64/processor.cpp b/src/pal/src/arch/amd64/processor.cpp index ac3d448a81..298d685c98 100644 --- a/src/pal/src/arch/amd64/processor.cpp +++ b/src/pal/src/arch/amd64/processor.cpp @@ -54,10 +54,18 @@ Return value: extern "C" unsigned int XmmYmmStateSupport() { unsigned int eax; - __asm(" xgetbv\n" \ - : "=a"(eax) /*output in eax*/\ - : "c"(0) /*inputs - 0 in ecx*/\ - : "eax", "edx" /* registers that are clobbered*/ + __asm(" mov $1, %%eax\n" \ + " cpuid\n" \ + " xor %%eax, %%eax\n" \ + " and $0x18000000, %%ecx\n" /* check for xsave feature set and that it is enabled by the OS */ \ + " cmp $0x18000000, %%ecx\n" \ + " jne end\n" \ + " xor %%ecx, %%ecx\n" \ + " xgetbv\n" \ + "end:\n" \ + : "=a"(eax) /* output in eax */ \ + : /* no inputs */ \ + : "eax", "ebx", "ecx", "edx" /* registers that are clobbered */ ); // Check OS has enabled both XMM and YMM state support return ((eax & 0x06) == 0x06) ? 1 : 0; diff --git a/src/pal/src/arch/i386/context2.S b/src/pal/src/arch/i386/context2.S index 16cbcc855c..11aba5e647 100644 --- a/src/pal/src/arch/i386/context2.S +++ b/src/pal/src/arch/i386/context2.S @@ -113,39 +113,22 @@ LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT): movdqu xmm7, [eax + CONTEXT_Xmm7] LOCAL_LABEL(Done_Restore_CONTEXT_EXTENDED_REGISTERS): - // Restore CONTROL register(s) - mov ecx, [eax + CONTEXT_Eip] - mov [esp], ecx - - mov ecx, [eax + CONTEXT_Esp] - push ecx - mov ecx, [eax + CONTEXT_Ebp] - push ecx - - pop ebp - pop esp - - // Restore INTEGER register(s) - mov ecx, [eax + CONTEXT_Edi] - push ecx - mov ecx, [eax + CONTEXT_Esi] - push ecx - mov ecx, [eax + CONTEXT_Edx] - push ecx - mov ecx, [eax + CONTEXT_Ecx] - push ecx - mov ecx, [eax + CONTEXT_Ebx] - push ecx - mov ecx, [eax + CONTEXT_Eax] - push ecx + // Restore Stack + mov esp, [eax + CONTEXT_Esp] - pop eax - pop ebx - pop ecx - pop edx - pop esi - pop edi + // Create a minimal frame + push DWORD PTR [eax + CONTEXT_Eip] + + // Restore register(s) + mov ebp, [eax + CONTEXT_Ebp] + mov edi, [eax + CONTEXT_Edi] + mov esi, [eax + CONTEXT_Esi] + mov edx, [eax + CONTEXT_Edx] + mov ecx, [eax + CONTEXT_Ecx] + mov ebx, [eax + CONTEXT_Ebx] + mov eax, [eax + CONTEXT_Eax] - ret 8 + // Resume + ret LEAF_END RtlRestoreContext, _TEXT diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in index 4d21fb70e4..77d7bfaf5a 100644 --- a/src/pal/src/config.h.in +++ b/src/pal/src/config.h.in @@ -51,6 +51,7 @@ #cmakedefine01 HAVE_MACH_EXCEPTIONS #cmakedefine01 HAVE_VM_ALLOCATE #cmakedefine01 HAVE_VM_READ +#cmakedefine01 HAVE_SEMAPHORE_H #cmakedefine01 HAS_SYSV_SEMAPHORES #cmakedefine01 HAS_PTHREAD_MUTEXES #cmakedefine01 HAVE_TTRACE diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake index a53e0db51e..4f2bc5739b 100644 --- a/src/pal/src/configure.cmake +++ b/src/pal/src/configure.cmake @@ -33,6 +33,7 @@ check_include_files(sys/lwp.h HAVE_SYS_LWP_H) check_include_files(lwp.h HAVE_LWP_H) check_include_files(libunwind.h HAVE_LIBUNWIND_H) check_include_files(runetype.h HAVE_RUNETYPE_H) +check_include_files(semaphore.h HAVE_SEMAPHORE_H) if(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD) set(CMAKE_REQUIRED_FLAGS "-ldl") @@ -48,15 +49,26 @@ check_include_files(gnu/lib-names.h HAVE_GNU_LIBNAMES_H) check_function_exists(kqueue HAVE_KQUEUE) check_function_exists(getpwuid_r HAVE_GETPWUID_R) -check_library_exists(pthread pthread_suspend "" HAVE_PTHREAD_SUSPEND) -check_library_exists(pthread pthread_suspend_np "" HAVE_PTHREAD_SUSPEND_NP) -check_library_exists(pthread pthread_continue "" HAVE_PTHREAD_CONTINUE) -check_library_exists(pthread pthread_continue_np "" HAVE_PTHREAD_CONTINUE_NP) -check_library_exists(pthread pthread_resume_np "" HAVE_PTHREAD_RESUME_NP) -check_library_exists(pthread pthread_attr_get_np "" HAVE_PTHREAD_ATTR_GET_NP) -check_library_exists(pthread pthread_getattr_np "" HAVE_PTHREAD_GETATTR_NP) -check_library_exists(pthread pthread_getcpuclockid "" HAVE_PTHREAD_GETCPUCLOCKID) -check_library_exists(pthread pthread_sigqueue "" HAVE_PTHREAD_SIGQUEUE) + +check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) +check_library_exists(c pthread_create "" HAVE_PTHREAD_IN_LIBC) + +if (HAVE_LIBPTHREAD) + set(PTHREAD_LIBRARY pthread) +elseif (HAVE_PTHREAD_IN_LIBC) + set(PTHREAD_LIBRARY c) +endif() + +check_library_exists(${PTHREAD_LIBRARY} pthread_suspend "" HAVE_PTHREAD_SUSPEND) +check_library_exists(${PTHREAD_LIBRARY} pthread_suspend_np "" HAVE_PTHREAD_SUSPEND_NP) +check_library_exists(${PTHREAD_LIBRARY} pthread_continue "" HAVE_PTHREAD_CONTINUE) +check_library_exists(${PTHREAD_LIBRARY} pthread_continue_np "" HAVE_PTHREAD_CONTINUE_NP) +check_library_exists(${PTHREAD_LIBRARY} pthread_resume_np "" HAVE_PTHREAD_RESUME_NP) +check_library_exists(${PTHREAD_LIBRARY} pthread_attr_get_np "" HAVE_PTHREAD_ATTR_GET_NP) +check_library_exists(${PTHREAD_LIBRARY} pthread_getattr_np "" HAVE_PTHREAD_GETATTR_NP) +check_library_exists(${PTHREAD_LIBRARY} pthread_getcpuclockid "" HAVE_PTHREAD_GETCPUCLOCKID) +check_library_exists(${PTHREAD_LIBRARY} pthread_sigqueue "" HAVE_PTHREAD_SIGQUEUE) + check_function_exists(sigreturn HAVE_SIGRETURN) check_function_exists(_thread_sys_sigreturn HAVE__THREAD_SYS_SIGRETURN) set(CMAKE_REQUIRED_LIBRARIES m) @@ -874,7 +886,8 @@ int main(void) unlink(szFileName); exit(ret); }" UNGETC_NOT_RETURN_EOF) -set(CMAKE_REQUIRED_LIBRARIES pthread) + +set(CMAKE_REQUIRED_LIBRARIES ${PTHREAD_LIBRARY}) check_cxx_source_runs(" #include <stdlib.h> #include <errno.h> diff --git a/src/pal/src/cruntime/file.cpp b/src/pal/src/cruntime/file.cpp index 5fe2b671f3..0eb2cea151 100644 --- a/src/pal/src/cruntime/file.cpp +++ b/src/pal/src/cruntime/file.cpp @@ -196,45 +196,6 @@ static BOOL WriteOnlyMode(FILE* pFile) /*++ Function: - _getw - -Gets an integer from a stream. - -Return Value - -_getw returns the integer value read. A return value of EOF indicates -either an error or end of file. However, because the EOF value is also -a legitimate integer value, use feof or ferror to verify an -end-of-file or error condition. - -Parameter - -file Pointer to FILE structure - ---*/ -int -__cdecl -_getw(PAL_FILE *f) -{ - INT ret = 0; - - PERF_ENTRY(_getw); - ENTRY("_getw (f=%p)\n", f); - - _ASSERTE(f != NULL); - - CLEARERR(f); - - ret = getw( f->bsdFilePtr ); - LOGEXIT( "returning %d\n", ret ); - PERF_EXIT(_getw); - - return ret; -} - - -/*++ -Function: _fdopen see MSDN @@ -448,45 +409,6 @@ _wfsopen( } /*++ -Function: - _putw - -Writes an integer to a stream. - -Return Value - -_putw returns the value written. A return value of EOF may indicate an -error. Because EOF is also a legitimate integer value, use ferror to -verify an error. - -Parameters - -c Binary integer to be output -file Pointer to FILE structure - ---*/ -int -__cdecl -_putw(int c, PAL_FILE *f) -{ - INT ret = 0; - - PERF_ENTRY(_putw); - ENTRY("_putw (c=0x%x, f=%p)\n", c, f); - - _ASSERTE(f != NULL); - - CLEARERR(f); - - ret = putw(c, f->bsdFilePtr ); - LOGEXIT( "returning %d\n", ret ); - PERF_EXIT(_putw); - - return ret; -} - - -/*++ Function PAL_get_stdout. diff --git a/src/pal/src/cruntime/math.cpp b/src/pal/src/cruntime/math.cpp index 08f4192998..d53dbe7982 100644 --- a/src/pal/src/cruntime/math.cpp +++ b/src/pal/src/cruntime/math.cpp @@ -66,11 +66,7 @@ int __cdecl _finite(double x) PERF_ENTRY(_finite); ENTRY("_finite (x=%f)\n", x); -#if defined(_IA64_) && defined (_HPUX_) - ret = !isnan(x) && (x != PAL_POSINF_DBL) && (x != PAL_NEGINF_DBL); -#else ret = isfinite(x); -#endif LOGEXIT("_finite returns int %d\n", ret); PERF_EXIT(_finite); @@ -452,11 +448,7 @@ int __cdecl _finitef(float x) PERF_ENTRY(_finitef); ENTRY("_finitef (x=%f)\n", x); -#if defined(_IA64_) && defined (_HPUX_) - ret = !isnan(x) && (x != PAL_POSINF_FLT) && (x != PAL_NEGINF_FLT); -#else ret = isfinite(x); -#endif LOGEXIT("_finitef returns int %d\n", ret); PERF_EXIT(_finitef); diff --git a/src/pal/src/cruntime/printf.cpp b/src/pal/src/cruntime/printf.cpp index c437b8e39f..72c7e11bea 100644 --- a/src/pal/src/cruntime/printf.cpp +++ b/src/pal/src/cruntime/printf.cpp @@ -1365,34 +1365,6 @@ int PAL_wvsscanf(LPCWSTR Buffer, LPCWSTR Format, va_list ap) /*++ Function: - PAL_swprintf - -See MSDN doc. ---*/ -int -__cdecl -PAL_swprintf( - wchar_16 *buffer, - const wchar_16 *format, - ...) -{ - LONG Length; - va_list ap; - - PERF_ENTRY(swprintf); - ENTRY("PAL_swprintf (buffer=%p, format=%p (%S))\n", buffer, format, format); - - va_start(ap, format); - Length = PAL__wvsnprintf(buffer, 0x7fffffff, format, ap); - va_end(ap); - - LOGEXIT("PAL_swprintf returns int %d\n", Length); - PERF_EXIT(swprintf); - return Length; -} - -/*++ -Function: PAL_swscanf See MSDN doc. @@ -1420,60 +1392,6 @@ PAL_swscanf( } -/*++ -Function: - PAL_vsprintf - -See MSDN doc. ---*/ -int -__cdecl -PAL_vsprintf(char *buffer, - const char *format, - va_list argptr) -{ - LONG Length; - - PERF_ENTRY(vsprintf); - ENTRY("PAL_vsprintf (buffer=%p, format=%p (%s), argptr=%p)\n", - buffer, format, format, argptr); - - Length = InternalVsnprintf(CorUnix::InternalGetCurrentThread(), buffer, 0x7fffffff, format, argptr); - - LOGEXIT("PAL_vsprintf returns int %d\n", Length); - PERF_EXIT(vsprintf); - - return Length; -} - - -/*++ -Function: - PAL_vswprintf - -See MSDN doc. ---*/ -int -__cdecl -PAL_vswprintf(wchar_16 *buffer, - const wchar_16 *format, - va_list argptr) -{ - LONG Length; - - PERF_ENTRY(vswprintf); - ENTRY("PAL_vswprintf (buffer=%p, format=%p (%S), argptr=%p)\n", - buffer, format, format, argptr); - - Length = PAL__wvsnprintf(buffer, 0x7fffffff, format, argptr); - - LOGEXIT("PAL_vswprintf returns int %d\n", Length); - PERF_EXIT(vswprintf); - - return Length; -} - - #if SSCANF_CANNOT_HANDLE_MISSING_EXPONENT /*++ Function: diff --git a/src/pal/src/cruntime/printfcpp.cpp b/src/pal/src/cruntime/printfcpp.cpp index ea074a604b..0b9072102b 100644 --- a/src/pal/src/cruntime/printfcpp.cpp +++ b/src/pal/src/cruntime/printfcpp.cpp @@ -35,8 +35,9 @@ SET_DEFAULT_DEBUG_CHANNEL(CRT); using namespace CorUnix; -int CoreWvsnprintf(CPalThread *pthrCurrent, LPWSTR Buffer, size_t Count, LPCWSTR Format, va_list ap); -int CoreVsnprintf(CPalThread *pthrCurrent, LPSTR Buffer, size_t Count, LPCSTR Format, va_list ap); +static const char __nullstring[] = "(null)"; /* string to print on null ptr */ +static const WCHAR __wnullstring[] = W("(null)"); /* string to print on null ptr */ + int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, va_list ap); int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *format, va_list ap); @@ -865,7 +866,7 @@ Parameters: - padding style flags (PRINTF_FORMAT_FLAGS) *******************************************************************************/ -INT Internal_AddPaddingVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, LPSTR In, +INT Internal_AddPaddingVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, LPCSTR In, INT Padding, INT Flags) { LPSTR Out; @@ -1053,49 +1054,6 @@ static INT Internal_AddPaddingVfwprintf(CPalThread *pthrCurrent, PAL_FILE *strea /******************************************************************************* Function: - PAL_vsnprintf - -Parameters: - Buffer - - out buffer - Count - - buffer size - Format - - format string - ap - - stdarg parameter list -*******************************************************************************/ - -int __cdecl PAL__vsnprintf(LPSTR Buffer, size_t Count, LPCSTR Format, va_list ap) -{ - LONG Length; - - PERF_ENTRY(PAL__vsnprintf); - ENTRY("PAL__vsnprintf (buffer=%p, count=%d, format=%p (%s), argptr=%p)\n", - Buffer, Count, Format, Format, ap); - - Length = CoreVsnprintf(InternalGetCurrentThread(), Buffer, Count, Format, ap); - - LOGEXIT("PAL__vsnprintf returns int %d\n", Length); - PERF_EXIT(PAL__vsnprintf); - - return Length; -} - -/******************************************************************************* -Function: - PAL_wvsnprintf - - -- see PAL_vsnprintf above -*******************************************************************************/ - -int __cdecl PAL__wvsnprintf(LPWSTR Buffer, size_t Count, LPCWSTR Format, va_list ap) -{ - return CoreWvsnprintf(InternalGetCurrentThread(), Buffer, Count, Format, ap); -} - -/******************************************************************************* -Function: PAL_vfprintf Parameters: @@ -1132,31 +1090,17 @@ int __cdecl PAL_vfwprintf(PAL_FILE *stream, const wchar_16 *format, va_list ap) } // end extern "C" -int CorUnix::InternalWvsnprintf(CPalThread *pthrCurrent, LPWSTR Buffer, size_t Count, LPCWSTR Format, va_list ap) -{ - return CoreWvsnprintf(pthrCurrent, Buffer, Count, Format, ap); -} - -int CorUnix::InternalVsnprintf(CPalThread *pthrCurrent, LPSTR Buffer, size_t Count, LPCSTR Format, va_list ap) -{ - return CoreVsnprintf(pthrCurrent, Buffer, Count, Format, ap); -} - int CorUnix::InternalVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, va_list ap) { return CoreVfprintf(pthrCurrent, stream, format, ap); } -int CorUnix::InternalVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *format, va_list ap) -{ - return CoreVfwprintf(pthrCurrent, stream, format, ap); -} - int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *format, va_list aparg) { CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */ LPCWSTR Fmt = format; - LPWSTR TempWStr = NULL; + LPCWSTR TempWStr = NULL; + LPWSTR AllocedTempWStr = NULL; LPWSTR WorkingWStr = NULL; WCHAR TempWChar[2]; INT Flags; @@ -1165,7 +1109,6 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for INT Prefix; INT Type; INT TempInt; - BOOL WStrWasMalloced = FALSE; int mbtowcResult; int written=0; int paddingReturnValue; @@ -1193,7 +1136,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for (Type == PFF_TYPE_STRING || Type == PFF_TYPE_WSTRING)) || (Type == PFF_TYPE_WSTRING && (Flags & PFF_ZERO) != 0)) { - WStrWasMalloced = FALSE; + AllocedTempWStr = NULL; if (WIDTH_STAR == Width) { @@ -1222,37 +1165,50 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for else { /* %lS assumes a LPSTR argument. */ - LPSTR s = va_arg(ap, LPSTR ); - UINT Length = 0; - Length = MultiByteToWideChar( CP_ACP, 0, s, -1, NULL, 0 ); - if ( Length != 0 ) + LPCSTR s = va_arg(ap, LPSTR ); + if (s == NULL) + { + TempWStr = NULL; + } + else { - TempWStr = - (LPWSTR)InternalMalloc( (Length) * sizeof( WCHAR ) ); - if ( TempWStr ) + UINT Length = 0; + Length = MultiByteToWideChar( CP_ACP, 0, s, -1, NULL, 0 ); + if ( Length != 0 ) { - WStrWasMalloced = TRUE; - MultiByteToWideChar( CP_ACP, 0, s, -1, - TempWStr, Length ); + AllocedTempWStr = + (LPWSTR)InternalMalloc( (Length) * sizeof( WCHAR ) ); + + if ( AllocedTempWStr ) + { + MultiByteToWideChar( CP_ACP, 0, s, -1, + AllocedTempWStr, Length ); + TempWStr = AllocedTempWStr; + } + else + { + ERROR( "InternalMalloc failed.\n" ); + LOGEXIT("vfwprintf returns int -1\n"); + PERF_EXIT(vfwprintf); + va_end(ap); + return -1; + } } else { - ERROR( "InternalMalloc failed.\n" ); + ASSERT( "Unable to convert from multibyte " + " to wide char.\n" ); LOGEXIT("vfwprintf returns int -1\n"); PERF_EXIT(vfwprintf); va_end(ap); return -1; } } - else - { - ASSERT( "Unable to convert from multibyte " - " to wide char.\n" ); - LOGEXIT("vfwprintf returns int -1\n"); - PERF_EXIT(vfwprintf); - va_end(ap); - return -1; - } + } + + if (TempWStr == NULL) + { + TempWStr = __wnullstring; } INT Length = PAL_wcslen(TempWStr); @@ -1263,10 +1219,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for LOGEXIT("vfwprintf returns int -1\n"); PERF_EXIT(vfwprintf); pthrCurrent->SetLastError(ERROR_NOT_ENOUGH_MEMORY); - if (WStrWasMalloced) - { - free(TempWStr); - } + free(AllocedTempWStr); va_end(ap); return -1; } @@ -1281,10 +1234,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for if (wcsncpy_s(WorkingWStr, (Length + 1), TempWStr, Precision+1) != SAFECRT_SUCCESS) { ERROR("Internal_AddPaddingVfwprintf failed\n"); - if (WStrWasMalloced) - { - free(TempWStr); - } + free(AllocedTempWStr); free(WorkingWStr); LOGEXIT("wcsncpy_s failed!\n"); PERF_EXIT(vfwprintf); @@ -1310,10 +1260,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for if (paddingReturnValue == -1) { ERROR("Internal_AddPaddingVfwprintf failed\n"); - if (WStrWasMalloced) - { - free(TempWStr); - } + free(AllocedTempWStr); free(WorkingWStr); LOGEXIT("vfwprintf returns int -1\n"); PERF_EXIT(vfwprintf); @@ -1323,10 +1270,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for written += paddingReturnValue; free(WorkingWStr); - if (WStrWasMalloced) - { - free(TempWStr); - } + free(AllocedTempWStr); } else if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_CHAR) { @@ -1466,7 +1410,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for va_list apcopy; va_copy(apcopy, ap); - TempInt = vsnprintf(TempSprintfStr, TEMP_COUNT, TempBuff, apcopy); + TempInt = _vsnprintf_s(TempSprintfStr, TEMP_COUNT, _TRUNCATE, TempBuff, apcopy); va_end(apcopy); PAL_printf_arg_remover(&ap, Width, Precision, Type, Prefix); @@ -1484,7 +1428,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for TempSprintfStr = TempSprintfStrPtr; va_copy(apcopy, ap); - vsnprintf(TempSprintfStr, TempInt, TempBuff, apcopy); + _vsnprintf_s(TempSprintfStr, TempInt, _TRUNCATE, TempBuff, apcopy); va_end(apcopy); PAL_printf_arg_remover(&ap, Width, Precision, Type, Prefix); } @@ -1581,669 +1525,11 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for return (written); } -int CoreVsnprintf(CPalThread *pthrCurrent, LPSTR Buffer, size_t Count, LPCSTR Format, va_list aparg) -{ - BOOL BufferRanOut = FALSE; - CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */ - LPSTR BufferPtr = Buffer; - LPCSTR Fmt = Format; - LPWSTR TempWStr; - LPSTR TempStr; - WCHAR TempWChar; - INT Flags; - INT Width; - INT Precision; - INT Prefix; - INT Type; - INT Length; - INT TempInt; - int wctombResult; - va_list ap; - - va_copy(ap, aparg); - - while (*Fmt) - { - if (BufferRanOut || (BufferPtr - Buffer) >= static_cast<int>(Count)) //Count is assumed to be in the range of int - { - BufferRanOut = TRUE; - break; - } - else if(*Fmt == '%' && - TRUE == Internal_ExtractFormatA(pthrCurrent, &Fmt, TempBuff, &Flags, - &Width, &Precision, - &Prefix, &Type)) - { - if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_STRING) - { - if (WIDTH_STAR == Width) - { - Width = va_arg(ap, INT); - } - else if (WIDTH_INVALID == Width) - { - /* both a '*' and a number, ignore, but remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - if (PRECISION_STAR == Precision) - { - Precision = va_arg(ap, INT); - } - else if (PRECISION_INVALID == Precision) - { - /* both a '*' and a number, ignore, but remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - TempWStr = va_arg(ap, LPWSTR); - Length = WideCharToMultiByte(CP_ACP, 0, TempWStr, -1, 0, - 0, 0, 0); - if (!Length) - { - ASSERT("WideCharToMultiByte failed. Error is %d\n", - GetLastError()); - va_end(ap); - return -1; - } - TempStr = (LPSTR) InternalMalloc(Length); - if (!TempStr) - { - ERROR("InternalMalloc failed\n"); - pthrCurrent->SetLastError(ERROR_NOT_ENOUGH_MEMORY); - va_end(ap); - return -1; - } - if (PRECISION_DOT == Precision) - { - /* copy nothing */ - *TempStr = 0; - Length = 0; - } - else if (Precision > 0 && Precision < Length - 1) - { - Length = WideCharToMultiByte(CP_ACP, 0, TempWStr, - Precision, TempStr, Length, - 0, 0); - if (!Length) - { - ASSERT("WideCharToMultiByte failed. Error is %d\n", - GetLastError()); - free(TempStr); - va_end(ap); - return -1; - } - TempStr[Length] = 0; - Length = Precision; - } - /* copy everything */ - else - { - wctombResult = WideCharToMultiByte(CP_ACP, 0, TempWStr, -1, - TempStr, Length, 0, 0); - if (!wctombResult) - { - ASSERT("WideCharToMultiByte failed. Error is %d\n", - GetLastError()); - free(TempStr); - va_end(ap); - return -1; - } - --Length; /* exclude null char */ - } - - /* do the padding (if needed)*/ - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - TempStr, - Width - Length, - Flags); - - free(TempStr); - } - else if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_CHAR) - { - CHAR TempBuffer[5]; - - if (WIDTH_STAR == Width || - WIDTH_INVALID == Width) - { - /* ignore (because it's a char), and remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - if (PRECISION_STAR == Precision || - PRECISION_INVALID == Precision) - { - /* ignore (because it's a char), and remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - TempWChar = va_arg(ap, int); - Length = WideCharToMultiByte(CP_ACP, 0, &TempWChar, 1, - TempBuffer, sizeof(TempBuffer), - 0, 0); - if (!Length) - { - ASSERT("WideCharToMultiByte failed. Error is %d\n", - GetLastError()); - va_end(ap); - return -1; - } - TempBuffer[Length] = 0; - - /* do the padding (if needed)*/ - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - TempBuffer, - Width - Length, - Flags); - - } - /* this places the number of bytes written to the buffer in the - next arg */ - else if (Type == PFF_TYPE_N) - { - if (WIDTH_STAR == Width) - { - Width = va_arg(ap, INT); - } - if (PRECISION_STAR == Precision) - { - Precision = va_arg(ap, INT); - } - - if (Prefix == PFF_PREFIX_SHORT) - { - *(va_arg(ap, short *)) = BufferPtr - Buffer; - } - else - { - *(va_arg(ap, LPLONG)) = BufferPtr - Buffer; - } - } - else if (Type == PFF_TYPE_CHAR && (Flags & PFF_ZERO) != 0) - { - // Some versions of sprintf don't support 0-padded chars, - // so we handle them here. - char ch[2]; - - ch[0] = (char) va_arg(ap, int); - ch[1] = '\0'; - Length = 1; - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - ch, - Width - Length, - Flags); - } - else if (Type == PFF_TYPE_STRING && (Flags & PFF_ZERO) != 0) - { - // Some versions of sprintf don't support 0-padded strings, - // so we handle them here. - char *tempStr; - - tempStr = va_arg(ap, char *); - Length = strlen(tempStr); - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - tempStr, - Width - Length, - Flags); - } - else - { - // Types that sprintf can handle - size_t TempCount = Count - (BufferPtr - Buffer); - -#if !HAVE_LARGE_SNPRINTF_SUPPORT - // Limit TempCount to 0x40000000, which is sufficient - // for platforms on which snprintf fails for very large - // sizes. - if (TempCount > 0x40000000) - { - TempCount = 0x40000000; - } -#endif // HAVE_LARGE_SNPRINTF_SUPPORT - - TempInt = 0; - // %h (short) doesn't seem to be handled properly by local sprintf, - // so we do the truncation ourselves for some cases. - if (Type == PFF_TYPE_P && Prefix == PFF_PREFIX_SHORT) - { - // Convert from pointer -> int -> short to avoid warnings. - long trunc1; - short trunc2; - - trunc1 = va_arg(ap, LONG); - trunc2 = (short) trunc1; - trunc1 = trunc2; - - TempInt = snprintf(BufferPtr, TempCount, TempBuff, trunc1); - } - else if (Type == PFF_TYPE_INT && Prefix == PFF_PREFIX_SHORT) - { - // Convert explicitly from int to short to get - // correct sign extension for shorts on all systems. - int n; - short s; - - n = va_arg(ap, int); - s = (short) n; - - TempInt = snprintf(BufferPtr, TempCount, TempBuff, s); - } - else - { - va_list apcopy; - va_copy(apcopy, ap); - TempInt = vsnprintf(BufferPtr, TempCount, TempBuff, apcopy); - va_end(apcopy); - PAL_printf_arg_remover(&ap, Width, Precision, Type, Prefix); - } - - if (TempInt < 0 || static_cast<size_t>(TempInt) >= TempCount) /* buffer not long enough */ - { - BufferPtr += TempCount; - BufferRanOut = TRUE; - } - else - { - BufferPtr += TempInt; - } - } - } - else - { - *BufferPtr++ = *Fmt++; /* copy regular chars into buffer */ - } - } - - if (static_cast<int>(Count) > (BufferPtr - Buffer)) //Count is assumed to be in the range of int - { - *BufferPtr = 0; /* end the string */ - } - - va_end(ap); - - if (BufferRanOut) - { - errno = ERANGE; - return -1; - } - else - { - return BufferPtr - Buffer; - } -} - -int CoreWvsnprintf(CPalThread *pthrCurrent, LPWSTR Buffer, size_t Count, LPCWSTR Format, va_list aparg) -{ - BOOL BufferRanOut = FALSE; - CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */ - LPWSTR BufferPtr = Buffer; - LPCWSTR Fmt = Format; - LPWSTR TempWStr = NULL; - LPWSTR WorkingWStr = NULL; - WCHAR TempWChar[2]; - INT Flags; - INT Width; - INT Precision; - INT Prefix; - INT Type; - INT TempInt; - LPSTR TempNumberBuffer; - int mbtowcResult; - va_list(ap); - - PERF_ENTRY(wvsnprintf); - ENTRY("wvsnprintf (buffer=%p, count=%u, format=%p (%S))\n", - Buffer, Count, Format, Format); - - va_copy(ap, aparg); - - while (*Fmt) - { - if (BufferRanOut || (BufferPtr - Buffer) >= static_cast<int>(Count)) //Count is assumed to be in the range of int - { - BufferRanOut = TRUE; - break; - } - else if(*Fmt == '%' && - TRUE == Internal_ExtractFormatW(pthrCurrent, &Fmt, TempBuff, &Flags, - &Width, &Precision, - &Prefix, &Type)) - { - if (((Prefix == PFF_PREFIX_LONG || Prefix == PFF_PREFIX_LONG_W) && - (Type == PFF_TYPE_STRING || Type == PFF_TYPE_WSTRING)) || - (Prefix == PFF_PREFIX_SHORT && Type == PFF_TYPE_STRING) || - (Type == PFF_TYPE_WSTRING && (Flags & PFF_ZERO) != 0)) - { - BOOL needToFree = FALSE; - - if (WIDTH_STAR == Width) - { - Width = va_arg(ap, INT); - } - else if (WIDTH_INVALID == Width) - { - /* both a '*' and a number, ignore, but remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - if (PRECISION_STAR == Precision) - { - Precision = va_arg(ap, INT); - } - else if (PRECISION_INVALID == Precision) - { - /* both a '*' and a number, ignore, but remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - if ((Type == PFF_TYPE_STRING && Prefix == PFF_PREFIX_LONG) || - Prefix == PFF_PREFIX_LONG_W) - { - TempWStr = va_arg(ap, LPWSTR); - } - else - { - // %lS and %hs assume an LPSTR argument. - LPSTR s = va_arg(ap, LPSTR ); - UINT Length = 0; - Length = MultiByteToWideChar( CP_ACP, 0, s, -1, NULL, 0 ); - if ( Length != 0 ) - { - TempWStr = - (LPWSTR)InternalMalloc((Length + 1 ) * sizeof( WCHAR ) ); - if ( TempWStr ) - { - needToFree = TRUE; - MultiByteToWideChar( CP_ACP, 0, s, -1, - TempWStr, Length ); - } - else - { - ERROR( "InternalMalloc failed.\n" ); - va_end(ap); - return -1; - } - } - else - { - ASSERT( "Unable to convert from multibyte " - " to wide char.\n" ); - va_end(ap); - return -1; - } - - } - - INT Length = PAL_wcslen(TempWStr); - WorkingWStr = (LPWSTR) InternalMalloc(sizeof(WCHAR) * (Length + 1)); - if (!WorkingWStr) - { - ERROR("InternalMalloc failed\n"); - pthrCurrent->SetLastError(ERROR_NOT_ENOUGH_MEMORY); - if (needToFree) - { - free(TempWStr); - } - va_end(ap); - return -1; - } - if (PRECISION_DOT == Precision) - { - // Copy nothing - *WorkingWStr = 0; - Length = 0; - } - else if (Precision > 0 && Precision < Length) - { - if (wcsncpy_s(WorkingWStr, (Length + 1), TempWStr, Precision+1) != SAFECRT_SUCCESS) - { - ERROR("CoreWvsnprintf failed\n"); - if (needToFree) - { - free(TempWStr); - } - free(WorkingWStr); - LOGEXIT("wcsncpy_s failed!\n"); - PERF_EXIT(wvsnprintf); - va_end(ap); - return (-1); - } - - Length = Precision; - } - else - { - // Copy everything - PAL_wcscpy(WorkingWStr, TempWStr); - } - - // Add padding if needed. - BufferRanOut = !Internal_AddPaddingW(&BufferPtr, - Count - (BufferPtr - Buffer), - WorkingWStr, - Width - Length, - Flags); - - if (needToFree) - { - free(TempWStr); - } - free(WorkingWStr); - } - else if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_CHAR) - { - if (WIDTH_STAR == Width || - WIDTH_INVALID == Width) - { - /* ignore (because it's a char), and remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - if (PRECISION_STAR == Precision || - PRECISION_INVALID == Precision) - { - /* ignore (because it's a char), and remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - TempWChar[0] = va_arg(ap, int); - TempWChar[1] = 0; - - /* do the padding (if needed)*/ - BufferRanOut = !Internal_AddPaddingW(&BufferPtr, - Count - (BufferPtr - Buffer), - TempWChar, - Width - 1, - Flags); - - } - /* this places the number of bytes written to the buffer in the - next arg */ - else if (Type == PFF_TYPE_N) - { - if (WIDTH_STAR == Width) - { - Width = va_arg(ap, INT); - } - if (PRECISION_STAR == Precision) - { - Precision = va_arg(ap, INT); - } - - if (Prefix == PFF_PREFIX_SHORT) - { - *(va_arg(ap, short *)) = BufferPtr - Buffer; - } - else - { - *(va_arg(ap, LPLONG)) = BufferPtr - Buffer; - } - } - else - { - // Types that sprintf can handle - - /* note: I'm using the wide buffer as a (char *) buffer when I - pass it to sprintf(). After I get the buffer back I make a - backup of the chars copied and then convert them to wide - and place them in the buffer (BufferPtr) */ - size_t TempCount = Count - (BufferPtr - Buffer); - TempInt = 0; - -#if !HAVE_LARGE_SNPRINTF_SUPPORT - // Limit TempCount to 0x40000000, which is sufficient - // for platforms on which snprintf fails for very large - // sizes. - if (TempCount > 0x40000000) - { - TempCount = 0x40000000; - } -#endif // HAVE_LARGE_SNPRINTF_SUPPORT - - // %h (short) doesn't seem to be handled properly by local sprintf, - // so we do the truncation ourselves for some cases. - if (Type == PFF_TYPE_P && Prefix == PFF_PREFIX_SHORT) - { - // Convert from pointer -> int -> short to avoid warnings. - long trunc1; - short trunc2; - - trunc1 = va_arg(ap, LONG); - trunc2 = (short)trunc1; - trunc1 = trunc2; - - TempInt = snprintf((LPSTR)BufferPtr, TempCount, TempBuff, trunc1); - } - else if (Type == PFF_TYPE_INT && Prefix == PFF_PREFIX_SHORT) - { - // Convert explicitly from int to short to get - // correct sign extension for shorts on all systems. - int n; - short s; - - n = va_arg(ap, int); - s = (short) n; - - TempInt = snprintf((LPSTR)BufferPtr, TempCount, TempBuff, s); - } - else - { - va_list apcopy; - va_copy(apcopy, ap); - TempInt = vsnprintf((LPSTR) BufferPtr, TempCount, TempBuff, apcopy); - va_end(apcopy); - PAL_printf_arg_remover(&ap, Width, Precision, Type, Prefix); - } - - if (TempInt == 0) - { - // The argument is "". - continue; - } - if (TempInt < 0 || static_cast<size_t>(TempInt) >= TempCount) /* buffer not long enough */ - { - TempNumberBuffer = (LPSTR) InternalMalloc(TempCount+1); - if (!TempNumberBuffer) - { - ERROR("InternalMalloc failed\n"); - pthrCurrent->SetLastError(ERROR_NOT_ENOUGH_MEMORY); - errno = ENOMEM; - va_end(ap); - return -1; - } - - if (strncpy_s(TempNumberBuffer, TempCount+1, (LPSTR) BufferPtr, TempCount) != SAFECRT_SUCCESS) - { - ASSERT("strncpy_s failed!\n"); - free(TempNumberBuffer); - va_end(ap); - return -1; - } - - mbtowcResult = MultiByteToWideChar(CP_ACP, 0, - TempNumberBuffer, - TempCount, - BufferPtr, TempCount); - if (!mbtowcResult) - { - ASSERT("MultiByteToWideChar failed. Error is %d\n", - GetLastError()); - free(TempNumberBuffer); - va_end(ap); - return -1; - } - BufferPtr += TempCount; - BufferRanOut = TRUE; - } - else - { - TempNumberBuffer = (LPSTR) InternalMalloc(TempInt+1); - if (!TempNumberBuffer) - { - ERROR("InternalMalloc failed\n"); - pthrCurrent->SetLastError(ERROR_NOT_ENOUGH_MEMORY); - va_end(ap); - return -1; - } - - if (strncpy_s(TempNumberBuffer, TempInt+1, (LPSTR) BufferPtr, TempInt) != SAFECRT_SUCCESS) - { - ASSERT("strncpy_s failed!\n"); - free(TempNumberBuffer); - va_end(ap); - return -1; - } - - mbtowcResult = MultiByteToWideChar(CP_ACP, 0, - TempNumberBuffer, - TempInt, - BufferPtr, TempInt); - if (!mbtowcResult) - { - ASSERT("MultiByteToWideChar failed. Error is %d\n", - GetLastError()); - free(TempNumberBuffer); - va_end(ap); - return -1; - } - BufferPtr += TempInt; - } - free(TempNumberBuffer); - } - } - else - { - *BufferPtr++ = *Fmt++; /* copy regular chars into buffer */ - } - } - - if (static_cast<int>(Count) > (BufferPtr - Buffer)) //Count is assumed to be in the range of int - { - *BufferPtr = 0; /* end the string */ - } - - va_end(ap); - - if (BufferRanOut) - { - errno = ERANGE; - return -1; - } - else - { - return BufferPtr - Buffer; - } -} - int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, va_list aparg) { CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */ LPCSTR Fmt = format; - LPWSTR TempWStr; + LPCWSTR TempWStr; LPSTR TempStr; WCHAR TempWChar; INT Flags; @@ -2292,6 +1578,10 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, } TempWStr = va_arg(ap, LPWSTR); + if (TempWStr == NULL)\ + { + TempWStr = __wnullstring; + } Length = WideCharToMultiByte(CP_ACP, 0, TempWStr, -1, 0, 0, 0, 0); if (!Length) @@ -2461,9 +1751,13 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, { // Some versions of fprintf don't support 0-padded strings, // so we handle them here. - char *tempStr; + const char *tempStr; tempStr = va_arg(ap, char *); + if (tempStr == NULL) + { + tempStr = __nullstring; + } Length = strlen(tempStr); paddingReturnValue = Internal_AddPaddingVfprintf( pthrCurrent, diff --git a/src/pal/src/cruntime/silent_printf.cpp b/src/pal/src/cruntime/silent_printf.cpp index 1d10963973..4047c7e199 100644 --- a/src/pal/src/cruntime/silent_printf.cpp +++ b/src/pal/src/cruntime/silent_printf.cpp @@ -40,286 +40,6 @@ static INT Silent_AddPaddingVfprintf(PAL_FILE *stream, LPSTR In, INT Padding, static size_t Silent_PAL_wcslen(const wchar_16 *string); -/******************************************************************************* -Function: - PAL_vsnprintf (silent version) - for more details, see PAL_vsnprintf in printf.c -*******************************************************************************/ -INT Silent_PAL_vsnprintf(LPSTR Buffer, INT Count, LPCSTR Format, va_list aparg) -{ - BOOL BufferRanOut = FALSE; - CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */ - LPSTR BufferPtr = Buffer; - LPCSTR Fmt = Format; - LPWSTR TempWStr; - CHAR TempStr[MAX_STR_LEN+1]; - WCHAR TempWChar; - INT Flags; - INT Width; - INT Precision; - INT Prefix; - INT Type; - INT Length; - INT TempInt; - int wctombResult; - va_list ap; - - va_copy(ap, aparg); - - while (*Fmt) - { - if ((BufferPtr - Buffer) >= Count) - { - BufferRanOut = TRUE; - break; - } - else if(*Fmt == '%' && - TRUE == Silent_ExtractFormatA(&Fmt, TempBuff, &Flags, - &Width, &Precision, - &Prefix, &Type)) - { - if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_STRING) - { - if (WIDTH_STAR == Width) - { - Width = va_arg(ap, INT); - } - else if (WIDTH_INVALID == Width) - { - /* both a '*' and a number, ignore, but remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - if (PRECISION_STAR == Precision) - { - Precision = va_arg(ap, INT); - } - else if (PRECISION_INVALID == Precision) - { - /* both a '*' and a number, ignore, but remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - TempWStr = va_arg(ap, LPWSTR); - Length = Silent_WideCharToMultiByte(TempWStr, -1, 0, 0); - if (!Length) - { - va_end(ap); - return -1; - } - - /* clip string output to MAX_STR_LEN characters */ - if (PRECISION_DOT == Precision) - { - Precision = MAX_STR_LEN; - } - - if (PRECISION_DOT == Precision) - { - /* copy nothing */ - *TempStr = 0; - Length = 0; - } - else if (Precision > 0 && Precision < Length - 1) - { - Length = Silent_WideCharToMultiByte(TempWStr, Precision, - TempStr, Length); - if (!Length) - { - va_end(ap); - return -1; - } - TempStr[Length] = 0; - Length = Precision; - } - /* copy everything */ - else - { - wctombResult = Silent_WideCharToMultiByte(TempWStr, -1, - TempStr, Length); - if (!wctombResult) - { - PAL_free(TempStr); - va_end(ap); - return -1; - } - --Length; /* exclude null char */ - } - - /* do the padding (if needed)*/ - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - TempStr, - Width - Length, - Flags); - } - else if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_CHAR) - { - CHAR TempBuffer[4]; - - if (WIDTH_STAR == Width || - WIDTH_INVALID == Width) - { - /* ignore (because it's a char), and remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - if (PRECISION_STAR == Precision || - PRECISION_INVALID == Precision) - { - /* ignore (because it's a char), and remove arg */ - TempInt = va_arg(ap, INT); /* value not used */ - } - - TempWChar = va_arg(ap, int); - Length = Silent_WideCharToMultiByte(&TempWChar, 1, TempBuffer, 4); - if (!Length) - { - va_end(ap); - return -1; - } - TempBuffer[Length] = 0; - - /* do the padding (if needed)*/ - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - TempBuffer, - Width - Length, - Flags); - - } - /* this places the number of bytes written to the buffer in the - next arg */ - else if (Type == PFF_TYPE_N) - { - if (WIDTH_STAR == Width) - { - Width = va_arg(ap, INT); - } - if (PRECISION_STAR == Precision) - { - Precision = va_arg(ap, INT); - } - if (Prefix == PFF_PREFIX_SHORT) - { - *(va_arg(ap, short *)) = BufferPtr - Buffer; - } - else - { - *(va_arg(ap, LPLONG)) = BufferPtr - Buffer; - } - } - else if (Type == PFF_TYPE_CHAR && (Flags & PFF_ZERO) != 0) - { - // Some versions of sprintf don't support 0-padded chars, - // so we handle them here. - char ch[2]; - - ch[0] = (char) va_arg(ap, int); - ch[1] = '\0'; - Length = 1; - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - ch, - Width - Length, - Flags); - } - else if (Type == PFF_TYPE_STRING && (Flags & PFF_ZERO) != 0) - { - // Some versions of sprintf don't support 0-padded strings, - // so we handle them here. - char *tempStr; - - tempStr = va_arg(ap, char *); - Length = strlen(tempStr); - BufferRanOut = !Internal_AddPaddingA(&BufferPtr, - Count - (BufferPtr - Buffer), - tempStr, - Width - Length, - Flags); - } - /* types that sprintf can handle */ - else - { - size_t TempCount = Count - (BufferPtr - Buffer); - - TempInt = 0; - /* %h (short) doesn't seem to be handled properly by local sprintf, - so lets do the truncation ourselves. (ptr -> int -> short to avoid - warnings */ - if (Type == PFF_TYPE_P && Prefix == PFF_PREFIX_SHORT) - { - long trunc1; - short trunc2; - - trunc1 = va_arg(ap, LONG); - trunc2 = (short)trunc1; - - TempInt = snprintf(BufferPtr, TempCount, TempBuff, trunc2); - } - else if (Type == PFF_TYPE_INT && Prefix == PFF_PREFIX_SHORT) - { - // Convert explicitly from int to short to get - // correct sign extension for shorts on all systems. - int n; - short s; - - n = va_arg(ap, int); - s = (short) n; - - TempInt = snprintf(BufferPtr, TempCount, TempBuff, s); - } - else - { - /* limit string output (%s) to 300 characters */ - if(TempBuff[0] == '%' && TempBuff[1] == 's') - { - if (strcpy_s(TempBuff, sizeof(TempBuff), "%.300s") != SAFECRT_SUCCESS) - { - va_end(ap); - return -1; - } - } - va_list apcopy; - va_copy(apcopy, ap); - TempInt = InternalVsnprintf(CorUnix::InternalGetCurrentThread(), BufferPtr, TempCount, TempBuff, apcopy); - va_end(apcopy); - PAL_printf_arg_remover(&ap, Width, Precision, Type, Prefix); - } - - if (TempInt < 0 || static_cast<size_t>(TempInt) >= TempCount) /* buffer not long enough */ - { - BufferPtr += TempCount; - BufferRanOut = TRUE; - } - else - { - BufferPtr += TempInt; - } - } - } - else - { - *BufferPtr++ = *Fmt++; /* copy regular chars into buffer */ - } - } - - if (Count > (BufferPtr - Buffer)) - { - *BufferPtr = 0; /* end the string */ - } - - va_end(ap); - - if (BufferRanOut) - { - return -1; - } - else - { - return BufferPtr - Buffer; - } -} - /*++ Function: PAL_vfprintf (silent version) diff --git a/src/pal/src/cruntime/string.cpp b/src/pal/src/cruntime/string.cpp index abe6d136f0..2abce6fd8f 100644 --- a/src/pal/src/cruntime/string.cpp +++ b/src/pal/src/cruntime/string.cpp @@ -278,7 +278,7 @@ PAL_atol(const char *szNumber) PERF_ENTRY(atol); ENTRY("atol (szNumber=%p (%s))\n", - szNumber?szNumber:"NULL" + szNumber, szNumber?szNumber:"NULL" ); lResult = atol(szNumber); diff --git a/src/pal/src/debug/debug.cpp b/src/pal/src/debug/debug.cpp index 2f7d17cabe..2eaaec9f1f 100644 --- a/src/pal/src/debug/debug.cpp +++ b/src/pal/src/debug/debug.cpp @@ -545,254 +545,6 @@ SetThreadContext( /*++ Function: - PAL_CreateExecWatchpoint - -Abstract - Creates an OS exec watchpoint for the specified instruction - and thread. This function should only be called on architectures - that do not support a hardware single-step mode (e.g., SPARC). - -Parameter - hThread : the thread for which the watchpoint is to apply - pvInstruction : the instruction on which the watchpoint is to be set - -Return - A Win32 error code ---*/ - -DWORD -PAL_CreateExecWatchpoint( - HANDLE hThread, - PVOID pvInstruction - ) -{ - PERF_ENTRY(PAL_CreateExecWatchpoint); - ENTRY("PAL_CreateExecWatchpoint (hThread=%p, pvInstruction=%p)\n", hThread, pvInstruction); - - DWORD dwError = ERROR_NOT_SUPPORTED; - -#if HAVE_PRWATCH_T - - CPalThread *pThread = NULL; - CPalThread *pTargetThread = NULL; - IPalObject *pobjThread = NULL; - int fd = -1; - char ctlPath[50]; - - struct - { - long ctlCode; - prwatch_t prwatch; - } ctlStruct; - - // - // We must never set a watchpoint on an instruction that enters a syscall; - // if such a request comes in we succeed it w/o actually creating the - // watchpoint. This mirrors the behavior of setting the single-step flag - // in a thread context when the thread is w/in a system service -- the - // flag is ignored and will not be present when the thread returns - // to user mode. - // - -#if defined(_SPARC_) - if (*(DWORD*)pvInstruction == 0x91d02008) // ta 8 - { - TRACE("Watchpoint requested on sysenter instruction -- ignoring"); - dwError = ERROR_SUCCESS; - goto PAL_CreateExecWatchpointExit; - } -#else -#error Need syscall instruction for this platform -#endif // _SPARC_ - - pThread = InternalGetCurrentThread(); - - dwError = InternalGetThreadDataFromHandle( - pThread, - hThread, - 0, // THREAD_SET_CONTEXT - &pTargetThread, - &pobjThread - ); - - if (NO_ERROR != dwError) - { - goto PAL_CreateExecWatchpointExit; - } - - snprintf(ctlPath, sizeof(ctlPath), "/proc/%u/lwp/%u/lwpctl", getpid(), pTargetThread->GetLwpId()); - - fd = InternalOpen(pThread, ctlPath, O_WRONLY); - if (-1 == fd) - { - ERROR("Failed to open %s\n", ctlPath); - dwError = ERROR_INVALID_ACCESS; - goto PAL_CreateExecWatchpointExit; - } - - ctlStruct.ctlCode = PCWATCH; - ctlStruct.prwatch.pr_vaddr = (uintptr_t) pvInstruction; - ctlStruct.prwatch.pr_size = sizeof(DWORD); - ctlStruct.prwatch.pr_wflags = WA_EXEC | WA_TRAPAFTER; - - if (write(fd, (void*) &ctlStruct, sizeof(ctlStruct)) != sizeof(ctlStruct)) - { - ERROR("Failure writing control structure (errno = %u)\n", errno); - dwError = ERROR_INTERNAL_ERROR; - goto PAL_CreateExecWatchpointExit; - } - - dwError = ERROR_SUCCESS; - -PAL_CreateExecWatchpointExit: - - if (NULL != pobjThread) - { - pobjThread->ReleaseReference(pThread); - } - - if (-1 != fd) - { - close(fd); - } - -#endif // HAVE_PRWATCH_T - - LOGEXIT("PAL_CreateExecWatchpoint returns ret:%d\n", dwError); - PERF_EXIT(PAL_CreateExecWatchpoint); - return dwError; -} - -/*++ -Function: - PAL_DeleteExecWatchpoint - -Abstract - Deletes an OS exec watchpoint for the specified instruction - and thread. This function should only be called on architectures - that do not support a hardware single-step mode (e.g., SPARC). - -Parameter - hThread : the thread to remove the watchpoint from - pvInstruction : the instruction for which the watchpoint is to be removed - -Return - A Win32 error code. Attempting to delete a watchpoint that does not exist - may or may not result in an error, depending on the behavior of the - underlying operating system. ---*/ - -DWORD -PAL_DeleteExecWatchpoint( - HANDLE hThread, - PVOID pvInstruction - ) -{ - PERF_ENTRY(PAL_DeleteExecWatchpoint); - ENTRY("PAL_DeleteExecWatchpoint (hThread=%p, pvInstruction=%p)\n", hThread, pvInstruction); - - DWORD dwError = ERROR_NOT_SUPPORTED; - -#if HAVE_PRWATCH_T - - CPalThread *pThread = NULL; - CPalThread *pTargetThread = NULL; - IPalObject *pobjThread = NULL; - int fd = -1; - char ctlPath[50]; - - struct - { - long ctlCode; - prwatch_t prwatch; - } ctlStruct; - - - pThread = InternalGetCurrentThread(); - - dwError = InternalGetThreadDataFromHandle( - pThread, - hThread, - 0, // THREAD_SET_CONTEXT - &pTargetThread, - &pobjThread - ); - - if (NO_ERROR != dwError) - { - goto PAL_DeleteExecWatchpointExit; - } - - snprintf(ctlPath, sizeof(ctlPath), "/proc/%u/lwp/%u/lwpctl", getpid(), pTargetThread->GetLwpId()); - - fd = InternalOpen(pThread, ctlPath, O_WRONLY); - if (-1 == fd) - { - ERROR("Failed to open %s\n", ctlPath); - dwError = ERROR_INVALID_ACCESS; - goto PAL_DeleteExecWatchpointExit; - } - - ctlStruct.ctlCode = PCWATCH; - ctlStruct.prwatch.pr_vaddr = (uintptr_t) pvInstruction; - ctlStruct.prwatch.pr_size = sizeof(DWORD); - ctlStruct.prwatch.pr_wflags = 0; - - if (write(fd, (void*) &ctlStruct, sizeof(ctlStruct)) != sizeof(ctlStruct)) - { - ERROR("Failure writing control structure (errno = %u)\n", errno); - dwError = ERROR_INTERNAL_ERROR; - goto PAL_DeleteExecWatchpointExit; - } - - dwError = ERROR_SUCCESS; - -PAL_DeleteExecWatchpointExit: - - if (NULL != pobjThread) - { - pobjThread->ReleaseReference(pThread); - } - - if (-1 != fd) - { - close(fd); - } - -#endif // HAVE_PRWATCH_T - - LOGEXIT("PAL_DeleteExecWatchpoint returns ret:%d\n", dwError); - PERF_EXIT(PAL_DeleteExecWatchpoint); - return dwError; -} - -__attribute__((noinline)) -__attribute__((optnone)) -void -ProbeMemory(volatile PBYTE pbBuffer, DWORD cbBuffer, bool fWriteAccess) -{ - // Need an throw in this function to fool the C++ runtime into handling the - // possible h/w exception below. - if (pbBuffer == NULL) - { - throw PAL_SEHException(); - } - - // Simple one byte at a time probing - while (cbBuffer > 0) - { - volatile BYTE read = *pbBuffer; - if (fWriteAccess) - { - *pbBuffer = read; - } - ++pbBuffer; - --cbBuffer; - } -} - -/*++ -Function: PAL_ProbeMemory Abstract @@ -812,18 +564,58 @@ PAL_ProbeMemory( DWORD cbBuffer, BOOL fWriteAccess) { - try - { - // Need to explicit h/w exception holder so to catch them in ProbeMemory - CatchHardwareExceptionHolder __catchHardwareException; + int fds[2]; - ProbeMemory((PBYTE)pBuffer, cbBuffer, fWriteAccess); - } - catch(...) + if (pipe(fds) != 0) { + ASSERT("pipe failed: errno is %d (%s)\n", errno, strerror(errno)); return FALSE; } - return TRUE; + + fcntl(fds[0], O_NONBLOCK); + fcntl(fds[1], O_NONBLOCK); + + PVOID pEnd = (PBYTE)pBuffer + cbBuffer; + BOOL result = TRUE; + + // Validate the first byte in the buffer, then validate the first byte on each page after that. + while (pBuffer < pEnd) + { + int written = write(fds[1], pBuffer, 1); + if (written == -1) + { + if (errno != EFAULT) + { + ASSERT("write failed: errno is %d (%s)\n", errno, strerror(errno)); + } + result = FALSE; + break; + } + else + { + if (fWriteAccess) + { + int rd = read(fds[0], pBuffer, 1); + if (rd == -1) + { + if (errno != EFAULT) + { + ASSERT("read failed: errno is %d (%s)\n", errno, strerror(errno)); + } + result = FALSE; + break; + } + } + } + + // Round to the beginning of the next page + pBuffer = (PVOID)(((SIZE_T)pBuffer & ~VIRTUAL_PAGE_MASK) + VIRTUAL_PAGE_SIZE); + } + + close(fds[0]); + close(fds[1]); + + return result; } } // extern "C" diff --git a/src/pal/src/exception/machexception.h b/src/pal/src/exception/machexception.h index 18e31501b2..e2f8ee7a86 100644 --- a/src/pal/src/exception/machexception.h +++ b/src/pal/src/exception/machexception.h @@ -25,8 +25,6 @@ extern "C" { #endif // __cplusplus -#define HIJACK_ON_SIGNAL 1 - // List of exception types we will be watching for // NOTE: if you change any of these, you need to adapt s_nMachExceptionPortsMax in thread.hpp #define PAL_EXC_ILLEGAL_MASK (EXC_MASK_BAD_INSTRUCTION | EXC_MASK_EMULATION) diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp index fa2f109875..e3fa09f7c8 100644 --- a/src/pal/src/exception/seh-unwind.cpp +++ b/src/pal/src/exception/seh-unwind.cpp @@ -322,14 +322,14 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP if (unw_is_signal_frame(&cursor) > 0) { context->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE; -#if defined(_ARM_) || defined(_ARM64_) +#if defined(_ARM_) || defined(_ARM64_) || defined(_X86_) context->ContextFlags &= ~CONTEXT_UNWOUND_TO_CALL; #endif // _ARM_ || _ARM64_ } else { context->ContextFlags &= ~CONTEXT_EXCEPTION_ACTIVE; -#if defined(_ARM_) || defined(_ARM64_) +#if defined(_ARM_) || defined(_ARM64_) || defined(_X86_) context->ContextFlags |= CONTEXT_UNWOUND_TO_CALL; #endif // _ARM_ || _ARM64_ } diff --git a/src/pal/src/exception/signal.hpp b/src/pal/src/exception/signal.hpp index c0c950ed4d..cd019e676b 100644 --- a/src/pal/src/exception/signal.hpp +++ b/src/pal/src/exception/signal.hpp @@ -46,13 +46,6 @@ Function : --*/ void SEHCleanupSignals(); -#if (__GNUC__ > 3 || \ - (__GNUC__ == 3 && __GNUC_MINOR__ > 2)) -// For gcc > 3.2, sjlj exceptions semantics are no longer available -// Therefore we need to hijack out of signal handlers before second pass -#define HIJACK_ON_SIGNAL 1 -#endif - #endif // !HAVE_MACH_EXCEPTIONS #endif /* _PAL_SIGNAL_HPP_ */ diff --git a/src/pal/src/file/disk.cpp b/src/pal/src/file/disk.cpp index ef1d488b28..08880c9c20 100644 --- a/src/pal/src/file/disk.cpp +++ b/src/pal/src/file/disk.cpp @@ -26,10 +26,7 @@ Revision History: #include "pal/stackstring.hpp" #include <sys/param.h> -#if !defined(_AIX) -// do we actually need this on other platforms. We don't seem to be using anything from there #include <sys/mount.h> -#endif #include <errno.h> #if HAVE_STATVFS #include <sys/types.h> diff --git a/src/pal/src/file/file.cpp b/src/pal/src/file/file.cpp index 6443a5e7b9..d70e62bd52 100644 --- a/src/pal/src/file/file.cpp +++ b/src/pal/src/file/file.cpp @@ -18,6 +18,9 @@ Abstract: --*/ +#include "pal/dbgmsg.h" +SET_DEFAULT_DEBUG_CHANNEL(FILE); // some headers have code with asserts, so do this first + #include "pal/thread.hpp" #include "pal/file.hpp" #include "shmfilelockmgr.hpp" @@ -25,7 +28,6 @@ Abstract: #include "pal/stackstring.hpp" #include "pal/palinternal.h" -#include "pal/dbgmsg.h" #include "pal/file.h" #include "pal/filetime.h" #include "pal/utils.h" @@ -42,8 +44,6 @@ Abstract: using namespace CorUnix; -SET_DEFAULT_DEBUG_CHANNEL(FILE); - int MaxWCharToAcpLengthFactor = 3; PAL_ERROR @@ -3657,12 +3657,9 @@ DWORD FILEGetLastErrorFromErrno( void ) case EEXIST: dwRet = ERROR_ALREADY_EXISTS; break; -#if !defined(_AIX) - // ENOTEMPTY is the same as EEXIST on AIX. Meaningful when involving directory operations case ENOTEMPTY: dwRet = ERROR_DIR_NOT_EMPTY; break; -#endif case EBADF: dwRet = ERROR_INVALID_HANDLE; break; diff --git a/src/pal/src/file/path.cpp b/src/pal/src/file/path.cpp index c4ef31be32..d998b72b2e 100644 --- a/src/pal/src/file/path.cpp +++ b/src/pal/src/file/path.cpp @@ -494,8 +494,8 @@ GetTempPathA( } else /* env var not found or was empty */ { - /* no luck, use /tmp/ */ - const char *defaultDir = "/tmp/"; + /* no luck, use /tmp/ or /data/local/tmp on Android */ + const char *defaultDir = TEMP_DIRECTORY_PATH; int defaultDirLen = strlen(defaultDir); if (defaultDirLen < nBufferLength) { diff --git a/src/pal/src/include/pal/modulename.h b/src/pal/src/include/pal/modulename.h index 70b0a610dc..20001f8797 100644 --- a/src/pal/src/include/pal/modulename.h +++ b/src/pal/src/include/pal/modulename.h @@ -28,9 +28,6 @@ extern "C" #endif // __cplusplus const char *PAL_dladdr(LPVOID ProcAddress); -#if defined(_AIX) -int GetLibRotorNameViaLoadQuery(LPSTR pszBuf); -#endif #ifdef __cplusplus } diff --git a/src/pal/src/include/pal/palinternal.h b/src/pal/src/include/pal/palinternal.h index f7856be902..48e2f3c683 100644 --- a/src/pal/src/include/pal/palinternal.h +++ b/src/pal/src/include/pal/palinternal.h @@ -335,7 +335,7 @@ function_name() to call the system's implementation #undef va_arg #endif -#if !defined(_MSC_VER) && defined(FEATURE_PAL) && defined(_WIN64) +#if !defined(_MSC_VER) && defined(_WIN64) #undef _BitScanForward64 #endif @@ -358,6 +358,7 @@ function_name() to call the system's implementation #undef memchr #undef strlen #undef strnlen +#undef wcsnlen #undef stricmp #undef strstr #undef strcmp @@ -502,7 +503,6 @@ function_name() to call the system's implementation #undef vfwprintf #undef vprintf #undef wprintf -#undef swprintf #undef wcstod #undef wcstol #undef wcstoul @@ -525,10 +525,6 @@ function_name() to call the system's implementation #undef iswspace #undef towlower #undef towupper -#undef vsprintf -#undef vswprintf -#undef _vsnprintf -#undef vsnprintf #undef wvsnprintf #ifdef _AMD64_ @@ -606,15 +602,19 @@ function_name() to call the system's implementation #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 +#ifndef __ANDROID__ +#define TEMP_DIRECTORY_PATH "/tmp/" +#else +// On Android, "/tmp/" doesn't exist; temporary files should go to +// /data/local/tmp/ +#define TEMP_DIRECTORY_PATH "/data/local/tmp/" +#endif + #define PROCESS_PIPE_NAME_PREFIX ".dotnet-pal-processpipe" #ifdef __cplusplus diff --git a/src/pal/src/include/pal/printfcpp.hpp b/src/pal/src/include/pal/printfcpp.hpp index 0a728c9fd7..12e923a506 100644 --- a/src/pal/src/include/pal/printfcpp.hpp +++ b/src/pal/src/include/pal/printfcpp.hpp @@ -32,22 +32,6 @@ typedef char16_t wchar_16; // __wchar_16_cpp (which is defined in palinternal.h) extern "C" { int - __cdecl - PAL__vsnprintf( - LPSTR Buffer, - size_t Count, - LPCSTR Format, - va_list ap); - - int - __cdecl - PAL__wvsnprintf( - LPWSTR Buffer, - size_t Count, - LPCWSTR Format, - va_list ap); - - int __cdecl PAL_vfprintf( PAL_FILE *stream, @@ -71,48 +55,9 @@ namespace CorUnix const char *format, va_list ap); - int - InternalWvsnprintf( - CPalThread *pthrCurrent, - LPWSTR Buffer, - size_t Count, - LPCWSTR Format, - va_list ap); - - int - InternalVsnprintf( - CPalThread *pthrCurrent, - LPSTR Buffer, - size_t Count, - LPCSTR Format, - va_list ap); - - int - InternalVfwprintf( - CPalThread *pthrCurrent, - PAL_FILE *stream, - const wchar_16 *format, - va_list ap); - } #else // __cplusplus - int - __cdecl - PAL__vsnprintf( - LPSTR Buffer, - size_t Count, - LPCSTR Format, - va_list ap); - - int - __cdecl - PAL__wvsnprintf( - LPWSTR Buffer, - size_t Count, - LPCWSTR Format, - va_list ap); - int __cdecl PAL_vfprintf( diff --git a/src/pal/src/include/pal/sharedmemory.h b/src/pal/src/include/pal/sharedmemory.h index 45cc4b2c8d..2e0d9d2a79 100644 --- a/src/pal/src/include/pal/sharedmemory.h +++ b/src/pal/src/include/pal/sharedmemory.h @@ -15,30 +15,33 @@ #define _countof(a) (sizeof(a) / sizeof(a[0])) #endif // !_countof +// The temporary folder is used for storing shared memory files and their lock files. +// The location of the temporary folder varies (e.g. /data/local/tmp on Android) +// and is set in TEMP_DIRECTORY_PATH. TEMP_DIRECTORY_PATH ends with '/' // - Global shared memory files go in: -// /tmp/.dotnet/shm/global/<fileName> +// {tmp}/.dotnet/shm/global/<fileName> // - Session-scoped shared memory files go in: -// /tmp/.dotnet/shm/session<sessionId>/<fileName> +// {tmp}/.dotnet/shm/session<sessionId>/<fileName> // - Lock files associated with global shared memory files go in: -// /tmp/.dotnet/lockfiles/global/<fileName> +// {tmp}/.dotnet/lockfiles/global/<fileName> // - Lock files associated with session-scoped shared memory files go in: -// /tmp/.dotnet/lockfiles/session<sessionId>/<fileName> +// {tmp}/.dotnet/lockfiles/session<sessionId>/<fileName> #define SHARED_MEMORY_MAX_FILE_NAME_CHAR_COUNT (_MAX_FNAME - 1) #define SHARED_MEMORY_MAX_NAME_CHAR_COUNT (_countof("Global\\") - 1 + SHARED_MEMORY_MAX_FILE_NAME_CHAR_COUNT) -#define SHARED_MEMORY_TEMP_DIRECTORY_PATH "/tmp" -#define SHARED_MEMORY_RUNTIME_TEMP_DIRECTORY_PATH "/tmp/.dotnet" +#define SHARED_MEMORY_TEMP_DIRECTORY_PATH TEMP_DIRECTORY_PATH +#define SHARED_MEMORY_RUNTIME_TEMP_DIRECTORY_PATH TEMP_DIRECTORY_PATH ".dotnet" -#define SHARED_MEMORY_SHARED_MEMORY_DIRECTORY_PATH "/tmp/.dotnet/shm" -#define SHARED_MEMORY_LOCK_FILES_DIRECTORY_PATH "/tmp/.dotnet/lockfiles" +#define SHARED_MEMORY_SHARED_MEMORY_DIRECTORY_PATH TEMP_DIRECTORY_PATH ".dotnet/shm" +#define SHARED_MEMORY_LOCK_FILES_DIRECTORY_PATH TEMP_DIRECTORY_PATH ".dotnet/lockfiles" static_assert_no_msg(_countof(SHARED_MEMORY_LOCK_FILES_DIRECTORY_PATH) >= _countof(SHARED_MEMORY_SHARED_MEMORY_DIRECTORY_PATH)); #define SHARED_MEMORY_GLOBAL_DIRECTORY_NAME "global" #define SHARED_MEMORY_SESSION_DIRECTORY_NAME_PREFIX "session" static_assert_no_msg(_countof(SHARED_MEMORY_SESSION_DIRECTORY_NAME_PREFIX) >= _countof(SHARED_MEMORY_GLOBAL_DIRECTORY_NAME)); -#define SHARED_MEMORY_UNIQUE_TEMP_NAME_TEMPLATE "/tmp/.coreclr.XXXXXX" +#define SHARED_MEMORY_UNIQUE_TEMP_NAME_TEMPLATE TEMP_DIRECTORY_PATH ".coreclr.XXXXXX" #define SHARED_MEMORY_MAX_SESSION_ID_CHAR_COUNT (10) diff --git a/src/pal/src/include/pal/thread.hpp b/src/pal/src/include/pal/thread.hpp index e6dacd2136..ddacfb9039 100644 --- a/src/pal/src/include/pal/thread.hpp +++ b/src/pal/src/include/pal/thread.hpp @@ -94,11 +94,6 @@ namespace CorUnix ); PAL_ERROR - InitializeGlobalThreadData( - void - ); - - PAL_ERROR CreateThreadData( CPalThread **ppThread ); @@ -243,12 +238,6 @@ namespace CorUnix friend PAL_ERROR - InitializeGlobalThreadData( - void - ); - - friend - PAL_ERROR CreateThreadData( CPalThread **ppThread ); @@ -338,13 +327,6 @@ namespace CorUnix // Limit address of the stack of this thread void* m_stackLimit; - // The default stack size of a newly created thread (currently 256KB) - // when the dwStackSize paramter of PAL_CreateThread() - // is zero. This value can be set by setting the - // environment variable PAL_THREAD_DEFAULT_STACK_SIZE - // (the value should be in bytes and in hex). - static DWORD s_dwDefaultThreadStackSize; - // // The thread entry routine (called from InternalCreateThread) // diff --git a/src/pal/src/include/pal/threadsusp.hpp b/src/pal/src/include/pal/threadsusp.hpp index e1e85e265c..dfd65d0f8b 100644 --- a/src/pal/src/include/pal/threadsusp.hpp +++ b/src/pal/src/include/pal/threadsusp.hpp @@ -55,6 +55,8 @@ Abstract: #if HAVE_SYS_SEMAPHORE_H #include <sys/semaphore.h> +#elif HAVE_SEMAPHORE_H +#include <semaphore.h> #endif // HAVE_SYS_SEMAPHORE_H #elif HAS_PTHREAD_MUTEXES && HAVE_MACH_EXCEPTIONS diff --git a/src/pal/src/include/pal/utils.h b/src/pal/src/include/pal/utils.h index 3ddad4ae2f..f381d957ab 100644 --- a/src/pal/src/include/pal/utils.h +++ b/src/pal/src/include/pal/utils.h @@ -20,10 +20,66 @@ Abstract: #ifndef _PAL_UTILS_H_ #define _PAL_UTILS_H_ +#include <stdint.h> + #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Alignment helpers (copied for PAL use from stdmacros.h) + +inline size_t ALIGN_UP(size_t val, size_t alignment) +{ + // alignment must be a power of 2 for this implementation to work (need modulo otherwise) + _ASSERTE(0 == (alignment & (alignment - 1))); + size_t result = (val + (alignment - 1)) & ~(alignment - 1); + _ASSERTE(result >= val); // check for overflow + return result; +} + +inline void* ALIGN_UP(void* val, size_t alignment) +{ + return (void*)ALIGN_UP((size_t)val, alignment); +} + +inline uint8_t* ALIGN_UP(uint8_t* val, size_t alignment) +{ + return (uint8_t*)ALIGN_UP((size_t)val, alignment); +} + +inline size_t ALIGN_DOWN(size_t val, size_t alignment) +{ + // alignment must be a power of 2 for this implementation to work (need modulo otherwise) + _ASSERTE(0 == (alignment & (alignment - 1))); + size_t result = val & ~(alignment - 1); + return result; +} + +inline void* ALIGN_DOWN(void* val, size_t alignment) +{ + return (void*)ALIGN_DOWN((size_t)val, alignment); +} + +inline uint8_t* ALIGN_DOWN(uint8_t* val, size_t alignment) +{ + return (uint8_t*)ALIGN_DOWN((size_t)val, alignment); +} + +inline BOOL IS_ALIGNED(size_t val, size_t alignment) +{ + // alignment must be a power of 2 for this implementation to work (need modulo otherwise) + _ASSERTE(0 == (alignment & (alignment - 1))); + return 0 == (val & (alignment - 1)); +} + +inline BOOL IS_ALIGNED(const void* val, size_t alignment) +{ + return IS_ALIGNED((size_t)val, alignment); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + #ifdef __cplusplus extern "C" { diff --git a/src/pal/src/include/pal/virtual.h b/src/pal/src/include/pal/virtual.h index a4e225281e..31d225fc04 100644 --- a/src/pal/src/include/pal/virtual.h +++ b/src/pal/src/include/pal/virtual.h @@ -58,12 +58,7 @@ enum VIRTUAL_CONSTANTS VIRTUAL_EXECUTE, VIRTUAL_EXECUTE_READ, - /* Page manipulation constants. */ -#ifdef __sparc__ - VIRTUAL_PAGE_SIZE = 0x2000, -#else // __sparc__ VIRTUAL_PAGE_SIZE = 0x1000, -#endif // __sparc__ VIRTUAL_PAGE_MASK = VIRTUAL_PAGE_SIZE - 1, BOUNDARY_64K = 0xffff }; diff --git a/src/pal/src/init/pal.cpp b/src/pal/src/init/pal.cpp index 0bda27644e..e6db7dca2e 100644 --- a/src/pal/src/init/pal.cpp +++ b/src/pal/src/init/pal.cpp @@ -18,6 +18,9 @@ Abstract: --*/ +#include "pal/dbgmsg.h" +SET_DEFAULT_DEBUG_CHANNEL(PAL); // some headers have code with asserts, so do this first + #include "pal/thread.hpp" #include "pal/synchobjects.hpp" #include "pal/procobj.hpp" @@ -27,7 +30,6 @@ Abstract: #include "../objmgr/shmobjectmanager.hpp" #include "pal/seh.hpp" #include "pal/palinternal.h" -#include "pal/dbgmsg.h" #include "pal/sharedmemory.h" #include "pal/shmemory.h" #include "pal/process.h" @@ -90,8 +92,6 @@ using namespace CorUnix; extern "C" BOOL CRTInitStdStreams( void ); -SET_DEFAULT_DEBUG_CHANNEL(PAL); - Volatile<INT> init_count = 0; Volatile<BOOL> shutdown_intent = 0; Volatile<LONG> g_coreclrInitialized = 0; @@ -314,17 +314,6 @@ Initialize( #endif // HAVE_MACH_EXCEPTIONS // - // Initialize global thread data - // - - palError = InitializeGlobalThreadData(); - if (NO_ERROR != palError) - { - ERROR("Unable to initialize thread data\n"); - goto CLEANUP1; - } - - // // Allocate the initial thread data // diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp index a4fc4949e4..63a65ffb61 100644 --- a/src/pal/src/loader/module.cpp +++ b/src/pal/src/loader/module.cpp @@ -18,11 +18,13 @@ Abstract: --*/ +#include "pal/dbgmsg.h" +SET_DEFAULT_DEBUG_CHANNEL(LOADER); // some headers have code with asserts, so do this first + #include "pal/thread.hpp" #include "pal/malloc.hpp" #include "pal/file.hpp" #include "pal/palinternal.h" -#include "pal/dbgmsg.h" #include "pal/module.h" #include "pal/cs.hpp" #include "pal/process.h" @@ -60,8 +62,6 @@ Abstract: using namespace CorUnix; -SET_DEFAULT_DEBUG_CHANNEL(LOADER); - // In safemath.h, Template SafeInt uses macro _ASSERTE, which need to use variable // defdbgchan defined by SET_DEFAULT_DEBUG_CHANNEL. Therefore, the include statement // should be placed after the SET_DEFAULT_DEBUG_CHANNEL(LOADER) diff --git a/src/pal/src/loader/modulename.cpp b/src/pal/src/loader/modulename.cpp index 026f89b3ea..87c1b026c2 100644 --- a/src/pal/src/loader/modulename.cpp +++ b/src/pal/src/loader/modulename.cpp @@ -30,118 +30,10 @@ Abstract: #include <dlfcn.h> #endif // NEED_DLCOMPAT -#if defined(_AIX) -#include <sys/ldr.h> -#endif - using namespace CorUnix; SET_DEFAULT_DEBUG_CHANNEL(LOADER); -#if defined(_AIX) -/*++ - GetLibRotorNameViaLoadQuery - - Retrieve the full path of the librotor_pal.so using loadquery() - -Parameters: - pszBuf - CHAR array of MAX_PATH_FNAME length - -Return value: - 0 on success - -1 on failure, with last error set ---*/ -int GetLibRotorNameViaLoadQuery(LPSTR pszBuf) -{ - CHAR* pLoadQueryBuf = NULL; - UINT cbBuf = 1024; - struct ld_info * pInfo = NULL; - INT iLQRetVal = -1; - INT iRetVal = -1; - CPalThread *pThread = NULL; - - if (!pszBuf) - { - ASSERT("GetLibRotorNameViaLoadQuery requires non-NULL pszBuf\n"); - SetLastError(ERROR_INTERNAL_ERROR); - goto Done; - } - - pThread = InternalGetCurrentThread(); - // Loop trying to call loadquery with enough memory until either - // 1) we succeed, 2) we run out of memory or 3) loadquery throws - // an error other than ENOMEM - while (iLQRetVal != 0) - { - pLoadQueryBuf = (CHAR*) InternalMalloc (pThread, cbBuf * sizeof(char)); - if (!pLoadQueryBuf) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Done; - } - iLQRetVal = loadquery(L_GETINFO, pLoadQueryBuf, cbBuf); - if (iLQRetVal < 0) - { - free(pThread, pLoadQueryBuf); - pLoadQueryBuf = NULL; - DWORD dwLastError = GetLastError(); - if (dwLastError == ERROR_NOT_ENOUGH_MEMORY) - { - // The buffer's too small. Try twice as large as a guess... - cbBuf *= 2; - } - else - { - SetLastError(ERROR_INTERNAL_ERROR); - goto Done; - } - } - } - - // We successfully called loadquery, so now see if we can find - // librotor_pal.a in the module list - if (pLoadQueryBuf) - { - pInfo = (struct ld_info *)pLoadQueryBuf; - while (TRUE) - { - if (strstr(pInfo->ldinfo_filename, "librotor_pal.a")) - { - UINT cchFileName = strlen(pInfo->ldinfo_filename); - if (cchFileName + 1 > MAX_PATH_FNAME) - { - ASSERT("Filename returned by loadquery was longer than MAX_PATH_FNAME!\n"); - SetLastError(ERROR_INTERNAL_ERROR); - goto Done; - } - else - { - // The buffer should be large enough to accomodate the filename. - // So, we send in the size of the filename+1 - strcpy_s(pszBuf, MAX_PATH_FNAME, pInfo->ldinfo_filename); - iRetVal = 0; - goto Done; - } - } - else - { - // The (wacky) design of ld_info is that the value of next is an offset in - // bytes rather than a pointer. So we need this weird cast to char * to get - // the pointer math correct. - if (pInfo->ldinfo_next == 0) - break; - else - pInfo = (struct ld_info *) ((char *)pInfo + pInfo->ldinfo_next); - } - } - } -Done: - if (pLoadQueryBuf) - free(pThread, pLoadQueryBuf); - return iRetVal; -} -#endif // defined(_AIX) - /*++ PAL_dladdr @@ -165,31 +57,6 @@ Notes: --*/ const char *PAL_dladdr(LPVOID ProcAddress) { -#if defined(_AIX) || defined(__hppa__) - /* dladdr is not supported on AIX or 32-bit HPUX-PARISC */ - return (NULL); -#elif defined(_HPUX_) && defined(_IA64_) - /* dladdr is not supported on HP-UX/IA64. That said, PAL_dladdr just returns to module name - and we can get that via dlgetname. So use that for HPUX. */ - { - char* pszName = NULL; - load_module_desc desc; - __uint64_t uimodret = NULL; - uimodret = dlmodinfo((__uint64_t)ProcAddress, &desc, sizeof(desc), NULL, 0, 0); - if (!uimodret) - { - WARN("dlmodinfo call failed! dlerror says '%s'\n", dlerror()); - return NULL; - } - pszName = dlgetname(&desc, sizeof(desc), NULL, 0, 0); - if (!pszName) - { - WARN("dlgetname desc didn't describe a loaded module?! dlerror says '%s'\n", dlerror()); - return NULL; - } - return pszName; - } -#else Dl_info dl_info; if (!dladdr(ProcAddress, &dl_info)) { @@ -202,6 +69,5 @@ const char *PAL_dladdr(LPVOID ProcAddress) /* Return the module name */ return dl_info.dli_fname; } -#endif } diff --git a/src/pal/src/misc/dbgmsg.cpp b/src/pal/src/misc/dbgmsg.cpp index 488e61494e..d6f173f160 100644 --- a/src/pal/src/misc/dbgmsg.cpp +++ b/src/pal/src/misc/dbgmsg.cpp @@ -528,8 +528,8 @@ int DBG_printf_gcc(DBG_CHANNEL_ID channel, DBG_LEVEL_ID level, BOOL bHeader, va_start(args, format); - output_size+=Silent_PAL_vsnprintf(buffer_ptr, DBG_BUFFER_SIZE-output_size, - format, args); + output_size+=_vsnprintf_s(buffer_ptr, DBG_BUFFER_SIZE-output_size, _TRUNCATE, + format, args); va_end(args); if( output_size > DBG_BUFFER_SIZE ) @@ -633,8 +633,8 @@ int DBG_printf_c99(DBG_CHANNEL_ID channel, DBG_LEVEL_ID level, BOOL bHeader, } va_start(args, format); - output_size+=Silent_PAL_vsnprintf(buffer_ptr, DBG_BUFFER_SIZE-output_size, - format, args); + output_size+=_vsnprintf_s(buffer_ptr, DBG_BUFFER_SIZE-output_size, _TRUNCATE, + format, args); va_end(args); if(output_size>DBG_BUFFER_SIZE) @@ -960,7 +960,7 @@ void PAL_DisplayDialogFormatted(const char *szTitle, const char *szTextFormat, . const int cchBuffer = 4096; char *szBuffer = (char*)alloca(cchBuffer); - PAL__vsnprintf(szBuffer, cchBuffer, szTextFormat, args); + _vsnprintf_s(szBuffer, cchBuffer, _TRUNCATE, szTextFormat, args); PAL_DisplayDialog(szTitle, szBuffer); va_end(args); diff --git a/src/pal/src/misc/fmtmessage.cpp b/src/pal/src/misc/fmtmessage.cpp index 46e0af6e0d..70b854aa9c 100644 --- a/src/pal/src/misc/fmtmessage.cpp +++ b/src/pal/src/misc/fmtmessage.cpp @@ -205,7 +205,7 @@ static LPWSTR FMTMSG_ProcessPrintf( wchar_t c , UINT nFormatLength = 0; int nBufferLength = 0; - TRACE( "FMTMSG_ProcessPrintf( %C, %S, %S )\n", c, + TRACE( "FMTMSG_ProcessPrintf( %C, %S, %p )\n", c, lpPrintfString, lpInsertString ); switch ( c ) @@ -299,7 +299,6 @@ FormatMessageW( LPWSTR lpReturnString = NULL; LPWSTR lpWorkingString = NULL; - PERF_ENTRY(FormatMessageW); ENTRY( "FormatMessageW(dwFlags=%#x, lpSource=%p, dwMessageId=%#x, " "dwLanguageId=%#x, lpBuffer=%p, nSize=%u, va_list=%p)\n", diff --git a/src/pal/src/misc/perftrace.cpp b/src/pal/src/misc/perftrace.cpp index d4fba3367a..fdefdf6694 100644 --- a/src/pal/src/misc/perftrace.cpp +++ b/src/pal/src/misc/perftrace.cpp @@ -23,26 +23,6 @@ Abstract: #ifdef PAL_PERF -#ifndef PLATFORM_UNIX -/* PAL Headers */ -#include "perftrace.h" - -/* Standard Headers */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#define snprintf _snprintf -#define MiscGetenv getenv -#define pthread_getspecific TlsGetValue -#define THREADSilentGetCurrentThreadId GetCurrentThreadId -#define getpid GetCurrentProcessId -#define PAL_fgets fgets // on Windows, we want fgets. -#define PAL_fwrite fwrite // on Windows, we want fwrite. -#define PAL_fseek fseek // on Windows, we want fseek. - -#else /* PAL Headers */ #include "pal/palinternal.h" #include "pal/perftrace.h" @@ -60,7 +40,6 @@ Abstract: #include <unistd.h> SET_DEFAULT_DEBUG_CHANNEL(MISC); -#endif //End of PLATFORM_UNIX #define PAL_PERF_MAX_LOGLINE 0x400 /* 1K */ @@ -110,21 +89,12 @@ typedef struct _pal_perf_program_info ULONGLONG total_duration; /* Total CPU clock ticks of all the threads */ ULONGLONG pal_duration; /* Total CPU clock ticks spent inside PAL */ -#ifndef PLATFORM_UNIX - DWORD process_id; -#else pid_t process_id; -#endif char start_time[32]; /* must be at least 26 characters */ } pal_perf_program_info; -#ifndef PLATFORM_UNIX -typedef FILE PERF_FILE; -#define PERF_FILEFN(x) x -#else typedef PAL_FILE PERF_FILE; #define PERF_FILEFN(x) PAL_ ## x -#endif static ULONGLONG PERFGetTicks(); static double PERFComputeStandardDeviation(pal_perf_api_info *api); @@ -144,11 +114,7 @@ typedef char PAL_API_NAME[PAL_PERF_MAX_FUNCTION_NAME]; static PAL_API_NAME API_list[PAL_API_NUMBER] ; static pal_perf_program_info program_info; -#ifndef PLATFORM_UNIX -static DWORD PERF_tlsTableKey=0 ; -#else static pthread_key_t PERF_tlsTableKey=0 ; -#endif static pal_thread_list_node * process_pal_thread_list=NULL; static BOOL pal_profile_on=FALSE; @@ -199,19 +165,11 @@ static const char PAL_PERF_HISTOGRAM_SIZE[]="PAL_PERF_HISTOGRAM_SIZE"; static const char PAL_PERF_HISTOGRAM_STEP[]="PAL_PERF_HISTOGRAM_STEP"; static const char traced_apis_filename[]="PerfTracedAPIs.txt"; static const char perf_enabled_filename[]="AllPerfEnabledAPIs.txt"; -#ifndef PLATFORM_UNIX -static const char PATH_SEPARATOR[] = "\\"; -#else static const char PATH_SEPARATOR[] = "/"; -#endif -#ifndef PLATFORM_UNIX -#define LLFORMAT "%I64u" -#else #define LLFORMAT "%llu" -#endif static ULONGLONG @@ -231,11 +189,7 @@ PERFGetTicks(){ #endif return ((ULONGLONG)((unsigned int)(d)) << 32) | (unsigned int)(a); #else -#ifdef __sparc__ - return (ULONGLONG)gethrtime(); -#else return 0; // on non-BSD and non-Windows, we'll return 0 for now. -#endif // __sparc__ #endif // _X86_ } @@ -283,11 +237,7 @@ BOOL PERFInitProgramInfo(LPWSTR command_line, LPWSTR exe_path) { ULONGLONG start_tick; -#ifndef PLATFORM_UNIX - time_t tv; -#else struct timeval tv; -#endif if (WideCharToMultiByte(CP_ACP, 0, command_line, -1, program_info.command_line, PAL_PERF_MAX_LOGLINE-1, NULL, NULL) == 0) @@ -299,23 +249,14 @@ PERFInitProgramInfo(LPWSTR command_line, LPWSTR exe_path) gethostname(program_info.hostname, PAL_PERF_MAX_FUNCTION_NAME); program_info.process_id = getpid(); -#ifndef PLATFORM_UNIX - time( &tv ); - strcpy(program_info.start_time, ctime( &tv )); -#else gettimeofday(&tv, NULL); ctime_r(&tv.tv_sec, program_info.start_time); -#endif // estimate the cpu clock cycles start_tick = PERFGetTicks(); if (start_tick != 0) { -#ifndef PLATFORM_UNIX - Sleep(1000); //Sleep on Windows takes milliseconds as argument -#else sleep(1); -#endif program_info.cpu_clock_frequency = (double) (PERFGetTicks() - start_tick); } else @@ -379,13 +320,8 @@ PERFInitialize(LPWSTR command_line, LPWSTR exe_path) pal_profile_on = FALSE; // turn it off until we setup everything. // allocate the TLS index for structures -#ifndef PLATFORM_UNIX - if( ( PERF_tlsTableKey = TlsAlloc() ) == -1 ) - ret = FALSE; -#else if( pthread_key_create(&PERF_tlsTableKey , NULL) != 0 ) ret = FALSE; -#endif if( ret == TRUE ) { @@ -399,11 +335,7 @@ PERFInitialize(LPWSTR command_line, LPWSTR exe_path) else { -#ifndef PLATFORM_UNIX - TlsFree(PERF_tlsTableKey ); -#else pthread_key_delete(PERF_tlsTableKey ); -#endif ret = FALSE; } } @@ -426,11 +358,7 @@ void PERFTerminate( ) return; PERFlushAllLogs(); -#ifndef PLATFORM_UNIX - TlsFree(PERF_tlsTableKey ); -#else - pthread_key_delete(PERF_tlsTableKey ); -#endif + pthread_key_delete(PERF_tlsTableKey ); PAL_free(pal_function_map); } @@ -516,13 +444,8 @@ BOOL PERFAllocThreadInfo( ) local_info->start_ticks = 0; memset(log_buf, 0, PAL_PERF_PROFILE_BUFFER_SIZE); -#ifndef PLATFORM_UNIX - if ( TlsSetValue(PERF_tlsTableKey, local_info) == 0) - ret = FALSE; -#else if (pthread_setspecific(PERF_tlsTableKey, local_info) != 0) ret = FALSE; -#endif PERFAllocThreadInfoExit: if (ret == TRUE) @@ -799,11 +722,7 @@ PERFReadSetting( ) char * pal_perf_histogram_size_env; char * pal_perf_histogram_step_env; -#ifdef PLATFORM_UNIX PAL_FILE * hFile; -#else - FILE * hFile; -#endif if((pal_function_map == NULL) || (PAL_API_NUMBER < 0) ) { @@ -936,11 +855,7 @@ PERFReadSetting( ) if(input_file_name) { -#ifdef PLATFORM_UNIX hFile = PAL_fopen(input_file_name, "r+"); -#else - hFile = fopen(input_file_name, "r+"); -#endif if ( hFile == NULL ) { memset(pal_function_map, 1, PAL_API_NUMBER); @@ -979,11 +894,7 @@ PERFReadSetting( ) } -#ifdef PLATFORM_UNIX PAL_fclose(hFile); -#else - fclose(hFile); -#endif ret = TRUE; } } @@ -1031,11 +942,7 @@ PERFReadSetting( ) return ret; } -#ifdef PLATFORM_UNIX hFile = PAL_fopen(input_file_name, "r+"); -#else - hFile = fopen(input_file_name, "r+"); -#endif if ( hFile != NULL ) { @@ -1065,11 +972,7 @@ PERFReadSetting( ) } } -#ifdef PLATFORM_UNIX PAL_fclose(hFile); -#else - fclose(hFile); -#endif } return ret; @@ -1126,13 +1029,7 @@ PERFLogFunctionEntry(unsigned int pal_api_id, ULONGLONG *pal_perf_start_tick ) short bufused = 0; -#ifndef PLATFORM_UNIX - DWORD tv; - DWORD last_error; - last_error = GetLastError(); -#else struct timeval tv; -#endif if(!pal_perf_enabled || pal_function_map==NULL || !pal_profile_on ) // haven't initialize, just quit. @@ -1163,28 +1060,17 @@ PERFLogFunctionEntry(unsigned int pal_api_id, ULONGLONG *pal_perf_start_tick ) PERFFlushLog(local_info, FALSE); } -#ifndef PLATFORM_UNIX - tv = GetTickCount(); -#else gettimeofday(&tv, NULL); -#endif buf_off = local_info->buf_offset; -#ifndef PLATFORM_UNIX - bufused = snprintf(&write_buf[buf_off], PAL_PERF_MAX_LOGLINE, "----> %d %lu entry.\n", pal_api_id, tv ); -#else bufused = snprintf(&write_buf[buf_off], PAL_PERF_MAX_LOGLINE, "----> %d %lu %06u entry.\n", pal_api_id, tv.tv_sec, tv.tv_usec ); -#endif local_info->buf_offset += bufused; } if(nested_tracing) local_info->profile_enabled = TRUE; *pal_perf_start_tick = PERFGetTicks(); } -#ifndef PLATFORM_UNIX - SetLastError( last_error ); -#endif return; } @@ -1223,14 +1109,8 @@ PERFLogFunctionExit(unsigned int pal_api_id, ULONGLONG *pal_perf_start_tick ) short bufused = 0; DWORD off; ULONGLONG duration = 0; -#ifndef PLATFORM_UNIX - DWORD timev; - DWORD last_error; - last_error = GetLastError(); -#else struct timeval timev; -#endif if(!pal_perf_enabled || (pal_function_map == NULL) || !pal_profile_on ) // haven't initiallize yet, just quit. return; @@ -1257,17 +1137,10 @@ PERFLogFunctionExit(unsigned int pal_api_id, ULONGLONG *pal_perf_start_tick ) if(summary_only) { local_info->profile_enabled = TRUE; -#ifndef PLATFORM_UNIX - SetLastError( last_error ); -#endif return; } -#ifndef PLATFORM_UNIX - timev = GetTickCount(); -#else gettimeofday(&timev, NULL); -#endif buf = local_info->pal_write_buf; if(local_info->buf_offset >= PAL_PERF_BUFFER_FULL) @@ -1276,17 +1149,10 @@ PERFLogFunctionExit(unsigned int pal_api_id, ULONGLONG *pal_perf_start_tick ) } off = local_info->buf_offset; -#ifndef PLATFORM_UNIX - bufused = snprintf(&buf[off], PAL_PERF_MAX_LOGLINE, "<---- %d %lu exit. \n", pal_api_id, timev); -#else bufused = snprintf(&buf[off], PAL_PERF_MAX_LOGLINE, "<---- %d %lu %06u exit. \n", pal_api_id, timev.tv_sec, timev.tv_usec ); -#endif local_info->buf_offset += bufused; local_info->profile_enabled = TRUE; } -#ifndef PLATFORM_UNIX - SetLastError( last_error ); -#endif return; } @@ -1295,10 +1161,6 @@ PERFNoLatencyProfileEntry(unsigned int pal_api_id ) { pal_perf_thread_info * local_info=NULL; pal_perf_api_info * table; -#ifndef PLATFORM_UNIX - DWORD last_error; - last_error = GetLastError(); -#endif if(!pal_perf_enabled || pal_function_map==NULL || !pal_profile_on ) // haven't initialize, just quit. return; @@ -1307,9 +1169,6 @@ PERFNoLatencyProfileEntry(unsigned int pal_api_id ) local_info= (pal_perf_thread_info * )pthread_getspecific(PERF_tlsTableKey); if (local_info==NULL ) { -#ifndef PLATFORM_UNIX - SetLastError( last_error ); -#endif return; } else{ @@ -1317,9 +1176,6 @@ PERFNoLatencyProfileEntry(unsigned int pal_api_id ) table[pal_api_id].entries++; } } -#ifndef PLATFORM_UNIX - SetLastError( last_error ); -#endif return; } @@ -1328,10 +1184,6 @@ void PERFEnableThreadProfile(BOOL isInternal) { pal_perf_thread_info * local_info; -#ifndef PLATFORM_UNIX - DWORD last_error; - last_error = GetLastError(); -#endif if (!pal_perf_enabled) return; if (NULL != (local_info = (pal_perf_thread_info*)pthread_getspecific(PERF_tlsTableKey))) @@ -1341,9 +1193,6 @@ PERFEnableThreadProfile(BOOL isInternal) local_info->start_ticks = PERFGetTicks(); } } -#ifndef PLATFORM_UNIX - SetLastError( last_error ); -#endif } @@ -1351,10 +1200,6 @@ void PERFDisableThreadProfile(BOOL isInternal) { pal_perf_thread_info * local_info; -#ifndef PLATFORM_UNIX - DWORD last_error; - last_error = GetLastError(); -#endif if (!pal_perf_enabled) return; if (NULL != (local_info = (pal_perf_thread_info*)pthread_getspecific(PERF_tlsTableKey))) @@ -1364,9 +1209,6 @@ PERFDisableThreadProfile(BOOL isInternal) local_info->total_duration = PERFGetTicks() - local_info->start_ticks; } } -#ifndef PLATFORM_UNIX - SetLastError( last_error ); -#endif } @@ -1406,29 +1248,17 @@ static char * PERFIsValidPath( const char * path ) { -#ifndef PLATFORM_UNIX - DWORD result; -#else DIR * dir; -#endif if(( path==NULL) || (strlen(path)==0)) return NULL; -#ifndef PLATFORM_UNIX - result = GetFileAttributesA( path ); - if ((result != INVALID_FILE_ATTRIBUTES) && (result & FILE_ATTRIBUTE_DIRECTORY)) - { - return ((char *) path ); - } -#else dir = opendir(path); if( dir!=NULL) { closedir(dir); return ((char *)path); } -#endif return NULL; } @@ -1508,13 +1338,6 @@ PAL_GetCpuTickCount(VOID) return PERFGetTicks(); } -#ifndef PLATFORM_UNIX -#undef snprintf -#undef MiscGetenv -#undef pthread_key_t -#undef pthread_getspecific -#endif /* ifndef PLATFORM_UNIX definitions */ - #endif /* PAL_PERF */ diff --git a/src/pal/src/misc/sysinfo.cpp b/src/pal/src/misc/sysinfo.cpp index e7589e8583..3ccb35ab81 100644 --- a/src/pal/src/misc/sysinfo.cpp +++ b/src/pal/src/misc/sysinfo.cpp @@ -76,11 +76,6 @@ Revision History: SET_DEFAULT_DEBUG_CHANNEL(MISC); -#if defined(_HPUX_) && ( defined (_IA64_) || defined (__hppa__) ) -#include <sys/pstat.h> -#include <sys/vmparam.h> -#endif - #ifndef __APPLE__ #if HAVE_SYSCONF && HAVE__SC_AVPHYS_PAGES #define SYSCONF_PAGES _SC_AVPHYS_PAGES @@ -135,22 +130,11 @@ GetSystemInfo( lpSystemInfo->dwActiveProcessorMask_PAL_Undefined = 0; #if HAVE_SYSCONF -#if defined(_HPUX_) && ( defined (_IA64_) || defined (__hppa__) ) - struct pst_dynamic psd; - if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1) { - nrcpus = psd.psd_proc_cnt; - } - else { - ASSERT("pstat_getdynamic failed (%d)\n", errno); - } - -#else // !__hppa__ nrcpus = sysconf(_SC_NPROCESSORS_ONLN); if (nrcpus < 1) { ASSERT("sysconf failed for _SC_NPROCESSORS_ONLN (%d)\n", errno); } -#endif // __hppa__ #elif HAVE_SYSCTL int rc; size_t sz; @@ -171,7 +155,7 @@ GetSystemInfo( #ifdef VM_MAXUSER_ADDRESS lpSystemInfo->lpMaximumApplicationAddress = (PVOID) VM_MAXUSER_ADDRESS; -#elif defined(__sun__) || defined(_AIX) || defined(__hppa__) || ( defined (_IA64_) && defined (_HPUX_) ) || defined(__linux__) +#elif defined(__linux__) lpSystemInfo->lpMaximumApplicationAddress = (PVOID) (1ull << 47); #elif defined(USERLIMIT) lpSystemInfo->lpMaximumApplicationAddress = (PVOID) USERLIMIT; diff --git a/src/pal/src/misc/utils.cpp b/src/pal/src/misc/utils.cpp index 1e333d19ac..f0ff63439f 100644 --- a/src/pal/src/misc/utils.cpp +++ b/src/pal/src/misc/utils.cpp @@ -18,21 +18,21 @@ Abstract: --*/ +#include "pal/dbgmsg.h" +SET_DEFAULT_DEBUG_CHANNEL(MISC); // some headers have code with asserts, so do this first + #include "pal/palinternal.h" #if HAVE_VM_ALLOCATE #include <mach/message.h> #endif //HAVE_VM_ALLOCATE #include "pal/utils.h" -#include "pal/dbgmsg.h" #include "pal/file.h" #include <errno.h> #include <string.h> -SET_DEFAULT_DEBUG_CHANNEL(MISC); - // In safemath.h, Template SafeInt uses macro _ASSERTE, which need to use variable // defdbgchan defined by SET_DEFAULT_DEBUG_CHANNEL. Therefore, the include statement // should be placed after the SET_DEFAULT_DEBUG_CHANNEL(MISC) diff --git a/src/pal/src/safecrt/cruntime.h b/src/pal/src/safecrt/cruntime.h index cdad474e53..7341a388b6 100644 --- a/src/pal/src/safecrt/cruntime.h +++ b/src/pal/src/safecrt/cruntime.h @@ -36,11 +36,11 @@ #endif /* defined (_SYSCRT) && defined (_WIN64) */ #if !defined (UNALIGNED) -#if defined (_M_IA64) || defined (_M_AMD64) +#if defined (_M_AMD64) #define UNALIGNED __unaligned -#else /* defined (_M_IA64) || defined (_M_AMD64) */ +#else /* defined (_M_AMD64) */ #define UNALIGNED -#endif /* defined (_M_IA64) || defined (_M_AMD64) */ +#endif /* defined (_M_AMD64) */ #endif /* !defined (UNALIGNED) */ #ifdef _M_IX86 @@ -57,9 +57,9 @@ #define REG8 #define REG9 -#elif defined (_M_IA64) || defined (_M_AMD64) +#elif defined (_M_AMD64) /* - * IA64 + * AMD64 */ #define REG1 register #define REG2 register @@ -71,7 +71,7 @@ #define REG8 register #define REG9 register -#else /* defined (_M_IA64) || defined (_M_AMD64) */ +#else /* defined (_M_AMD64) */ #pragma message ("Machine register set not defined") @@ -89,7 +89,7 @@ #define REG8 #define REG9 -#endif /* defined (_M_IA64) || defined (_M_AMD64) */ +#endif /* defined (_M_AMD64) */ /* * Are the macro definitions below still needed in this file? diff --git a/src/pal/src/safecrt/sscanf_s.cpp b/src/pal/src/safecrt/sscanf_s.cpp index 4f548bccc6..7a481b580f 100644 --- a/src/pal/src/safecrt/sscanf_s.cpp +++ b/src/pal/src/safecrt/sscanf_s.cpp @@ -21,7 +21,7 @@ typedef int (*INPUTFN)(miniFILE *, const unsigned char*, va_list); typedef int (*WINPUTFN)(miniFILE *, const wchar_t*, va_list); - +extern size_t PAL_wcsnlen(const WCHAR* inString, size_t inMaxSize); /*** *static int v[nw]scan_fn([w]inputfn, string, [count], format, ...) @@ -115,7 +115,7 @@ static int __cdecl vwscan_fn ( miniFILE str; miniFILE *infile = &str; int retval; - size_t count = wcsnlen(string, INT_MAX); + size_t count = PAL_wcsnlen(string, INT_MAX); _VALIDATE_RETURN( (string != NULL), EINVAL, EOF); _VALIDATE_RETURN( (format != NULL), EINVAL, EOF); @@ -149,7 +149,7 @@ static int __cdecl vnwscan_fn ( miniFILE str; miniFILE *infile = &str; int retval; - size_t length = wcsnlen(string, INT_MAX); + size_t length = PAL_wcsnlen(string, INT_MAX); _VALIDATE_RETURN( (string != NULL), EINVAL, EOF); _VALIDATE_RETURN( (format != NULL), EINVAL, EOF); diff --git a/src/pal/src/safecrt/wcslen_s.cpp b/src/pal/src/safecrt/wcslen_s.cpp index 4fd5371035..0688148b5d 100644 --- a/src/pal/src/safecrt/wcslen_s.cpp +++ b/src/pal/src/safecrt/wcslen_s.cpp @@ -42,7 +42,7 @@ * *******************************************************************************/ -size_t __cdecl wcsnlen(const wchar_t *wcs, size_t maxsize) +size_t __cdecl PAL_wcsnlen(const wchar_t *wcs, size_t maxsize) { size_t n; diff --git a/src/pal/src/shmemory/shmemory.cpp b/src/pal/src/shmemory/shmemory.cpp index 42e06be834..35dadd6b3a 100644 --- a/src/pal/src/shmemory/shmemory.cpp +++ b/src/pal/src/shmemory/shmemory.cpp @@ -189,10 +189,6 @@ SET_DEFAULT_DEBUG_CHANNEL(SHMEM); #define SEGMENT_NAME_SUFFIX_LENGTH 10 -#if defined(_DEBUG) && defined(_HPUX_) -#define TRACK_SHMLOCK_OWNERSHIP -#endif // _DEBUG && _HPUX_ - /* SHMPTR structure : High byte is SHM segment number @@ -808,24 +804,6 @@ int SHMLock(void) CHECK_CANARIES(header); #endif // TRACK_SHMLOCK_OWNERSHIP -#ifdef _HPUX_ - // - // TODO: workaround for VSW # 381564 - // - if (0 == tmp_pid && my_pid != header->spinlock) - { - ERROR("InterlockedCompareExchange returned the Comperand but " - "failed to store the Exchange value to the Destination: " - "looping again [my_pid=%u header->spinlock=%u tmp_pid=%u " - "spincount=%d locking_thread=%u]\n", (DWORD)my_pid, - (DWORD)header->spinlock, (DWORD)tmp_pid, (int)spincount, - (HANDLE)locking_thread); - - // Keep looping - tmp_pid = 42; - } -#endif // _HPUX_ - if (0 == tmp_pid) { // Spinlock acquired: break out of the loop @@ -964,31 +942,17 @@ int SHMRelease(void) #endif // TRACK_SHMLOCK_OWNERSHIP -#ifdef _HPUX_ - // - // TODO: workaround for VSW # 381564 - // - do -#endif // _HPUX_ - { - /* Make sure we don't touch the spinlock if we don't own it. We're - supposed to own it if we get here, but just in case... */ - tmp_pid = InterlockedCompareExchange((LONG *) &header->spinlock, 0, my_pid); + /* Make sure we don't touch the spinlock if we don't own it. We're + supposed to own it if we get here, but just in case... */ + tmp_pid = InterlockedCompareExchange((LONG *) &header->spinlock, 0, my_pid); - if (tmp_pid != my_pid) - { - ASSERT("Process 0x%08x tried to release spinlock owned by process " - "0x%08x! \n", my_pid, tmp_pid); - PALCLeaveCriticalSection(&shm_critsec); - return 0; - } + if (tmp_pid != my_pid) + { + ASSERT("Process 0x%08x tried to release spinlock owned by process " + "0x%08x! \n", my_pid, tmp_pid); + PALCLeaveCriticalSection(&shm_critsec); + return 0; } -#ifdef _HPUX_ - // - // TODO: workaround for VSW # 381564 - // - while (my_pid == header->spinlock); -#endif // _HPUX_ /* indicate no thread (in this process) holds the SHM lock */ locking_thread = 0; diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp index a64bfb8ab1..ae069aec86 100644 --- a/src/pal/src/thread/process.cpp +++ b/src/pal/src/thread/process.cpp @@ -18,6 +18,9 @@ Abstract: --*/ +#include "pal/dbgmsg.h" +SET_DEFAULT_DEBUG_CHANNEL(PROCESS); // some headers have code with asserts, so do this first + #include "pal/procobj.hpp" #include "pal/thread.hpp" #include "pal/file.hpp" @@ -29,7 +32,6 @@ Abstract: #include "pal/init.h" #include "pal/critsect.h" #include "pal/debug.h" -#include "pal/dbgmsg.h" #include "pal/utils.h" #include "pal/environ.h" #include "pal/virtual.h" @@ -67,8 +69,6 @@ Abstract: using namespace CorUnix; -SET_DEFAULT_DEBUG_CHANNEL(PROCESS); - CObjectType CorUnix::otProcess( otiProcess, NULL, @@ -1453,7 +1453,7 @@ static uint64_t HashSemaphoreName(uint64_t a, uint64_t b) #define HashSemaphoreName(a,b) a,b #endif -static const char* PipeNameFormat = "/tmp/clr-debug-pipe-%d-%llu-%s"; +static const char* PipeNameFormat = TEMP_DIRECTORY_PATH "clr-debug-pipe-%d-%llu-%s"; class PAL_RuntimeStartupHelper { @@ -1879,7 +1879,7 @@ Parameters: None Return value: - TRUE - succeeded, FALSE - failed + TRUE - successfully launched by debugger, FALSE - not launched or some failure in the handshake --*/ BOOL PALAPI @@ -1889,7 +1889,7 @@ PAL_NotifyRuntimeStarted() char continueSemName[CLR_SEM_MAX_NAMELEN]; sem_t *startupSem = SEM_FAILED; sem_t *continueSem = SEM_FAILED; - BOOL result = TRUE; + BOOL launched = FALSE; UINT64 processIdDisambiguationKey = 0; GetProcessIdDisambiguationKey(gPID, &processIdDisambiguationKey); @@ -1899,9 +1899,7 @@ PAL_NotifyRuntimeStarted() TRACE("PAL_NotifyRuntimeStarted opening continue '%s' startup '%s'\n", continueSemName, startupSemName); - - // Open the debugger startup semaphore. If it doesn't exists, then we do nothing and - // the function is successful. + // Open the debugger startup semaphore. If it doesn't exists, then we do nothing and return startupSem = sem_open(startupSemName, 0); if (startupSem == SEM_FAILED) { @@ -1913,7 +1911,6 @@ PAL_NotifyRuntimeStarted() if (continueSem == SEM_FAILED) { ASSERT("sem_open(%s) failed: %d (%s)\n", continueSemName, errno, strerror(errno)); - result = FALSE; goto exit; } @@ -1921,7 +1918,6 @@ PAL_NotifyRuntimeStarted() if (sem_post(startupSem) != 0) { ASSERT("sem_post(startupSem) failed: errno is %d (%s)\n", errno, strerror(errno)); - result = FALSE; goto exit; } @@ -1929,10 +1925,12 @@ PAL_NotifyRuntimeStarted() if (sem_wait(continueSem) != 0) { ASSERT("sem_wait(continueSem) failed: errno is %d (%s)\n", errno, strerror(errno)); - result = FALSE; goto exit; } + // Returns that the runtime was successfully launched for debugging + launched = TRUE; + exit: if (startupSem != SEM_FAILED) { @@ -1942,7 +1940,7 @@ exit: { sem_close(continueSem); } - return result; + return launched; } /*++ diff --git a/src/pal/src/thread/thread.cpp b/src/pal/src/thread/thread.cpp index 566ef855b4..53283320c5 100644 --- a/src/pal/src/thread/thread.cpp +++ b/src/pal/src/thread/thread.cpp @@ -34,6 +34,8 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do #include "pal/module.h" #include "pal/environ.h" #include "pal/init.h" +#include "pal/utils.h" +#include "pal/virtual.h" #if defined(__NetBSD__) && !HAVE_PTHREAD_GETCPUCLOCKID #include <sys/cdefs.h> @@ -77,13 +79,6 @@ using namespace CorUnix; /* ------------------- Definitions ------------------------------*/ -// The default stack size of a newly created thread (currently 256KB) -// when the dwStackSize parameter of PAL_CreateThread() -// is zero. This value can be set by setting the -// environment variable PAL_THREAD_DEFAULT_STACK_SIZE -// (the value should be in bytes and in hex). -DWORD CPalThread::s_dwDefaultThreadStackSize = 256*1024; - /* list of free CPalThread objects */ static Volatile<CPalThread*> free_threads_list = NULL; @@ -528,6 +523,7 @@ CorUnix::InternalCreateThread( #endif // PTHREAD_CREATE_MODIFIES_ERRNO BOOL fHoldingProcessLock = FALSE; int iError = 0; + size_t alignedStackSize; if (0 != terminator) { @@ -573,7 +569,24 @@ CorUnix::InternalCreateThread( palError = ERROR_INVALID_PARAMETER; goto EXIT; } - + + alignedStackSize = dwStackSize; + if (alignedStackSize != 0) + { + // Some systems require the stack size to be aligned to the page size + if (sizeof(alignedStackSize) <= sizeof(dwStackSize) && alignedStackSize + (VIRTUAL_PAGE_SIZE - 1) < alignedStackSize) + { + // When coming here from the public API surface, the incoming value is originally a nonnegative signed int32, so + // this shouldn't happen + ASSERT( + "Couldn't align the requested stack size (%Iu) to the page size because the stack size was too large\n", + alignedStackSize); + palError = ERROR_INVALID_PARAMETER; + goto EXIT; + } + alignedStackSize = ALIGN_UP(alignedStackSize, VIRTUAL_PAGE_SIZE); + } + // Ignore the STACK_SIZE_PARAM_IS_A_RESERVATION flag dwCreationFlags &= ~STACK_SIZE_PARAM_IS_A_RESERVATION; @@ -616,42 +629,34 @@ CorUnix::InternalCreateThread( fAttributesInitialized = TRUE; /* adjust the stack size if necessary */ - if (0 != pthread_attr_getstacksize(&pthreadAttr, &pthreadStackSize)) + if (alignedStackSize != 0) { - ERROR("couldn't set thread stack size\n"); - palError = ERROR_INTERNAL_ERROR; - goto EXIT; - } - - TRACE("default pthread stack size is %d, caller requested %d (default is %d)\n", - pthreadStackSize, dwStackSize, CPalThread::s_dwDefaultThreadStackSize); - - if (0 == dwStackSize) - { - dwStackSize = CPalThread::s_dwDefaultThreadStackSize; - } - #ifdef PTHREAD_STACK_MIN - if (PTHREAD_STACK_MIN > pthreadStackSize) - { - WARN("default stack size is reported as %d, but PTHREAD_STACK_MIN is " - "%d\n", pthreadStackSize, PTHREAD_STACK_MIN); - } -#endif - - if (pthreadStackSize < dwStackSize) - { - TRACE("setting thread stack size to %d\n", dwStackSize); - if (0 != pthread_attr_setstacksize(&pthreadAttr, dwStackSize)) + const size_t MinStackSize = PTHREAD_STACK_MIN; +#else // !PTHREAD_STACK_MIN + const size_t MinStackSize = 64 * 1024; // this value is typically accepted by pthread_attr_setstacksize() +#endif // PTHREAD_STACK_MIN + _ASSERTE(IS_ALIGNED(MinStackSize, VIRTUAL_PAGE_SIZE)); + if (alignedStackSize < MinStackSize) { - ERROR("couldn't set pthread stack size to %d\n", dwStackSize); + // Adjust the stack size to a minimum value that is likely to be accepted by pthread_attr_setstacksize(). If this + // function fails, typically the caller will end up throwing OutOfMemoryException under the assumption that the + // requested stack size is too large or the system does not have sufficient memory to create a thread. Try to + // prevent failing just just because the stack size value is too low. + alignedStackSize = MinStackSize; + } + + TRACE("setting thread stack size to %Iu\n", alignedStackSize); + if (0 != pthread_attr_setstacksize(&pthreadAttr, alignedStackSize)) + { + ERROR("couldn't set pthread stack size to %Iu\n", alignedStackSize); palError = ERROR_INTERNAL_ERROR; goto EXIT; } } else { - TRACE("using the system default thread stack size of %d\n", pthreadStackSize); + TRACE("using the system default thread stack size\n"); } #if HAVE_THREAD_SELF || HAVE__LWP_SELF @@ -1755,39 +1760,6 @@ fail: return NULL; } - -#define PAL_THREAD_DEFAULT_STACK_SIZE "PAL_THREAD_DEFAULT_STACK_SIZE" - -PAL_ERROR -CorUnix::InitializeGlobalThreadData( - void - ) -{ - PAL_ERROR palError = NO_ERROR; - char *pszStackSize = NULL; - - // - // Read in the environment to see whether we need to change the default - // thread stack size. - // - pszStackSize = EnvironGetenv(PAL_THREAD_DEFAULT_STACK_SIZE); - if (NULL != pszStackSize) - { - // Environment variable exists - char *pszEnd; - DWORD dw = PAL_strtoul(pszStackSize, &pszEnd, 16); // treat it as hex - if ( (pszStackSize != pszEnd) && (0 != dw) ) - { - CPalThread::s_dwDefaultThreadStackSize = dw; - } - - free(pszStackSize); - } - - return palError; -} - - /*++ Function: CreateThreadData diff --git a/src/pal/src/thread/threadsusp.cpp b/src/pal/src/thread/threadsusp.cpp index b31b88da59..c7787bef68 100644 --- a/src/pal/src/thread/threadsusp.cpp +++ b/src/pal/src/thread/threadsusp.cpp @@ -36,16 +36,6 @@ Revision History: #include <limits.h> #include <debugmacrosext.h> -#if defined(_AIX) -// AIX requires explicit definition of the union semun (see semctl man page) -union semun -{ - int val; - struct semid_ds * buf; - unsigned short * array; -}; -#endif - using namespace CorUnix; /* ------------------- Definitions ------------------------------*/ |