Swift 4.1: s390x architecture: Illegal instruction while running Foundation Tests

Hello folks,

I am trying to get 4.1 working on s390x arch (big-endian) and we are running into several issues but I think we could be chasing a single problem related to memory allocation. I made the following changes to the code and it went further but failed elsewhere.

/=======================================/
diff --git a/CoreFoundation/Base.subproj/CFInternal.h b/CoreFoundation/Base.subproj/CFInternal.h
index 1a832ae…05646bd 100644
— a/CoreFoundation/Base.subproj/CFInternal.h
+++ b/CoreFoundation/Base.subproj/CFInternal.h
@@ -405,6 +405,12 @@ CF_EXPORT void * __CFConstantStringClassReferencePtr;

CF_EXPORT void *__CFConstantStringClassReference[];

+#if CF_BIG_ENDIAN
+#define CF_CONST_STRING_INFO {0x00, 0x00, 0x07, 0xc8}
+#elif CF_LITTLE_ENDIAN
+#define CF_CONST_STRING_INFO {0xc8, 0x07, 0x00, 0x00}
+#endif
+
#if DEPLOYMENT_TARGET_LINUX
#define CONST_STRING_SECTION attribute((section(".cfstr.data")))
#else
@@ -412,11 +418,11 @@ CF_EXPORT void *__CFConstantStringClassReference[];
#endif

#define CONST_STRING_DECL(S, V)
-const struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x000007c8U}, (uint8_t *)(V), sizeof(V) - 1};
+const struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, CF_CONST_STRING_INFO}, (uint8_t *)(V), sizeof(V) - 1};
const CFStringRef S = (CFStringRef)&
##S;

#define PE_CONST_STRING_DECL(S, V)
-const static struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x000007c8U}, (uint8_t *)(V), sizeof(V) - 1};
+const static struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, CF_CONST_STRING_INFO}, (uint8_t *)(V), sizeof(V) - 1};
CF_PRIVATE const CFStringRef S = (CFStringRef)&
##S;

@@ -430,7 +436,11 @@ CF_PRIVATE const CFStringRef S = (CFStringRef)&__##S;
struct CF_CONST_STRING {
CFRuntimeBase _base;
uint8_t *_ptr;

  • uint32_t _length;
    +#if defined(LP64) && defined(BIG_ENDIAN)
  •   uint64_t _length;
    

+#else

  •   uint32_t _length;
    

+#endif
};

CF_EXPORT int __CFConstantStringClassReference[];
@@ -438,10 +448,10 @@ CF_EXPORT int __CFConstantStringClassReference[];
/* CFNetwork also has a copy of the CONST_STRING_DECL macro (for use on platforms without constant string support in cc); please warn cfnetwork-core@group.apple.com of any necessary changes to this macro. – REW, 1/28/2002 */

#define CONST_STRING_DECL(S, V)
-static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, 0x000007c8U}, (uint8_t *)V, sizeof(V) - 1};
+static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, CF_CONST_STRING_INFO}, (uint8_t *)V, sizeof(V) - 1};
const CFStringRef S = (CFStringRef) & __ ## S ## __;
#define PE_CONST_STRING_DECL(S, V)
-static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, 0x000007c8U}, (uint8_t *)V, sizeof(V) - 1};
+static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, CF_CONST_STRING_INFO}, (uint8_t *)V, sizeof(V) - 1};
CF_PRIVATE const CFStringRef S = (CFStringRef) & __ ## S ## __;

#endif // CONSTANT_CFSTRINGS
diff --git a/CoreFoundation/Base.subproj/CFRuntime.c b/CoreFoundation/Base.subproj/CFRuntime.c
index da9d2c0…a9a45ab 100644
— a/CoreFoundation/Base.subproj/CFRuntime.c
+++ b/CoreFoundation/Base.subproj/CFRuntime.c
@@ -388,11 +388,11 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF

 // Zero the rest of the memory, starting at cfinfo
 memset(&memory->_cfinfoa, 0, size - (sizeof(memory->_cfisa) + sizeof(memory->_swift_strong_rc) + sizeof(memory->_swift_weak_rc)));
  • // Set up the cfinfo struct
  • uint32_t *cfinfop = (uint32_t *)&(memory->_cfinfoa);
  • uint64_t *cfinfop = (uint64_t *)&(memory->_cfinfoa);
    // The 0x80 means we use the default allocator
  • *cfinfop = (uint32_t)(((uint32_t)typeID << 8) | (0x80));
  • *cfinfop = (uint64_t)(((uint64_t)typeID << 8) | (0x80));

    return memory;
    #else

/=======================================/

After making the changes, core dump happens here:
/========================================/

  • env LD_LIBRARY_PATH=/opt/swift4.1///usr//lib/swift/:/home/swift/swift4.1/swift4.1/build/Ninja-DebugAssert/foundation-linux-s390x/Foundation:/home/swift/swift4.1/swift4.1/build/Ninja-DebugAssert/xctest-linux-s390x:/home/swift/swift4.1/swift4.1/build/Ninja-DebugAssert/libdispatch-linux-s390x/src/.libs:/usr/local/lib: /home/swift/swift4.1/swift4.1/build/Ninja-DebugAssert/foundation-linux-s390x/TestFoundation/TestFoundation
    Fatal error: Index out of range: file /home/swift/swift4.1/swift4.1/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 414
    Current stack trace:
    /home/swift/swift4.1/swift4.1/swift/utils/build-script-impl: line 259: 366 Illegal instruction (core dumped) “$@”
    ./utils/build-script: fatal error: command terminated with a non-zero exit status 132, aborting
    /========================================/

Please let me know if anything obvious can be spotted or places I can look at for further insight.

Thanks.

The struct behind all CF types is laid out in memory to match Swift object. Is it possible that some of those fields also need to be adjusted?