diff --git a/llvm/include/llvm/MC/MCSymbolXCOFF.h b/llvm/include/llvm/MC/MCSymbolXCOFF.h --- a/llvm/include/llvm/MC/MCSymbolXCOFF.h +++ b/llvm/include/llvm/MC/MCSymbolXCOFF.h @@ -10,6 +10,7 @@ #include "llvm/BinaryFormat/XCOFF.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSectionXCOFF.h" namespace llvm { @@ -22,9 +23,13 @@ void setStorageClass(XCOFF::StorageClass SC) { StorageClass = SC; }; XCOFF::StorageClass getStorageClass() const { return StorageClass; } + + void setContainingCSect(const MCSectionXCOFF *C); + const MCSectionXCOFF *getContainingCSect() const; private: XCOFF::StorageClass StorageClass; + const MCSectionXCOFF *ContainingCSect = nullptr; }; } // end namespace llvm diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -44,6 +44,7 @@ MCSubtargetInfo.cpp MCSymbol.cpp MCSymbolELF.cpp + MCSymbolXCOFF.cpp MCTargetOptions.cpp MCValue.cpp MCWasmObjectTargetWriter.cpp diff --git a/llvm/lib/MC/MCSymbolXCOFF.cpp b/llvm/lib/MC/MCSymbolXCOFF.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/MC/MCSymbolXCOFF.cpp @@ -0,0 +1,25 @@ +//===- lib/MC/MCSymbolXCOFF.cpp -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCSymbolXCOFF.h" +#include "llvm/MC/MCSectionXCOFF.h" + +using namespace llvm; + +const MCSectionXCOFF *MCSymbolXCOFF::getContainingCSect() const { + assert(ContainingCSect && "Trying to get containing csect but none was set."); + return ContainingCSect; +} + +void MCSymbolXCOFF::setContainingCSect(const MCSectionXCOFF *C) { + assert((!ContainingCSect || ContainingCSect == C) && + "Trying to set a contain csect that doesn't match the one that this " + "symbol is already mapped to."); + if (!ContainingCSect) + ContainingCSect = C; +} diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -251,8 +251,7 @@ } // Map the symbol into its containing csect. - MCSectionXCOFF *ContainingCSect = - dyn_cast(XSym->getFragment(false)->getParent()); + const MCSectionXCOFF *ContainingCSect = XSym->getContainingCSect(); assert(WrapperMap.find(ContainingCSect) != WrapperMap.end() && "Expected containing csect to exist in map"); diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -168,6 +168,7 @@ StringRef getPassName() const override { return "AIX PPC Assembly Printer"; } void EmitGlobalVariable(const GlobalVariable *GV) override; + void EmitStartOfAsmFile(Module &M) override; }; } // end anonymous namespace @@ -1671,6 +1672,7 @@ MCSymbolXCOFF *XSym = cast(getSymbol(GV)); XSym->setStorageClass( TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV)); + XSym->setContainingCSect(CSect); const DataLayout &DL = GV->getParent()->getDataLayout(); unsigned Align = GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV); @@ -1682,6 +1684,17 @@ OutStreamer->EmitCommonSymbol(XSym, Size, Align); } +void PPCAIXAsmPrinter::EmitStartOfAsmFile(Module &M) { + // Map the TOC anchor to it's containing Csect, since we will almost always + // need it. That way other methods can query it freely assuming it is set. + StringRef TOC("TOC"); + MCSymbol *TOCBaseSym = OutContext.getOrCreateSymbol(TOC); + MCSectionXCOFF *TOCAnchor = OutStreamer->getContext().getXCOFFSection( + TOC, XCOFF::XMC_TC0, XCOFF::XTY_SD, XCOFF::C_HIDEXT, + SectionKind::getData()); + cast(TOCBaseSym)->setContainingCSect(TOCAnchor); +} + /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code /// for a MachineFunction to the given output stream, in a format that the /// Darwin assembler can deal with.