From 32b92669e4ec83005eff2641b092f25be09373b8 Mon Sep 17 00:00:00 2001 From: Amit Aryeh Levy Date: Tue, 25 Apr 2017 20:05:51 -0400 Subject: [PATCH 1/2] Add RWPI/ROPI relocation model support Adds support for using LLVM 4's ROPI and RWPI relocation models for ARM --- src/librustc_llvm/ffi.rs | 3 +++ src/librustc_trans/back/write.rs | 5 ++++- src/rustllvm/PassWrapper.cpp | 19 +++++++++++++++---- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 402166cc13f..a9a8ee93df1 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -288,6 +288,9 @@ pub enum RelocMode { Static = 1, PIC = 2, DynamicNoPic = 3, + ROPI = 4, + RWPI = 5, + ROPI_RWPI = 6, } /// LLVMRustCodeModel diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index ccb3f7ac882..3492403a1bf 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -37,11 +37,14 @@ use std::sync::mpsc::channel; use std::thread; use libc::{c_uint, c_void}; -pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 4] = [ +pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [ ("pic", llvm::RelocMode::PIC), ("static", llvm::RelocMode::Static), ("default", llvm::RelocMode::Default), ("dynamic-no-pic", llvm::RelocMode::DynamicNoPic), + ("ropi", llvm::RelocMode::ROPI), + ("rwpi", llvm::RelocMode::RWPI), + ("ropi-rwpi", llvm::RelocMode::ROPI_RWPI), ]; pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeModel); 5] = [ diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index c410a6b1349..1e19e28e78a 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -290,7 +290,7 @@ extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) { extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( const char *TripleStr, const char *CPU, const char *Feature, - LLVMRustCodeModel RustCM, LLVMRelocMode Reloc, + LLVMRustCodeModel RustCM, int Reloc, LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat, bool PositionIndependentExecutable, bool FunctionSections, bool DataSections) { @@ -304,15 +304,26 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( auto OptLevel = fromRust(RustOptLevel); switch (Reloc) { - case LLVMRelocStatic: + case 1: RM = Reloc::Static; break; - case LLVMRelocPIC: + case 2: RM = Reloc::PIC_; break; - case LLVMRelocDynamicNoPic: + case 3: RM = Reloc::DynamicNoPIC; break; +#if LLVM_VERSION_GE(4, 0) + case 4: + RM = Reloc::ROPI; + break; + case 5: + RM = Reloc::RWPI; + break; + case 6: + RM = Reloc::ROPI_RWPI; + break; +#endif default: #if LLVM_VERSION_LE(3, 8) RM = Reloc::Default; From 0f00f27e0d4743b14f7c0d0fca9731a45eae487a Mon Sep 17 00:00:00 2001 From: Amit Aryeh Levy Date: Fri, 28 Apr 2017 17:21:59 -0500 Subject: [PATCH 2/2] Added LLVMRustRelocMode Replaces the llvm-c exposed LLVMRelocMode, which does not include all relocation model variants, with a LLVMRustRelocMode modeled after LLVMRustCodeMode. --- src/librustc_llvm/ffi.rs | 14 +++---- src/rustllvm/PassWrapper.cpp | 77 ++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index a9a8ee93df1..5cb5a62c93b 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -284,13 +284,13 @@ pub enum CodeGenOptLevel { #[derive(Copy, Clone, PartialEq)] #[repr(C)] pub enum RelocMode { - Default = 0, - Static = 1, - PIC = 2, - DynamicNoPic = 3, - ROPI = 4, - RWPI = 5, - ROPI_RWPI = 6, + Default, + Static, + PIC, + DynamicNoPic, + ROPI, + RWPI, + ROPI_RWPI, } /// LLVMRustCodeModel diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 1e19e28e78a..f91145fbb5e 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -239,6 +239,47 @@ static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) { } } +enum class LLVMRustRelocMode { + Default, + Static, + PIC, + DynamicNoPic, + ROPI, + RWPI, + ROPIRWPI, +}; + +#if LLVM_VERSION_LE(3, 8) +static Reloc::Model fromRust(LLVMRustRelocMode RustReloc) { +#else +static Optional fromRust(LLVMRustRelocMode RustReloc) { +#endif + switch (RustReloc) { + case LLVMRustRelocMode::Default: +#if LLVM_VERSION_LE(3, 8) + return Reloc::Default; +#else + return None; +#endif + case LLVMRustRelocMode::Static: + return Reloc::Static; + case LLVMRustRelocMode::PIC: + return Reloc::PIC_; + case LLVMRustRelocMode::DynamicNoPic: + return Reloc::DynamicNoPIC; +#if LLVM_VERSION_GE(4, 0) + case LLVMRustRelocMode::ROPI: + return Reloc::ROPI; + case LLVMRustRelocMode::RWPI: + return Reloc::RWPI; + case LLVMRustRelocMode::ROPIRWPI: + return Reloc::ROPI_RWPI; +#endif + default: + llvm_unreachable("Bad RelocModel."); + } +} + #if LLVM_RUSTLLVM /// getLongestEntryLength - Return the length of the longest entry in the table. /// @@ -290,46 +331,14 @@ extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) { extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( const char *TripleStr, const char *CPU, const char *Feature, - LLVMRustCodeModel RustCM, int Reloc, + LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc, LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat, bool PositionIndependentExecutable, bool FunctionSections, bool DataSections) { -#if LLVM_VERSION_LE(3, 8) - Reloc::Model RM; -#else - Optional RM; -#endif auto CM = fromRust(RustCM); auto OptLevel = fromRust(RustOptLevel); - - switch (Reloc) { - case 1: - RM = Reloc::Static; - break; - case 2: - RM = Reloc::PIC_; - break; - case 3: - RM = Reloc::DynamicNoPIC; - break; -#if LLVM_VERSION_GE(4, 0) - case 4: - RM = Reloc::ROPI; - break; - case 5: - RM = Reloc::RWPI; - break; - case 6: - RM = Reloc::ROPI_RWPI; - break; -#endif - default: -#if LLVM_VERSION_LE(3, 8) - RM = Reloc::Default; -#endif - break; - } + auto RM = fromRust(RustReloc); std::string Error; Triple Trip(Triple::normalize(TripleStr));