[LLVMdev] [RFC PATCH] X32 ABI support for Clang/compiler-rt (compiler-rt patch)

Steven Newbury
Thu, 22 Aug 2013 06:09:30 -0000

X32 support patch for compiler-rt.  Applies against current trunk.

--- projects/compiler-rt/make/platform/clang_linux.mk~	2013-08-21
06:27:38.000000000 +0000
+++ projects/compiler-rt/make/platform/clang_linux.mk	2013-08-21
11:16:55.891621025 +0000
@@ -41,7 +41,18 @@
     SupportedArches += x86_64
   endif
 else
-  SupportedArches := x86_64
+  # x86-64 arch has two ABIs 64 bit x86-64 and 32 bit x32
+  ifeq ($(lastword $(subst -gnu, ,$(CompilerTargetTriple))),x32)
+    SupportedArches := x32
+    ifeq ($(call TryCompile,$(CC),$(test_source),-m64),0)
+      SupportedArches += x86_64
+    endif
+  else
+    SupportedArches := x86_64
+    ifeq ($(call TryCompile,$(CC),$(test_source),-mx32),0)
+      SupportedArches += x32
+    endif
+  endif
   ifeq ($(call TryCompile,$(CC),$(test_source),-m32),0)
     SupportedArches += i386
   endif
@@ -74,6 +85,22 @@
 Arch.lsan-x86_64 := x86_64
 endif

+# Build runtime libraries for x32.
+ifeq ($(call contains,$(SupportedArches),x32),true)
+Configs += full-x32 profile-x32 san-x32 asan-x32 tsan-x32 \
+           msan-x32 ubsan-x32 ubsan_cxx-x32 dfsan-x32 lsan-x32
+Arch.full-x32 := x32
+Arch.profile-x32 := x32
+Arch.san-x32 := x32
+Arch.asan-x32 := x32
+Arch.tsan-x32 := x32
+Arch.msan-x32 := x32
+Arch.ubsan-x32 := x32
+Arch.ubsan_cxx-x32 := x32
+Arch.dfsan-x32 := x32
+Arch.lsan-x32 := x32
+endif
+
 ifneq ($(LLVM_ANDROID_TOOLCHAIN_DIR),)
 Configs += asan-arm-android
 Arch.asan-arm-android := arm-android
@@ -89,22 +116,33 @@

 CFLAGS.full-i386 := $(CFLAGS) -m32
 CFLAGS.full-x86_64 := $(CFLAGS) -m64
+CFLAGS.full-x32 := $(CFLAGS) -mx32
 CFLAGS.profile-i386 := $(CFLAGS) -m32
 CFLAGS.profile-x86_64 := $(CFLAGS) -m64
+CFLAGS.profile-x32 := $(CFLAGS) -mx32
 CFLAGS.san-i386 := $(CFLAGS) -m32 $(SANITIZER_CFLAGS) -fno-rtti
 CFLAGS.san-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS) -fno-rtti
+CFLAGS.san-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS) -fno-rtti
 CFLAGS.asan-i386 := $(CFLAGS) -m32 $(SANITIZER_CFLAGS) -fno-rtti \
                     -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1
 CFLAGS.asan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS) -fno-rtti \
                     -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1
+CFLAGS.asan-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS) -fno-rtti \
+                    -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1
 CFLAGS.tsan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS) -fno-rtti
+CFLAGS.tsan-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS) -fno-rtti
 CFLAGS.msan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS) -fno-rtti
+CFLAGS.msan-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS) -fno-rtti
 CFLAGS.ubsan-i386 := $(CFLAGS) -m32 $(SANITIZER_CFLAGS) -fno-rtti
 CFLAGS.ubsan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS) -fno-rtti
+CFLAGS.ubsan-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS) -fno-rtti
 CFLAGS.ubsan_cxx-i386 := $(CFLAGS) -m32 $(SANITIZER_CFLAGS)
 CFLAGS.ubsan_cxx-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS)
+CFLAGS.ubsan_cxx-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS)
 CFLAGS.dfsan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS)
+CFLAGS.dfsan-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS)
 CFLAGS.lsan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS)
+CFLAGS.lsan-x32 := $(CFLAGS) -mx32 $(SANITIZER_CFLAGS)

 SHARED_LIBRARY.asan-arm-android := 1
 ANDROID_COMMON_FLAGS := -target arm-linux-androideabi \
@@ -120,30 +158,45 @@
 # enough support to build the sanitizers or profile runtimes.
 CFLAGS.full-i386 += --sysroot=$(ProjSrcRoot)/SDKs/linux
 CFLAGS.full-x86_64 += --sysroot=$(ProjSrcRoot)/SDKs/linux
+CFLAGS.full-x32 += --sysroot=$(ProjSrcRoot)/SDKs/linux

 FUNCTIONS.full-i386 := $(CommonFunctions) $(ArchFunctions.i386)
 FUNCTIONS.full-x86_64 := $(CommonFunctions) $(ArchFunctions.x86_64)
+FUNCTIONS.full-x32 := $(CommonFunctions) $(ArchFunctions.x32)
 FUNCTIONS.profile-i386 := GCDAProfiling
 FUNCTIONS.profile-x86_64 := GCDAProfiling
+FUNCTIONS.profile-x32 := GCDAProfiling
 FUNCTIONS.san-i386 := $(SanitizerCommonFunctions)
 FUNCTIONS.san-x86_64 := $(SanitizerCommonFunctions)
+FUNCTIONS.san-x32 := $(SanitizerCommonFunctions)
 FUNCTIONS.asan-i386 := $(AsanFunctions) $(InterceptionFunctions) \
                                         $(SanitizerCommonFunctions)
 FUNCTIONS.asan-x86_64 := $(AsanFunctions) $(InterceptionFunctions) \
                          $(SanitizerCommonFunctions)
$(LsanCommonFunctions)
+FUNCTIONS.asan-x32 := $(AsanFunctions) $(InterceptionFunctions) \
+                         $(SanitizerCommonFunctions)
$(LsanCommonFunctions)
 FUNCTIONS.asan-arm-android := $(AsanFunctions) $(InterceptionFunctions)
\
                                           $(SanitizerCommonFunctions)
 FUNCTIONS.tsan-x86_64 := $(TsanFunctions) $(InterceptionFunctions) \
                                           $(SanitizerCommonFunctions)
+FUNCTIONS.tsan-x32 := $(TsanFunctions) $(InterceptionFunctions) \
+                                          $(SanitizerCommonFunctions)
 FUNCTIONS.msan-x86_64 := $(MsanFunctions) $(InterceptionFunctions) \
                                           $(SanitizerCommonFunctions)
+FUNCTIONS.msan-x32 := $(MsanFunctions) $(InterceptionFunctions) \
+                                          $(SanitizerCommonFunctions)
 FUNCTIONS.ubsan-i386 := $(UbsanFunctions)
 FUNCTIONS.ubsan-x86_64 := $(UbsanFunctions)
+FUNCTIONS.ubsan-x32 := $(UbsanFunctions)
 FUNCTIONS.ubsan_cxx-i386 := $(UbsanCXXFunctions)
 FUNCTIONS.ubsan_cxx-x86_64 := $(UbsanCXXFunctions)
+FUNCTIONS.ubsan_cxx-x32 := $(UbsanCXXFunctions)
 FUNCTIONS.dfsan-x86_64 := $(DfsanFunctions) $(SanitizerCommonFunctions)
+FUNCTIONS.dfsan-x32 := $(DfsanFunctions) $(SanitizerCommonFunctions)
 FUNCTIONS.lsan-x86_64 := $(LsanFunctions) $(InterceptionFunctions) \
                                           $(SanitizerCommonFunctions)
+FUNCTIONS.lsan-x32 := $(LsanFunctions) $(InterceptionFunctions) \
+                                          $(SanitizerCommonFunctions)

 # Always use optimized variants.
 OPTIMIZED := 1
--- tools/clang/runtime/compiler-rt/Makefile.orig	2013-08-21
16:20:43.915932247 +0000
+++ tools/clang/runtime/compiler-rt/Makefile	2013-08-21
17:03:15.856154519 +0000
@@ -96,29 +96,66 @@
     $(1) $$cflags $(2) -o /dev/null > /dev/null 2> /dev/null ; \
     echo $$?)

-# We try to build 32-bit runtimes both on 32-bit hosts and 64-bit
hosts.
-Runtime32BitConfigs = \
+# We try to build x86 runtimes both on x86 hosts and 64-bit hosts.
+Runtimex86Configs = \
 	full-i386.a profile-i386.a san-i386.a asan-i386.a ubsan-i386.a \
 	ubsan_cxx-i386.a

+Runtime64BitConfigs = \
+	full-x86_64.a profile-x86_64.a san-x86_64.a asan-x86_64.a \
+	tsan-x86_64.a msan-x86_64.a ubsan-x86_64.a ubsan_cxx-x86_64.a \
+	dfsan-x86_64.a lsan-x86_64.a
+
+Runtimex32Configs += \
+	full-x32.a profile-x32.a san-x32.a asan-x32.a \
+	tsan-x32.a msan-x32.a ubsan-x32.a ubsan_cxx-x32.a \
+	dfsan-x32.a lsan-x32.a
+
+
 # We currently only try to generate runtime libraries on x86.
 ifeq ($(ARCH),x86)
-RuntimeLibrary.linux.Configs += $(Runtime32BitConfigs)
+RuntimeLibrary.linux.Configs += $(Runtimex86Configs)
+
+ifneq ($(LLVM_ANDROID_TOOLCHAIN_DIR),)
+RuntimeLibrary.linux.Configs += asan-arm-android.so
+endif
 endif

 ifeq ($(ARCH),x86_64)
-RuntimeLibrary.linux.Configs += \
-	full-x86_64.a profile-x86_64.a san-x86_64.a asan-x86_64.a \
-	tsan-x86_64.a msan-x86_64.a ubsan-x86_64.a ubsan_cxx-x86_64.a \
-	dfsan-x86_64.a lsan-x86_64.a
-# We need to build 32-bit ASan/UBsan libraries on 64-bit platform, and
add them
+CompilerTargetTriple := $(shell \
+	$(CC) -v 2>&1 | grep 'Target:' | cut -d' ' -f2)
+ifeq ($(CompilerTargetTriple),)
+$(error "unable to infer compiler target triple for $(CC)")
+endif
+ifeq ($(lastword $(subst -gnu, ,$(CompilerTargetTriple))),x32)
+ARCH=x32
+RuntimeLibrary.linux.Configs += $(Runtimex32Configs)
+# We need to build x86 ASan/UBsan libraries on x32 platform, and add
them
 # to the list of runtime libraries to make
-# "clang -fsanitize=(address|undefined) -m32" work.
-# We check that Clang can produce working 32-bit binaries by compiling
a simple
+# "clang -fsanitize=(address|undefined) -m32/-m64" work.
+# We check that Clang can produce working 32/64-bit binaries by
compiling a simple
 # executable.
 test_source
$(LLVM_SRC_ROOT)/tools/clang/runtime/compiler-rt/clang_linux_test_input.c
+ifeq ($(call TryCompile,$(ToolDir)/clang,$(test_source),-m64),0)
+RuntimeLibrary.linux.Configs += $(Runtime64BitConfigs)
+endif
 ifeq ($(call TryCompile,$(ToolDir)/clang,$(test_source),-m32),0)
-RuntimeLibrary.linux.Configs += $(Runtime32BitConfigs)
+RuntimeLibrary.linux.Configs += $(Runtimex86Configs)
+endif
+else
+RuntimeLibrary.linux.Configs += $(Runtime64BitConfigs)
+# We need to build x86/x32 ASan/UBsan libraries on 64-bit platform, and
add them
+# to the list of runtime libraries to make
+# "clang -fsanitize=(address|undefined) -m32/-mx32" work.
+# We check that Clang can produce working x86 binaries by compiling a
simple
+# executable.
+test_source
$(LLVM_SRC_ROOT)/tools/clang/runtime/compiler-rt/clang_linux_test_input.c
+ifeq ($(call TryCompile,$(ToolDir)/clang,$(test_source),-m32),0)
+RuntimeLibrary.linux.Configs += $(Runtimex86Configs)
+endif
+ifeq ($(call TryCompile,$(ToolDir)/clang,$(test_source),-mx32),0)
+RuntimeLibrary.linux.Configs += $(Runtimex32Configs)
+endif
 endif
 ifneq ($(LLVM_ANDROID_TOOLCHAIN_DIR),)
 RuntimeLibrary.linux.Configs += asan-arm-android.so