Merge remote-tracking branch 'upstream/release/18.x' into rustc/18.0-2024-02-13
diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt
index 806d5a7..e5ad8f7 100644
--- a/libunwind/CMakeLists.txt
+++ b/libunwind/CMakeLists.txt
@@ -251,7 +251,7 @@
 
   # On Release builds cmake automatically defines NDEBUG, so we
   # explicitly undefine it:
-  if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
+  if ((NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") AND (NOT RUST_SGX))
     add_compile_flags(-UNDEBUG)
   endif()
 else()
diff --git a/libunwind/README_RUST_SGX.md b/libunwind/README_RUST_SGX.md
new file mode 100644
index 0000000..c5d6eb4
--- /dev/null
+++ b/libunwind/README_RUST_SGX.md
@@ -0,0 +1,22 @@
+# Libunwind customizations for linking with x86_64-fortanix-unknown-sgx Rust target.
+
+## Description
+### Initial Fork
+Initial Fork has been made from 5.0 release of llvm (commit: 6a075b6de4)
+### Detailed Description
+#### Header files that we do not include for this target
+1. pthread.h
+#### Library that we do not link to for this target.
+1. pthread (Locks used by libunwind is provided by rust stdlib for this target)
+
+## Building unwind for rust-sgx target
+### Generate Make files:
+* `cd where you want to build libunwind`
+* `mkdir build`
+* `cd build`
+* `cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" -DLLVM_ENABLE_WARNINGS=1 -DLIBUNWIND_ENABLE_PEDANTIC=0 -DLLVM_PATH=<path/to/llvm> <path/to/libunwind>`
+* `"DEBUG"` could be used instead of `"RELEASE"` to enable debug logs of libunwind.
+
+### Build:
+* `make unwind_static`
+* `build/lib/` will have the built library.
diff --git a/libunwind/docs/BuildingLibunwind.rst b/libunwind/docs/BuildingLibunwind.rst
index 79166b4..abd432c9 100644
--- a/libunwind/docs/BuildingLibunwind.rst
+++ b/libunwind/docs/BuildingLibunwind.rst
@@ -148,3 +148,8 @@
 
   Path where built libunwind libraries should be installed. If a relative path,
   relative to ``CMAKE_INSTALL_PREFIX``.
+
+.. option:: LIBUNWIND_ENABLE_RUST_SGX:BOOL
+
+  **Default**: ``OFF``
+
diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index 5551c7d..9f0a611 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -94,6 +94,7 @@
 //   __eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
 //   __eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;
 
+#if !defined(RUST_SGX)
 extern char __eh_frame_start;
 extern char __eh_frame_end;
 
@@ -102,6 +103,15 @@
 extern char __eh_frame_hdr_end;
 #endif
 
+#elif defined(RUST_SGX)
+extern "C" char IMAGE_BASE;
+extern "C" uint64_t EH_FRM_HDR_OFFSET;
+extern "C" uint64_t EH_FRM_HDR_LEN;
+extern "C" uint64_t EH_FRM_OFFSET;
+extern "C" uint64_t EH_FRM_LEN;
+#endif
+
+
 #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL)
 
 // When statically linked on bare-metal, the symbols for the EH table are looked
@@ -487,6 +497,10 @@
 #endif  // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
 
 
+#if defined(RUST_SGX)
+extern "C" char IMAGE_BASE;
+#endif
+    
 inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
                                                   UnwindInfoSections &info) {
 #ifdef __APPLE__
@@ -520,6 +534,8 @@
 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
   info.dso_base = 0;
   // Bare metal is statically linked, so no need to ask the dynamic loader
+
+#if !defined(RUST_SGX)
   info.dwarf_section_length = (size_t)(&__eh_frame_end - &__eh_frame_start);
   info.dwarf_section =        (uintptr_t)(&__eh_frame_start);
   _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p",
@@ -530,6 +546,17 @@
   _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %p length %p",
                              (void *)info.dwarf_index_section, (void *)info.dwarf_index_section_length);
 #endif
+
+#elif defined(RUST_SGX)
+  info.dwarf_section =        (uintptr_t)EH_FRM_OFFSET + (uintptr_t)(&IMAGE_BASE);
+  info.dwarf_section_length = (uintptr_t)EH_FRM_LEN;
+#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
+  info.dwarf_index_section =        (uintptr_t)EH_FRM_HDR_OFFSET + (uintptr_t)(&IMAGE_BASE);
+  info.dwarf_index_section_length = (uintptr_t)EH_FRM_HDR_LEN;
+#endif
+
+#endif
+  
   if (info.dwarf_section_length)
     return true;
 #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL)
diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt
index 780430b..facf371 100644
--- a/libunwind/src/CMakeLists.txt
+++ b/libunwind/src/CMakeLists.txt
@@ -1,5 +1,9 @@
 # Get sources
 
+enable_language(C CXX ASM)
+
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
 set(LIBUNWIND_CXX_SOURCES
     libunwind.cpp
     Unwind-EHABI.cpp
@@ -18,9 +22,6 @@
     Unwind-sjlj.c
     Unwind-wasm.c
     )
-set_source_files_properties(${LIBUNWIND_C_SOURCES}
-                            PROPERTIES
-                              COMPILE_FLAGS "-std=c99")
 
 set(LIBUNWIND_ASM_SOURCES
     UnwindRegistersRestore.S
@@ -60,6 +61,44 @@
   source_group("Header Files" FILES ${LIBUNWIND_HEADERS})
 endif()
 
+if (RUST_SGX)
+    # Compile Flags
+    add_definitions(-DRUST_SGX)
+    add_definitions(-D__NO_STRING_INLINES)
+    add_definitions(-D__NO_MATH_INLINES)
+    add_definitions(-D_LIBUNWIND_IS_BAREMETAL)
+    # Can't use add_definitions because CMake will reorder these arguments
+    list(APPEND LIBUNWIND_COMPILE_FLAGS -U_FORTIFY_SOURCE)
+    list(APPEND LIBUNWIND_COMPILE_FLAGS -D_FORTIFY_SOURCE=0)
+
+    list(APPEND LIBUNWIND_COMPILE_FLAGS -fno-stack-protector)
+    list(APPEND LIBUNWIND_COMPILE_FLAGS -ffreestanding)
+    list(APPEND LIBUNWIND_COMPILE_FLAGS -fexceptions)
+    # Avoid too new relocation types being emitted, which might prevent linking
+    # on older platforms.
+    #
+    # See https://github.com/rust-lang/rust/issues/34978
+    if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+        list(APPEND LIBUNWIND_COMPILE_FLAGS -Wa,-mrelax-relocations=no)
+    else()
+        list(APPEND LIBUNWIND_COMPILE_FLAGS)
+    endif()
+
+    # Sources
+    list(APPEND LIBUNWIND_HEADERS   UnwindRustSgx.h)
+    list(APPEND LIBUNWIND_C_SOURCES UnwindRustSgx.c)
+endif()
+
+
+set_source_files_properties(${LIBUNWIND_C_SOURCES}
+                            PROPERTIES
+                              COMPILE_FLAGS "-std=c99")
+
+# See add_asm_sources() in compiler-rt for explanation of this workaround.
+if((APPLE AND CMAKE_VERSION VERSION_LESS 3.19) OR (MINGW AND CMAKE_VERSION VERSION_LESS 3.17))
+  set_source_files_properties(${LIBUNWIND_ASM_SOURCES} PROPERTIES LANGUAGE C)
+endif()
+
 set(LIBUNWIND_SOURCES
     ${LIBUNWIND_CXX_SOURCES}
     ${LIBUNWIND_C_SOURCES}
@@ -82,11 +121,11 @@
   add_library_flags_if(LIBUNWIND_HAS_DL_LIB dl)
 endif()
 
-if (LIBUNWIND_ENABLE_THREADS AND NOT APPLE)
+if (LIBUNWIND_ENABLE_THREADS AND NOT APPLE AND (NOT RUST_SGX))
     add_library_flags_if(LIBUNWIND_HAS_PTHREAD_LIB pthread)
 endif()
 
-if (LIBUNWIND_ENABLE_THREADS)
+if (LIBUNWIND_ENABLE_THREADS AND (NOT RUST_SGX))
   add_compile_flags_if(LIBUNWIND_WEAK_PTHREAD_LIB -DLIBUNWIND_USE_WEAK_PTHREAD=1)
 endif()
 
diff --git a/libunwind/src/RWMutex.hpp b/libunwind/src/RWMutex.hpp
index 344d356..65bd849 100644
--- a/libunwind/src/RWMutex.hpp
+++ b/libunwind/src/RWMutex.hpp
@@ -15,7 +15,7 @@
 
 #if defined(_WIN32)
 #include <windows.h>
-#elif !defined(_LIBUNWIND_HAS_NO_THREADS)
+#elif !defined(_LIBUNWIND_HAS_NO_THREADS) && !defined(RUST_SGX)
 #include <pthread.h>
 #if defined(__ELF__) && defined(_LIBUNWIND_LINK_PTHREAD_LIB)
 #pragma comment(lib, "pthread")
diff --git a/libunwind/src/UnwindRustSgx.c b/libunwind/src/UnwindRustSgx.c
new file mode 100644
index 0000000..9be7c1b
--- /dev/null
+++ b/libunwind/src/UnwindRustSgx.c
@@ -0,0 +1,125 @@
+//===--------------------- UnwindRustSgx.c ----------------------------------===//
+//
+////                     The LLVM Compiler Infrastructure
+////
+//// This file is dual licensed under the MIT and the University of Illinois Open
+//// Source Licenses. See LICENSE.TXT for details.
+////
+////
+////===----------------------------------------------------------------------===//
+
+#define _GNU_SOURCE
+#include <link.h>
+
+#include <elf.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stddef.h>
+#include "UnwindRustSgx.h"
+
+#define max_log 256
+
+__attribute__((weak)) struct _IO_FILE *stderr  = (struct _IO_FILE *)-1;
+
+static int vwrite_err(const char *format, va_list ap)
+{
+    int len = 0;
+#ifndef NDEBUG
+    char s[max_log];
+    s[0]='\0';
+    len = vsnprintf(s, max_log, format, ap);
+    __rust_print_err((uint8_t *)s, len);
+#endif
+    return len;
+}
+
+static int write_err(const char *format, ...)
+{
+    int ret;
+    va_list args;
+        va_start(args, format);
+    ret = vwrite_err(format, args);
+    va_end(args);
+
+
+    return ret;
+}
+
+__attribute__((weak)) int fprintf (FILE *__restrict __stream,
+            const char *__restrict __format, ...)
+{
+
+    int ret;
+    if (__stream != stderr) {
+        write_err("Rust SGX Unwind supports only writing to stderr\n");
+        return -1;
+    } else {
+        va_list args;
+        ret = 0;
+        va_start(args, __format);
+        ret += vwrite_err(__format, args);
+        va_end(args);
+    }
+
+    return ret;
+}
+
+__attribute__((weak)) int fflush (FILE *__stream)
+{
+    // We do not need to do anything here.
+    return 0;
+}
+
+__attribute__((weak)) void __assert_fail(const char * assertion,
+                                       const char * file,
+                           unsigned int line,
+                           const char * function)
+{
+    write_err("%s:%d %s %s\n", file, line, function, assertion);
+    abort();
+}
+
+// We do not report stack over flow detected.
+// Calling write_err uses more stack due to the way we have implemented it.
+// With possible enabling of stack probes, we should not
+// get into __stack_chk_fail() at all.
+__attribute__((weak))  void __stack_chk_fail() {
+    abort();
+}
+
+/*
+ * Below are defined for all executibles compiled for
+ * x86_64-fortanix-unknown-sgx rust target.
+ * Ref: rust/src/libstd/sys/sgx/abi/entry.S
+ */
+
+struct libwu_rs_alloc_meta {
+    size_t alloc_size;
+    // Should we put a signatre guard before ptr for oob access?
+    unsigned char ptr[0];
+};
+
+#define META_FROM_PTR(__PTR) (struct libwu_rs_alloc_meta *) \
+    ((unsigned char *)__PTR - offsetof(struct libwu_rs_alloc_meta, ptr))
+
+void *libuw_malloc(size_t size)
+{
+    struct libwu_rs_alloc_meta *meta;
+    size_t alloc_size = size + sizeof(struct libwu_rs_alloc_meta);
+    meta = (void *)__rust_c_alloc(alloc_size, sizeof(size_t));
+    if (!meta) {
+        return NULL;
+    }
+    meta->alloc_size = alloc_size;
+    return (void *)meta->ptr;
+}
+
+void libuw_free(void *p)
+{
+    struct libwu_rs_alloc_meta *meta;
+    if (!p) {
+        return;
+    }
+    meta = META_FROM_PTR(p);
+    __rust_c_dealloc((unsigned char *)meta, meta->alloc_size, sizeof(size_t));
+}
diff --git a/libunwind/src/UnwindRustSgx.h b/libunwind/src/UnwindRustSgx.h
new file mode 100644
index 0000000..8155b8e
--- /dev/null
+++ b/libunwind/src/UnwindRustSgx.h
@@ -0,0 +1,84 @@
+//===--------------------- UnwindRustSgx.h ----------------------------------===//
+//
+////                     The LLVM Compiler Infrastructure
+////
+//// This file is dual licensed under the MIT and the University of Illinois Open
+//// Source Licenses. See LICENSE.TXT for details.
+////
+////
+////===----------------------------------------------------------------------===//
+
+#if !defined(UNWIND_RUST_SGX_H)
+#define UNWIND_RUST_SGX_H
+
+#ifdef RUST_SGX
+
+#undef _GNU_SOURCE
+#define _GNU_SOURCE
+#include <link.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdint.h>
+
+// We have to use RWLock from rust repo, it is defined in:
+// src/libstd/sys/sgx/rwlock.rs.
+// rwlock.rs has a compile time check to ensure the size and alignment matches
+// the Rust definition.
+typedef struct {
+  void *opaque;
+} RWLock;
+
+#define RWLOCK_INIT                                                            \
+  { (void *)0 }
+
+// These are the functions exposed by SGX-Rust.
+// The rust changes are available at:
+#ifdef __cplusplus
+extern "C"  {
+#endif
+    int __rust_rwlock_rdlock(RWLock *rwlock);
+    int __rust_rwlock_wrlock(RWLock *rwlock);
+    int __rust_rwlock_unlock(RWLock *rwlock);
+    unsigned char *__rust_c_alloc(size_t, size_t);
+    void __rust_c_dealloc(unsigned char *, size_t, size_t);
+    __attribute__((noreturn)) void __rust_abort(void);
+    unsigned char *__rust_encl_address(size_t);
+
+#ifndef NDEBUG
+    void __rust_print_err(uint8_t *m, int s);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define abort __rust_abort
+
+#undef pthread_rwlock_t
+#undef pthread_rwlock_rdlock
+#undef pthread_rwlock_wrlock
+#undef pthread_rwlock_unlock
+#undef PTHREAD_RWLOCK_INITIALIZER
+
+#define pthread_rwlock_t RWLock
+#define pthread_rwlock_rdlock __rust_rwlock_rdlock
+#define pthread_rwlock_wrlock __rust_rwlock_wrlock
+#define pthread_rwlock_unlock __rust_rwlock_unlock
+#define PTHREAD_RWLOCK_INITIALIZER RWLOCK_INIT
+
+#define malloc libuw_malloc
+#define free libuw_free
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *libuw_malloc(size_t size);
+void libuw_free(void *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/libunwind/src/config.h b/libunwind/src/config.h
index deb5a4d..5337be4 100644
--- a/libunwind/src/config.h
+++ b/libunwind/src/config.h
@@ -20,6 +20,10 @@
 
 #include <__libunwind_config.h>
 
+#ifdef RUST_SGX
+#include "UnwindRustSgx.h"
+#endif
+
 // Platform specific configuration defines.
 #ifdef __APPLE__
   #if defined(FOR_DYLD)
diff --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt
index 595c286..d17d3c5 100644
--- a/lld/CMakeLists.txt
+++ b/lld/CMakeLists.txt
@@ -187,6 +187,19 @@
     )
 endif()
 
+if (MSVC)
+  FOREACH(flag
+      CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
+      CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT
+      CMAKE_CXX_FLAGS_RELEASE  CMAKE_CXX_FLAGS_RELWITHDEBINFO
+      CMAKE_CXX_FLAGS_DEBUG  CMAKE_CXX_FLAGS_DEBUG_INIT)
+      if (MSVC)
+          STRING(REPLACE "/MD"  "/MT" "${flag}" "${${flag}}")
+          SET("${flag}" "${${flag}}")
+      endif (MSVC)
+  ENDFOREACH()
+endif()
+
 add_subdirectory(Common)
 add_subdirectory(tools/lld)
 
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 9f89d63..6a904d9 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -1483,7 +1483,7 @@
 std::error_code copy_file(const Twine &From, const Twine &To) {
   std::string FromS = From.str();
   std::string ToS = To.str();
-#if __has_builtin(__builtin_available)
+#if 0 && __has_builtin(__builtin_available)
   if (__builtin_available(macos 10.12, *)) {
     // Optimistically try to use clonefile() and handle errors, rather than
     // calling stat() to see if it'll work.