diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -178,6 +178,9 @@ MCSection *getSectionForJumpTable(const Function &F, const TargetMachine &TM) const override; + bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, + const Function &F) const override; + /// Emit Obj-C garbage collection and linker options. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -71,6 +71,10 @@ using namespace llvm; using namespace dwarf; +static cl::opt JumpTableInFunctionSection( + "jumptable-in-function-section", cl::Hidden, cl::init(false), + cl::desc("Putting Jump Table in function section")); + static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, StringRef &Section) { SmallVector ModuleFlags; @@ -1777,6 +1781,17 @@ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); } +bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection( + bool UsesLabelDifference, const Function &F) const { + if (!JumpTableInFunctionSection) { + // We can always create relative relocations, so use another section + // that can be marked non-executable. + return false; + } + return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( + UsesLabelDifference, F); +} + void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { emitLinkerDirectives(Streamer, M); diff --git a/llvm/test/MC/COFF/jumptable-rdata.ll b/llvm/test/MC/COFF/jumptable-rdata.ll new file mode 100644 --- /dev/null +++ b/llvm/test/MC/COFF/jumptable-rdata.ll @@ -0,0 +1,29 @@ +; RUN: llc -mtriple x86_64-pc-win32 < %s | FileCheck %s + +define void @switch_jumptable(i32 %what) nounwind { +entry: + switch i32 %what, label %sw.epilog [ + i32 0, label %sw.bb + i32 1, label %sw.bb + i32 2, label %sw.bb + i32 3, label %sw.bb14 + i32 4, label %sw.bb18 + i32 6, label %sw.bb57 + ] + +sw.bb: ; preds = %entry, %entry, %entry + ret void + +sw.bb14: ; preds = %entry + ret void + +sw.bb18: ; preds = %entry + ret void + +sw.bb57: ; preds = %entry + ret void + +sw.epilog: ; preds = %entry + ret void +} +; CHECK: .section .rdata