From ff7ccbf54a14cc8f1b05fb8fffb30d1831f4193d Mon Sep 17 00:00:00 2001
From: q66 <daniel@octaforge.org>
Date: Sat, 6 Jul 2019 02:34:29 +0200
Subject: [PATCH] llvm8: add a secureplt patch and fix build with gcc9 on/for
 ppc32

[ci skip]
---
 .../patches/llvm/llvm-003-secureplt.patch     | 99 +++++++++++++++++++
 .../patches/llvm/llvm-004-override-opt.patch  | 18 ++++
 srcpkgs/llvm8/template                        |  9 +-
 3 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 srcpkgs/llvm8/files/patches/llvm/llvm-003-secureplt.patch
 create mode 100644 srcpkgs/llvm8/files/patches/llvm/llvm-004-override-opt.patch

diff --git a/srcpkgs/llvm8/files/patches/llvm/llvm-003-secureplt.patch b/srcpkgs/llvm8/files/patches/llvm/llvm-003-secureplt.patch
new file mode 100644
index 00000000000..bfdc7d5557c
--- /dev/null
+++ b/srcpkgs/llvm8/files/patches/llvm/llvm-003-secureplt.patch
@@ -0,0 +1,99 @@
+Partially taken from Adélie Linux, even-more-secure-plt.patch
+--- a/lib/Target/PowerPC/PPCSubtarget.cpp
++++ b/lib/Target/PowerPC/PPCSubtarget.cpp
+@@ -138,6 +138,10 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
+   if (isDarwin())
+     HasLazyResolverStubs = true;
+ 
++  // Force SecurePlt for all 32-bit Linux targets
++  if (isTargetLinux() && !IsPPC64)
++    SecurePlt = true;
++
+   if (HasSPE && IsPPC64)
+     report_fatal_error( "SPE is only supported for 32-bit targets.\n", false);
+   if (HasSPE && (HasAltivec || HasQPX || HasVSX || HasFPU))
+--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
++++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
+@@ -218,6 +218,10 @@ static Reloc::Model getEffectiveRelocModel(const Triple &TT,
+   if (TT.getArch() == Triple::ppc64)
+     return Reloc::PIC_;
+ 
++  // We force SecurePlt on 32-bit ppc linux which requires PIC
++  if (TT.isOSLinux() && (TT.getArch() == Triple::ppc))
++    return Reloc::PIC_;
++
+   // Rest are static by default.
+   return Reloc::Static;
+ }
+
+--- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
++++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
+@@ -442,13 +442,22 @@
+   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
+   // come at the _end_ of the expression.
+   const MCOperand &Op = MI->getOperand(OpNo);
+-  const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*Op.getExpr());
+-  O << refExp.getSymbol().getName();
++  const MCSymbolRefExpr *RefExp = nullptr;
++  const MCConstantExpr *ConstExp = nullptr;
++  if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Op.getExpr())) {
++    RefExp = cast<MCSymbolRefExpr>(BinExpr->getLHS());
++    ConstExp = cast<MCConstantExpr>(BinExpr->getRHS());
++  } else
++    RefExp = cast<MCSymbolRefExpr>(Op.getExpr());
++
++  O << RefExp->getSymbol().getName();
+   O << '(';
+   printOperand(MI, OpNo+1, O);
+   O << ')';
+-  if (refExp.getKind() != MCSymbolRefExpr::VK_None)
+-    O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind());
++  if (RefExp->getKind() != MCSymbolRefExpr::VK_None)
++    O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
++  if (ConstExp != nullptr)
++    O << '+' << ConstExp->getValue();
+ }
+ 
+ /// showRegistersWithPercentPrefix - Check if this register name should be
+--- a/lib/Target/PowerPC/PPCAsmPrinter.cpp
++++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp
+@@ -487,8 +487,14 @@
+   if (!Subtarget->isPPC64() && !Subtarget->isDarwin() &&
+       isPositionIndependent())
+     Kind = MCSymbolRefExpr::VK_PLT;
+-  const MCSymbolRefExpr *TlsRef =
++  const MCExpr *TlsRef =
+     MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
++
++  // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
++  if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt())
++    TlsRef = MCBinaryExpr::createAdd(TlsRef,
++                                     MCConstantExpr::create(32768, OutContext),
++                                     OutContext);
+   const MachineOperand &MO = MI->getOperand(2);
+   const GlobalValue *GValue = MO.getGlobal();
+   MCSymbol *MOSymbol = getSymbol(GValue);
+--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
++++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+@@ -4054,7 +4054,20 @@
+     if (trySETCC(N))
+       return;
+     break;
+-
++  // These nodes will be transformed into GETtlsADDR32 node, which
++  // later becomes BL_TLS __tls_get_addr(sym at tlsgd)@PLT
++  case PPCISD::ADDI_TLSLD_L_ADDR:
++  case PPCISD::ADDI_TLSGD_L_ADDR: {
++    const Module *Mod = MF->getFunction().getParent();
++    if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) != MVT::i32 ||
++        !PPCSubTarget->isSecurePlt() || !PPCSubTarget->isTargetELF() ||
++        Mod->getPICLevel() == PICLevel::SmallPIC)
++      break;
++      // Attach global base pointer on GETtlsADDR32 node in order to
++      // generate secure plt code for TLS symbols.
++      getGlobalBaseReg();
++  }
++    break;
+   case PPCISD::CALL: {
+     const Module *M = MF->getFunction().getParent();
+ 
diff --git a/srcpkgs/llvm8/files/patches/llvm/llvm-004-override-opt.patch b/srcpkgs/llvm8/files/patches/llvm/llvm-004-override-opt.patch
new file mode 100644
index 00000000000..d4c74235b41
--- /dev/null
+++ b/srcpkgs/llvm8/files/patches/llvm/llvm-004-override-opt.patch
@@ -0,0 +1,18 @@
+This allows us to override the optimization level as not all platforms can
+deal with -O3.
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -847,6 +847,12 @@ if( MINGW AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
+   llvm_replace_compiler_option(CMAKE_CXX_FLAGS_RELEASE "-O3" "-O2")
+ endif()
+ 
++set(VOID_CXX_OPT_FLAGS "" CACHE STRING "Optimization level to use")
++
++if(NOT VOID_CXX_OPT_FLAGS STREQUAL "")
++  llvm_replace_compiler_option(CMAKE_CXX_FLAGS_RELEASE "-O3" "${VOID_CXX_OPT_FLAGS}")
++endif()
++
+ # Put this before tblgen. Else we have a circular dependence.
+ add_subdirectory(lib/Demangle)
+ add_subdirectory(lib/Support)
diff --git a/srcpkgs/llvm8/template b/srcpkgs/llvm8/template
index cc26eb18f89..450444355d7 100644
--- a/srcpkgs/llvm8/template
+++ b/srcpkgs/llvm8/template
@@ -1,7 +1,7 @@
 # Template file for 'llvm8'
 pkgname=llvm8
 version=8.0.0
-revision=4
+revision=5
 wrksrc="llvm-${version}.src"
 build_style=cmake
 configure_args="
@@ -105,6 +105,13 @@ pre_configure() {
 	CFLAGS=${CFLAGS/ -g/ -g1}
 	CXXFLAGS=${CXXFLAGS/ -g/ -g1}
 
+	# since gcc9, the build likes to blow up for ppc32 apparently because
+	# of clang being too large for a 24-bit relative call to the PLT, so
+	# optimize for size instead
+	case "$XBPS_TARGET_MACHINE" in
+		ppc|ppc-musl) configure_args+=" -DVOID_CXX_OPT_FLAGS=-Os" ;;
+	esac
+
 	if [ "$CROSS_BUILD" ]; then
 		msg_normal "Building host tblgen\n"
 		mkdir -p build/HOST
