Length != 2 and X86_64_RELOC_GOT not supported

Hi guys,

I'm not sure whether to put this in compiler or stdlib but on balance, thought probably this is the best place.

As part of my patches to the compiler to add 16-bit and avr support, I added this patch to IR Generation...

diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 6f2448f701..976f939e60 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -167,6 +167,8 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
   Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
   Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
   SizeTy = DataLayout.getIntPtrType(getLLVMContext(), /*addrspace*/ 0);
+  RelativeAddressTy = SizeTy;
+  RelativeAddressPtrTy = RelativeAddressTy->getPointerTo();
 
   FloatTy = llvm::Type::getFloatTy(getLLVMContext());
   DoubleTy = llvm::Type::getDoubleTy(getLLVMContext());
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 95978c644c..6d317f7ffa 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -557,14 +557,10 @@ public:
   llvm::IntegerType *Int1Ty;           /// i1
   llvm::IntegerType *Int8Ty;           /// i8
   llvm::IntegerType *Int16Ty;          /// i16
-  union {
-    llvm::IntegerType *Int32Ty;          /// i32
-    llvm::IntegerType *RelativeAddressTy;
-  };
-  union {
-    llvm::PointerType *Int32PtrTy;            /// i32 *
-    llvm::PointerType *RelativeAddressPtrTy;
-  };
+  llvm::IntegerType *Int32Ty;          /// i32
+  llvm::IntegerType *RelativeAddressTy;
+  llvm::PointerType *Int32PtrTy;            /// i32 *
+  llvm::PointerType *RelativeAddressPtrTy;
   llvm::IntegerType *Int64Ty;          /// i64
   union {
     llvm::IntegerType *SizeTy;         /// usually i32 or i64

The intention is to fix a class of errors when using the compiler to build for 16-bit targets. This might be my rustyness on C++ but I read this as effectively setting RelativeAddressTy to be equal to Int32Ty, so it's hard-coded to 32 bit, regardless of target pointer size. I was attempting to correct this and make it more general.

It works up to a point. I can make swiftc and it will compile basic swift code, but when I attempted to use the build script to do a clean build and test, before creating a pull request, I started to get strange errors during linking the dynamic library for stdlib.

Here's a dump of the error...

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: lib/swift_static/macosx/x86_64/libswiftCore.a(MathStubs.cpp.o) has no symbols
[112/677] Linking CXX shared library lib/swift/macosx/x86_64/libswiftCore.dylib
FAILED: lib/swift/macosx/x86_64/libswiftCore.dylib 
: && /Users/carlpeto/avr/swift/build/Ninja-ReleaseAssert/llvm-macosx-x86_64/./bin/clang++ -Wno-unknown-warning-option -Werror=unguarded-availability-new -fno-stack-protector -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wcovered-switch-default -Wno-class-memaccess -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -Werror=switch -Wdocumentation -Wimplicit-fallthrough -Wunreachable-code -Woverloaded-virtual -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -fno-sanitize=all -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1 -O3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -dynamiclib -Wl,-headerpad_max_install_names -all_load -target x86_64-apple-macosx10.9 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -arch x86_64 -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/../../../Developer/Library/Frameworks -mmacosx-version-min=10.9 -Wl,-sectcreate,__TEXT,__info_plist,/Users/carlpeto/avr/swift/build/Ninja-ReleaseAssert/swift-macosx-x86_64/stdlib/public/core/Info.plist -Wl,-application_extension  "-L/Users/carlpeto/avr/swift/build/Ninja-ReleaseAssert/swift-macosx-x86_64/./lib/swift/macosx/x86_64" "-L/Users/carlpeto/avr/swift/build/Ninja-ReleaseAssert/swift-macosx-x86_64/./bin/../lib/swift/macosx/x86_64" "-L/Users/carlpeto/avr/swift/build/Ninja-ReleaseAssert/swift-macosx-x86_64/./bin/../lib/swift/macosx" -o lib/swift/macosx/x86_64/libswiftCore.dylib -install_name @rpath/libswiftCore.dylib stdlib/public/core/macosx/x86_64/Swift.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/AnyHashableSupport.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Array.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Casting.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/CompatibilityOverride.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/CygwinPort.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Demangle.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Enum.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ErrorObjectConstants.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ErrorObjectNative.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Errors.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ErrorDefaultImpls.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Exclusivity.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ExistentialContainer.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Heap.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/HeapObject.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ImageInspectionMachO.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ImageInspectionELF.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ImageInspectionCOFF.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/KeyPaths.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/KnownMetadata.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/LLVMSupport.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Metadata.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/MetadataLookup.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/MutexPThread.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/MutexWin32.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Numeric.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Once.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/Portability.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ProtocolConformance.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/RefCount.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/RuntimeInvocationsTracking.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/SwiftDtoa.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/OldDemangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/Demangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/NodePrinter.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/Context.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/ManglingUtils.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/Punycode.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/NodeDumper.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ErrorObject.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/SwiftObject.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/SwiftValue.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ReflectionMirror.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/ObjCRuntimeGetImageNameFromClass.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/OldRemangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/Remangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-macosx-x86_64.dir/__/__/__/lib/Demangling/TypeDecoder.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/Assert.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/CommandLine.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/GlobalObjects.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/LibcShims.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/Random.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/Stubs.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/ThreadLocalStorage.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/MathStubs.cpp.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/Availability.mm.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/FoundationHelpers.mm.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/OptionalBridgingHelper.mm.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/Reflection.mm.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/SwiftNativeNSXXXBaseARC.m.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/8/SwiftNativeNSXXXBase.mm.o stdlib/public/stubs/CMakeFiles/swiftStdlibStubs-macosx-x86_64.dir/UnicodeNormalization.cpp.o -L/Users/carlpeto/avr/swift/build/Ninja-ReleaseAssert/llvm-macosx-x86_64/./lib -framework Foundation -framework CoreFoundation -licucore && :
ld: in section __TEXT,__const reloc 5290: length != 2 and X86_64_RELOC_GOT not supported file 'stdlib/public/core/macosx/x86_64/Swift.o' for architecture x86_64
clang-7: error: linker command failed with exit code 1 (use -v to see invocation)
[113/677] Compiling /Users/carlpeto/avr/swift/build/Ninja-ReleaseAssert/swift-macosx-x86_64/stdlib/public/SDK/Foundation/macosx/x86_64/Foundation.o
ninja: build stopped: subcommand failed.
utils/build-script: fatal error: command terminated with a non-zero exit status 1, aborting...

It looks like libswiftCore.dylib can't be linked. Can anyone suggest why this seemingly innocuous patch is causing the build to fail?

My build command is utils/build-script -R --build-swift-static-stdlib TRUE but it's the same if I do debug builds, include tests or not, clean, reconfigure, etc. etc.

You're changing RelativeAddressTy from i32 to the target-specific type SizeTy, which is i64 on 64-bit targets. Mach-O doesn't support a full-width pointer subtraction relocation on x86-64, so LLVM doesn't know how to emit that constant.

Probably the right fix for now is to set RelativeAddressTy to the min of i32 or SizeTy.

That makes sense. It was an issue with not being able to emit a valid relocation for AVR that first led me to try and fix some of the incompatibilities in the swift compiler.

I think I hadn't thought through the full process of what is being built here, llvm/clang, then swiftc, then the standard library is built using those tools, meaning my "innocuous patch" is being used as part of the toolchain itself for the last part of the build process. In this case the compiler is emitting fixups/relocations (I am still too n00b to always understand the difference, linking is one of the parts of toolchains I am still most vague about).

As I understand it from what you've said, swiftc goes to compile the standard library swift, lowers it to SIL and then attempts to emit LLVM IR. At that point, it uses the target specific parts of LLVM for x86_64 on macOS (machO object files/shared libraries). These are unable to lower the LLVM IR into relocations/fixups in the shared library, so it borks with an error.

In my old toolchain, I was lowering swift to LLVM IR for x86_64/machO, output in a text file, then attempting to lower that to AVR machine code using llc. It broke in a similar way because it couldn't generate suitable relocations on AVR.

I think your idea of using the minimum of pointer length and i32 seems like the best plan for now.

It feels like a bit of a rough area in IR generation though, like we have secret, architecture specific compromises in the IR generation, like somehow LLVM should have some abstractions added to deal with this that we can use that would wrap up the idea of these relative offsets in abstract terms that can be lowered appropriately on each platform. Maybe when I've been doing this a few more years, and understand it all better, I'll take a look. :slight_smile:

The main thing is that your "innocuous change" is in fact a huge difference in the layout of those types on 64-bit targets. That it happened to blow up in LLVM is not quite a coincidence but also not the core thing.

Yes. That makes sense. Thanks very much for your help!