From 34982576a43887e7f062ed0a3571af2cbab003f3 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Thu, 26 Jan 2012 09:25:43 +0000 Subject: [PATCH] Add support for the R_ARM_TARGET1 relocation, which should be given to relocations applied to all C++ constructors and destructors. This enables the linker to match concrete relocation types (absolute or relative) with whatever library or C++ support code is being linked against. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149057 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 6 ++++++ include/llvm/MC/MCExpr.h | 1 + lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +- lib/MC/MCExpr.cpp | 4 +++- lib/Target/ARM/ARMAsmPrinter.cpp | 16 ++++++++++++++++ lib/Target/ARM/ARMAsmPrinter.h | 1 + .../ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 5 ++++- test/MC/ARM/cxx-global-constructor.ll | 12 ++++++++++++ 8 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 test/MC/ARM/cxx-global-constructor.ll diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 285c7690ce3..303c6c21f42 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -268,6 +268,12 @@ namespace llvm { virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); + /// EmitXXStructor - Targets can override this to change how global constants + /// that are part of a C++ static/global constructor list are emitted. + virtual void EmitXXStructor(const Constant *CV) { + EmitGlobalConstant(CV); + } + /// isBlockOnlyReachableByFallthough - Return true if the basic block has /// exactly one predecessor and the control transfer mechanism between /// the predecessor and this block is a fall-through. diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 6f156b28447..093278395f6 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -169,6 +169,7 @@ public: VK_ARM_GOTOFF, VK_ARM_TPOFF, VK_ARM_GOTTPOFF, + VK_ARM_TARGET1, VK_PPC_TOC, VK_PPC_DARWIN_HA16, // ha16(symbol) diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d67b164fb8d..38638674866 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1296,7 +1296,7 @@ void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) { OutStreamer.SwitchSection(OutputSection); if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection()) EmitAlignment(Align); - EmitGlobalConstant(Structors[i].second); + EmitXXStructor(Structors[i].second); } } diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 455c03d1614..9a19f6deba8 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -58,7 +58,8 @@ void MCExpr::print(raw_ostream &OS) const { SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOT || SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTOFF || SRE.getKind() == MCSymbolRefExpr::VK_ARM_TPOFF || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF) + SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF || + SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1) OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); else if (SRE.getKind() != MCSymbolRefExpr::VK_None && SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 && @@ -193,6 +194,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_ARM_TPOFF: return "(tpoff)"; case VK_ARM_GOTTPOFF: return "(gottpoff)"; case VK_ARM_TLSGD: return "(tlsgd)"; + case VK_ARM_TARGET1: return "(target1)"; case VK_PPC_TOC: return "toc"; case VK_PPC_DARWIN_HA16: return "ha16"; case VK_PPC_DARWIN_LO16: return "lo16"; diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 288b7f14e4c..cc3e01fe253 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -299,6 +299,22 @@ void ARMAsmPrinter::EmitFunctionEntryLabel() { OutStreamer.EmitLabel(CurrentFnSym); } +void ARMAsmPrinter::EmitXXStructor(const Constant *CV) { + uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); + assert(Size && "C++ constructor pointer had zero size!"); + + const GlobalValue *GV = dyn_cast(CV); + assert(GV && "C++ constructor pointer was not a GlobalValue!"); + + const MCExpr *E = MCSymbolRefExpr::Create(Mang->getSymbol(GV), + (Subtarget->isTargetDarwin() + ? MCSymbolRefExpr::VK_None + : MCSymbolRefExpr::VK_ARM_TARGET1), + OutContext); + + OutStreamer.EmitValue(E, Size); +} + /// runOnMachineFunction - This uses the EmitInstruction() /// method to print assembly for each instruction. /// diff --git a/lib/Target/ARM/ARMAsmPrinter.h b/lib/Target/ARM/ARMAsmPrinter.h index 7741fc4b34e..dcf693ce19f 100644 --- a/lib/Target/ARM/ARMAsmPrinter.h +++ b/lib/Target/ARM/ARMAsmPrinter.h @@ -73,6 +73,7 @@ public: virtual void EmitFunctionEntryLabel(); void EmitStartOfAsmFile(Module &M); void EmitEndOfAsmFile(Module &M); + void EmitXXStructor(const Constant *CV); // lowerOperand - Convert a MachineOperand into the equivalent MCOperand. bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 67345bfc05f..2ad64de9886 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -236,7 +236,10 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_ARM_GOTOFF: Type = ELF::R_ARM_GOTOFF32; break; - } + case MCSymbolRefExpr::VK_ARM_TARGET1: + Type = ELF::R_ARM_TARGET1; + break; + } break; case ARM::fixup_arm_ldst_pcrel_12: case ARM::fixup_arm_pcrel_10: diff --git a/test/MC/ARM/cxx-global-constructor.ll b/test/MC/ARM/cxx-global-constructor.ll new file mode 100644 index 00000000000..e06d2c73ed9 --- /dev/null +++ b/test/MC/ARM/cxx-global-constructor.ll @@ -0,0 +1,12 @@ +; RUN: llc %s -mtriple=armv7-linux-gnueabi -relocation-model=pic \ +; RUN: -filetype=obj -o - | elf-dump --dump-section-data | FileCheck %s + + +@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }] + +define void @f() { + ret void +} + +; Check for a relocation of type R_ARM_TARGET1. +; CHECK: ('r_type', 0x26) -- 2.34.1