From 771023dbcb5dbf2e967f064021ecf0d8e8acf6de Mon Sep 17 00:00:00 2001 From: Venkatraman Govindaraju Date: Wed, 29 Jan 2014 04:51:35 +0000 Subject: [PATCH] [Sparc] Use %r_disp32 for pc_rel entries in gcc_except_table and eh_frame. Otherwise, assembler (gas) fails to assemble them with error message "operation combines symbols in different segments". This is because MC computes pc_rel entries with subtract expression between labels from different sections. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200373 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/CMakeLists.txt | 1 + .../Sparc/MCTargetDesc/SparcMCAsmInfo.cpp | 13 ++++++ .../Sparc/MCTargetDesc/SparcMCAsmInfo.h | 15 ++++--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp | 4 ++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h | 1 + lib/Target/Sparc/SparcISelLowering.cpp | 3 +- lib/Target/Sparc/SparcTargetObjectFile.cpp | 43 +++++++++++++++++++ lib/Target/Sparc/SparcTargetObjectFile.h | 34 +++++++++++++++ test/CodeGen/SPARC/exception.ll | 29 ++++++++++++- 9 files changed, 134 insertions(+), 9 deletions(-) create mode 100644 lib/Target/Sparc/SparcTargetObjectFile.cpp create mode 100644 lib/Target/Sparc/SparcTargetObjectFile.h diff --git a/lib/Target/Sparc/CMakeLists.txt b/lib/Target/Sparc/CMakeLists.txt index 4a906e597de..cebda920e74 100644 --- a/lib/Target/Sparc/CMakeLists.txt +++ b/lib/Target/Sparc/CMakeLists.txt @@ -27,6 +27,7 @@ add_llvm_target(SparcCodeGen SparcJITInfo.cpp SparcCodeEmitter.cpp SparcMCInstLower.cpp + SparcTargetObjectFile.cpp ) add_subdirectory(TargetInfo) diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp index e3f957fc4b2..856b4bbf5d1 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp @@ -12,7 +12,9 @@ //===----------------------------------------------------------------------===// #include "SparcMCAsmInfo.h" +#include "SparcMCExpr.h" #include "llvm/ADT/Triple.h" +#include "llvm/MC/MCStreamer.h" using namespace llvm; @@ -42,4 +44,15 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT) { UsesELFSectionDirectiveForBSS = true; } +const MCExpr* +SparcELFMCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const { + if (Encoding & dwarf::DW_EH_PE_pcrel) { + MCContext &Ctx = Streamer.getContext(); + return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32, + MCSymbolRefExpr::Create(Sym, Ctx), Ctx); + } + return MCAsmInfo::getExprForPersonalitySymbol(Sym, Encoding, Streamer); +} diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h b/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h index 1e58e37ce14..71dcf6bec35 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h @@ -17,13 +17,16 @@ #include "llvm/MC/MCAsmInfoELF.h" namespace llvm { - class StringRef; +class StringRef; - class SparcELFMCAsmInfo : public MCAsmInfoELF { - virtual void anchor(); - public: - explicit SparcELFMCAsmInfo(StringRef TT); - }; +class SparcELFMCAsmInfo : public MCAsmInfoELF { + virtual void anchor(); +public: + explicit SparcELFMCAsmInfo(StringRef TT); + virtual const MCExpr* getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const; +}; } // namespace llvm diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp index 103a5a012bc..45f2f9f11e4 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp @@ -41,6 +41,7 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const case VK_Sparc_L44: OS << "%l44("; break; case VK_Sparc_HH: OS << "%hh("; break; case VK_Sparc_HM: OS << "%hm("; break; + case VK_Sparc_R_DISP32: OS << "%r_disp32("; break; case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break; case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break; case VK_Sparc_TLS_GD_ADD: OS << "%tgd_add("; break; @@ -77,6 +78,7 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name) .Case("l44", VK_Sparc_L44) .Case("hh", VK_Sparc_HH) .Case("hm", VK_Sparc_HM) + .Case("r_disp32", VK_Sparc_R_DISP32) .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22) .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10) .Case("tgd_add", VK_Sparc_TLS_GD_ADD) @@ -101,6 +103,8 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name) bool SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const { + if (!Layout) + return false; return getSubExpr()->EvaluateAsRelocatable(Res, *Layout); } diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h index c156ea03512..f1995171864 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h @@ -31,6 +31,7 @@ public: VK_Sparc_L44, VK_Sparc_HH, VK_Sparc_HM, + VK_Sparc_R_DISP32, VK_Sparc_TLS_GD_HI22, VK_Sparc_TLS_GD_LO10, VK_Sparc_TLS_GD_ADD, diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index e782be3ebbd..75b0167acd5 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -17,6 +17,7 @@ #include "SparcMachineFunctionInfo.h" #include "SparcRegisterInfo.h" #include "SparcTargetMachine.h" +#include "SparcTargetObjectFile.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -1363,7 +1364,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { } SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) - : TargetLowering(TM, new TargetLoweringObjectFileELF()) { + : TargetLowering(TM, new SparcELFTargetObjectFile()) { Subtarget = &TM.getSubtarget(); // Set up the register classes. diff --git a/lib/Target/Sparc/SparcTargetObjectFile.cpp b/lib/Target/Sparc/SparcTargetObjectFile.cpp new file mode 100644 index 00000000000..4913ea75fd9 --- /dev/null +++ b/lib/Target/Sparc/SparcTargetObjectFile.cpp @@ -0,0 +1,43 @@ +//===------- SparcTargetObjectFile.cpp - Sparc Object Info Impl -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SparcTargetObjectFile.h" +#include "MCTargetDesc/SparcMCExpr.h" +#include "llvm/CodeGen/MachineModuleInfoImpls.h" +#include "llvm/Support/Dwarf.h" + +using namespace llvm; + + +const MCExpr *SparcELFTargetObjectFile:: +getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding, + MCStreamer &Streamer) const { + + if (Encoding & dwarf::DW_EH_PE_pcrel) { + MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo(); + + MCSymbol *SSym = getSymbolWithGlobalValueBase(*Mang, GV, ".DW.stub"); + + // Add information about the stub reference to ELFMMI so that the stub + // gets emitted by the asmprinter. + MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); + if (StubSym.getPointer() == 0) { + MCSymbol *Sym = getSymbol(*Mang, GV); + StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); + } + + MCContext &Ctx = getContext(); + return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32, + MCSymbolRefExpr::Create(SSym, Ctx), Ctx); + } + + return TargetLoweringObjectFileELF:: + getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer); +} diff --git a/lib/Target/Sparc/SparcTargetObjectFile.h b/lib/Target/Sparc/SparcTargetObjectFile.h new file mode 100644 index 00000000000..7cf850de160 --- /dev/null +++ b/lib/Target/Sparc/SparcTargetObjectFile.h @@ -0,0 +1,34 @@ +//===-- SparcTargetObjectFile.h - Sparc Object Info -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_SPARC_TARGETOBJECTFILE_H +#define LLVM_TARGET_SPARC_TARGETOBJECTFILE_H + +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" + +namespace llvm { + +class MCContext; +class TargetMachine; + +class SparcELFTargetObjectFile : public TargetLoweringObjectFileELF { +public: + SparcELFTargetObjectFile() : + TargetLoweringObjectFileELF() + {} + + const MCExpr * + getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding, + MCStreamer &Streamer) const; +}; + +} // end namespace llvm + +#endif diff --git a/test/CodeGen/SPARC/exception.ll b/test/CodeGen/SPARC/exception.ll index edc9d59e569..d6044e199f5 100644 --- a/test/CodeGen/SPARC/exception.ll +++ b/test/CodeGen/SPARC/exception.ll @@ -1,7 +1,9 @@ ; RUN: llc < %s -march=sparc -relocation-model=static | FileCheck -check-prefix=V8ABS %s ; RUN: llc < %s -march=sparc -relocation-model=pic | FileCheck -check-prefix=V8PIC %s +; RUN: llc < %s -march=sparc -relocation-model=pic -disable-cfi | FileCheck -check-prefix=V8PIC_NOCFI %s ; RUN: llc < %s -march=sparcv9 -relocation-model=static | FileCheck -check-prefix=V9ABS %s ; RUN: llc < %s -march=sparcv9 -relocation-model=pic | FileCheck -check-prefix=V9PIC %s +; RUN: llc < %s -march=sparcv9 -relocation-model=pic -disable-cfi | FileCheck -check-prefix=V9PIC_NOCFI %s %struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo } @@ -40,11 +42,23 @@ ; V8PIC: .cfi_register 15, 31 ; V8PIC: .section .gcc_except_table ; V8PIC-NOT: .section -; V8PIC: .word .L_ZTIi.DW.stub- +; V8PIC: .word %r_disp32(.L_ZTIi.DW.stub) ; V8PIC: .data ; V8PIC: .L_ZTIi.DW.stub: ; V8PIC-NEXT: .word _ZTIi +; V8PIC_NOCFI-LABEL: main: +; V8PIC_NOCFI: .section .gcc_except_table +; V8PIC_NOCFI-NOT: .section +; V8PIC_NOCFI: .word %r_disp32(.L_ZTIi.DW.stub) +; V8PIC_NOCFI: .data +; V8PIC_NOCFI: .L_ZTIi.DW.stub: +; V8PIC_NOCFI-NEXT: .word _ZTIi +; V8PIC_NOCFI: .section .eh_frame +; V8PIC_NOCFI-NOT: .section +; V8PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0) + + ; V9ABS-LABEL: main: ; V9ABS: .cfi_startproc ; V9ABS: .cfi_personality 0, __gxx_personality_v0 @@ -65,11 +79,22 @@ ; V9PIC: .cfi_register 15, 31 ; V9PIC: .section .gcc_except_table ; V9PIC-NOT: .section -; V9PIC: .word .L_ZTIi.DW.stub- +; V9PIC: .word %r_disp32(.L_ZTIi.DW.stub) ; V9PIC: .data ; V9PIC: .L_ZTIi.DW.stub: ; V9PIC-NEXT: .xword _ZTIi +; V9PIC_NOCFI-LABEL: main: +; V9PIC_NOCFI: .section .gcc_except_table +; V9PIC_NOCFI-NOT: .section +; V9PIC_NOCFI: .word %r_disp32(.L_ZTIi.DW.stub) +; V9PIC_NOCFI: .data +; V9PIC_NOCFI: .L_ZTIi.DW.stub: +; V9PIC_NOCFI-NEXT: .xword _ZTIi +; V9PIC_NOCFI: .section .eh_frame +; V9PIC_NOCFI-NOT: .section +; V9PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0) + define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 { entry: %0 = icmp eq i32 %argc, 2