//===-- 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;
}