summaryrefslogtreecommitdiff
path: root/src/pal/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/src')
-rw-r--r--src/pal/src/CMakeLists.txt111
-rw-r--r--src/pal/src/arch/amd64/processor.cpp16
-rw-r--r--src/pal/src/arch/i386/context2.S47
-rw-r--r--src/pal/src/config.h.in1
-rw-r--r--src/pal/src/configure.cmake33
-rw-r--r--src/pal/src/cruntime/file.cpp78
-rw-r--r--src/pal/src/cruntime/math.cpp8
-rw-r--r--src/pal/src/cruntime/printf.cpp82
-rw-r--r--src/pal/src/cruntime/printfcpp.cpp818
-rw-r--r--src/pal/src/cruntime/silent_printf.cpp280
-rw-r--r--src/pal/src/cruntime/string.cpp2
-rw-r--r--src/pal/src/debug/debug.cpp304
-rw-r--r--src/pal/src/exception/machexception.h2
-rw-r--r--src/pal/src/exception/seh-unwind.cpp4
-rw-r--r--src/pal/src/exception/signal.hpp7
-rw-r--r--src/pal/src/file/disk.cpp3
-rw-r--r--src/pal/src/file/file.cpp9
-rw-r--r--src/pal/src/file/path.cpp4
-rw-r--r--src/pal/src/include/pal/modulename.h3
-rw-r--r--src/pal/src/include/pal/palinternal.h20
-rw-r--r--src/pal/src/include/pal/printfcpp.hpp55
-rw-r--r--src/pal/src/include/pal/sharedmemory.h21
-rw-r--r--src/pal/src/include/pal/thread.hpp18
-rw-r--r--src/pal/src/include/pal/threadsusp.hpp2
-rw-r--r--src/pal/src/include/pal/utils.h56
-rw-r--r--src/pal/src/include/pal/virtual.h5
-rw-r--r--src/pal/src/init/pal.cpp17
-rw-r--r--src/pal/src/loader/module.cpp6
-rw-r--r--src/pal/src/loader/modulename.cpp134
-rw-r--r--src/pal/src/misc/dbgmsg.cpp10
-rw-r--r--src/pal/src/misc/fmtmessage.cpp3
-rw-r--r--src/pal/src/misc/perftrace.cpp179
-rw-r--r--src/pal/src/misc/sysinfo.cpp18
-rw-r--r--src/pal/src/misc/utils.cpp6
-rw-r--r--src/pal/src/safecrt/cruntime.h14
-rw-r--r--src/pal/src/safecrt/sscanf_s.cpp6
-rw-r--r--src/pal/src/safecrt/wcslen_s.cpp2
-rw-r--r--src/pal/src/shmemory/shmemory.cpp54
-rw-r--r--src/pal/src/thread/process.cpp24
-rw-r--r--src/pal/src/thread/thread.cpp108
-rw-r--r--src/pal/src/thread/threadsusp.cpp10
41 files changed, 416 insertions, 2164 deletions
diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt
index 28ee83a..16c9d8b 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 ac3d448..298d685 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 16cbcc8..11aba5e 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 4d21fb7..77d7bfa 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 a53e0db..4f2bc57 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 5fe2b67..0eb2cea 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 08f4192..d53dbe7 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 c437b8e..72c7e11 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 ea074a6..0b90721 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 1d10963..4047c7e 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 abe6d13..2abce6f 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 2f7d17c..2eaaec9 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 18e3150..e2f8ee7 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 fa2f109..e3fa09f 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 c0c950e..cd019e6 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 ef1d488..08880c9 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 6443a5e..d70e62b 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 c4ef31b..d998b72 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 70b0a61..20001f8 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 f7856be..48e2f3c 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 0a728c9..12e923a 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 45cc4b2..2e0d9d2 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 e6dacd2..ddacfb9 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 e1e85e2..dfd65d0 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 3ddad4a..f381d95 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 a4e2252..31d225f 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 0bda276..e6db7dc 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 a4fc494..63a65ff 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 026f89b..87c1b02 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 488e614..d6f173f 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 46e0af6..70b854a 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 d4fba33..fdefdf6 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 e7589e8..3ccb35a 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 1e333d1..f0ff634 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 cdad474..7341a38 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 4f548bc..7a481b5 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 4fd5371..0688148 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 42e06be..35dadd6 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 a64bfb8..ae069ae 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 566ef85..5328332 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 b31b88d..c7787be 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 ------------------------------*/