//===-- XCoreTargetObjectFile.cpp - XCore object files --------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "XCoreTargetObjectFile.h" #include "XCoreSubtarget.h" #include "llvm/IR/DataLayout.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/Support/ELF.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ TargetLoweringObjectFileELF::Initialize(Ctx, TM); BSSSection = Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getBSS()); BSSSectionLarge = Ctx.getELFSection(".dp.bss.large", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getBSS()); DataSection = Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getDataRel()); DataSectionLarge = Ctx.getELFSection(".dp.data.large", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getDataRel()); DataRelROSection = Ctx.getELFSection(".dp.rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getReadOnlyWithRel()); DataRelROSectionLarge = Ctx.getELFSection(".dp.rodata.large", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getReadOnlyWithRel()); ReadOnlySection = Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION, SectionKind::getReadOnlyWithRel()); ReadOnlySectionLarge = Ctx.getELFSection(".cp.rodata.large", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION, SectionKind::getReadOnlyWithRel()); MergeableConst4Section = Ctx.getELFSection(".cp.rodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, SectionKind::getMergeableConst4()); MergeableConst8Section = Ctx.getELFSection(".cp.rodata.cst8", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, SectionKind::getMergeableConst8()); MergeableConst16Section = Ctx.getELFSection(".cp.rodata.cst16", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, SectionKind::getMergeableConst16()); CStringSection = Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::XCORE_SHF_CP_SECTION, SectionKind::getReadOnlyWithRel()); // TextSection - see MObjectFileInfo.cpp // StaticCtorSection - see MObjectFileInfo.cpp // StaticDtorSection - see MObjectFileInfo.cpp } static unsigned getXCoreSectionType(SectionKind K) { if (K.isBSS()) return ELF::SHT_NOBITS; return ELF::SHT_PROGBITS; } static unsigned getXCoreSectionFlags(SectionKind K, bool IsCPRel) { unsigned Flags = 0; if (!K.isMetadata()) Flags |= ELF::SHF_ALLOC; if (K.isText()) Flags |= ELF::SHF_EXECINSTR; else if (IsCPRel) Flags |= ELF::XCORE_SHF_CP_SECTION; else Flags |= ELF::XCORE_SHF_DP_SECTION; if (K.isWriteable()) Flags |= ELF::SHF_WRITE; if (K.isMergeableCString() || K.isMergeableConst4() || K.isMergeableConst8() || K.isMergeableConst16()) Flags |= ELF::SHF_MERGE; if (K.isMergeableCString()) Flags |= ELF::SHF_STRINGS; return Flags; } const MCSection * XCoreTargetObjectFile::getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { StringRef SectionName = GV->getSection(); // Infer section flags from the section name if we can. bool IsCPRel = SectionName.startswith(".cp."); if (IsCPRel && !Kind.isReadOnly()) report_fatal_error("Using .cp. section for writeable object."); return getContext().getELFSection(SectionName, getXCoreSectionType(Kind), getXCoreSectionFlags(Kind, IsCPRel), Kind); } const MCSection *XCoreTargetObjectFile:: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const{ bool UseCPRel = GV->isLocalLinkage(GV->getLinkage()); if (Kind.isText()) return TextSection; if (UseCPRel) { if (Kind.isMergeable1ByteCString()) return CStringSection; if (Kind.isMergeableConst4()) return MergeableConst4Section; if (Kind.isMergeableConst8()) return MergeableConst8Section; if (Kind.isMergeableConst16()) return MergeableConst16Section; } Type *ObjType = GV->getType()->getPointerElementType(); if (TM.getCodeModel() == CodeModel::Small || !ObjType->isSized() || TM.getDataLayout()->getTypeAllocSize(ObjType) < CodeModelLargeSize) { if (Kind.isReadOnly()) return UseCPRel? ReadOnlySection : DataRelROSection; if (Kind.isBSS() || Kind.isCommon())return BSSSection; if (Kind.isDataRel()) return DataSection; if (Kind.isReadOnlyWithRel()) return DataRelROSection; } else { if (Kind.isReadOnly()) return UseCPRel? ReadOnlySectionLarge : DataRelROSectionLarge; if (Kind.isBSS() || Kind.isCommon())return BSSSectionLarge; if (Kind.isDataRel()) return DataSectionLarge; if (Kind.isReadOnlyWithRel()) return DataRelROSectionLarge; } assert((Kind.isThreadLocal() || Kind.isCommon()) && "Unknown section kind"); report_fatal_error("Target does not support TLS or Common sections"); } const MCSection *XCoreTargetObjectFile:: getSectionForConstant(SectionKind Kind) const { if (Kind.isMergeableConst4()) return MergeableConst4Section; if (Kind.isMergeableConst8()) return MergeableConst8Section; if (Kind.isMergeableConst16()) return MergeableConst16Section; assert((Kind.isReadOnly() || Kind.isReadOnlyWithRel()) && "Unknown section kind"); // We assume the size of the object is never greater than CodeModelLargeSize. // To handle CodeModelLargeSize changes to AsmPrinter would be required. return ReadOnlySection; }