1198090Srdivacky//===-- XCoreTargetObjectFile.cpp - XCore object files --------------------===//
2198090Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6198090Srdivacky//
7198090Srdivacky//===----------------------------------------------------------------------===//
8198090Srdivacky
9198090Srdivacky#include "XCoreTargetObjectFile.h"
10198090Srdivacky#include "XCoreSubtarget.h"
11321369Sdim#include "llvm/BinaryFormat/ELF.h"
12276479Sdim#include "llvm/IR/DataLayout.h"
13207618Srdivacky#include "llvm/MC/MCContext.h"
14207618Srdivacky#include "llvm/MC/MCSectionELF.h"
15198090Srdivacky#include "llvm/Target/TargetMachine.h"
16276479Sdim
17198090Srdivackyusing namespace llvm;
18198090Srdivacky
19198090Srdivacky
20198090Srdivackyvoid XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
21198090Srdivacky  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
22198090Srdivacky
23288943Sdim  BSSSection = Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS,
24288943Sdim                                 ELF::SHF_ALLOC | ELF::SHF_WRITE |
25288943Sdim                                     ELF::XCORE_SHF_DP_SECTION);
26288943Sdim  BSSSectionLarge = Ctx.getELFSection(".dp.bss.large", ELF::SHT_NOBITS,
27288943Sdim                                      ELF::SHF_ALLOC | ELF::SHF_WRITE |
28288943Sdim                                          ELF::XCORE_SHF_DP_SECTION);
29288943Sdim  DataSection = Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS,
30288943Sdim                                  ELF::SHF_ALLOC | ELF::SHF_WRITE |
31288943Sdim                                      ELF::XCORE_SHF_DP_SECTION);
32288943Sdim  DataSectionLarge = Ctx.getELFSection(".dp.data.large", ELF::SHT_PROGBITS,
33288943Sdim                                       ELF::SHF_ALLOC | ELF::SHF_WRITE |
34288943Sdim                                           ELF::XCORE_SHF_DP_SECTION);
35288943Sdim  DataRelROSection = Ctx.getELFSection(".dp.rodata", ELF::SHT_PROGBITS,
36288943Sdim                                       ELF::SHF_ALLOC | ELF::SHF_WRITE |
37288943Sdim                                           ELF::XCORE_SHF_DP_SECTION);
38288943Sdim  DataRelROSectionLarge = Ctx.getELFSection(
39288943Sdim      ".dp.rodata.large", ELF::SHT_PROGBITS,
40288943Sdim      ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION);
41276479Sdim  ReadOnlySection =
42288943Sdim      Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS,
43288943Sdim                        ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
44276479Sdim  ReadOnlySectionLarge =
45288943Sdim      Ctx.getELFSection(".cp.rodata.large", ELF::SHT_PROGBITS,
46288943Sdim                        ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
47288943Sdim  MergeableConst4Section = Ctx.getELFSection(
48288943Sdim      ".cp.rodata.cst4", ELF::SHT_PROGBITS,
49288943Sdim      ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 4, "");
50288943Sdim  MergeableConst8Section = Ctx.getELFSection(
51288943Sdim      ".cp.rodata.cst8", ELF::SHT_PROGBITS,
52288943Sdim      ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 8, "");
53288943Sdim  MergeableConst16Section = Ctx.getELFSection(
54288943Sdim      ".cp.rodata.cst16", ELF::SHT_PROGBITS,
55288943Sdim      ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 16, "");
56276479Sdim  CStringSection =
57288943Sdim      Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS,
58288943Sdim                        ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS |
59288943Sdim                            ELF::XCORE_SHF_CP_SECTION);
60276479Sdim  // TextSection       - see MObjectFileInfo.cpp
61276479Sdim  // StaticCtorSection - see MObjectFileInfo.cpp
62276479Sdim  // StaticDtorSection - see MObjectFileInfo.cpp
63276479Sdim }
64276479Sdim
65276479Sdimstatic unsigned getXCoreSectionType(SectionKind K) {
66276479Sdim  if (K.isBSS())
67276479Sdim    return ELF::SHT_NOBITS;
68276479Sdim  return ELF::SHT_PROGBITS;
69198090Srdivacky}
70276479Sdim
71276479Sdimstatic unsigned getXCoreSectionFlags(SectionKind K, bool IsCPRel) {
72276479Sdim  unsigned Flags = 0;
73276479Sdim
74276479Sdim  if (!K.isMetadata())
75276479Sdim    Flags |= ELF::SHF_ALLOC;
76276479Sdim
77276479Sdim  if (K.isText())
78276479Sdim    Flags |= ELF::SHF_EXECINSTR;
79276479Sdim  else if (IsCPRel)
80276479Sdim    Flags |= ELF::XCORE_SHF_CP_SECTION;
81276479Sdim  else
82276479Sdim    Flags |= ELF::XCORE_SHF_DP_SECTION;
83276479Sdim
84276479Sdim  if (K.isWriteable())
85276479Sdim    Flags |= ELF::SHF_WRITE;
86276479Sdim
87276479Sdim  if (K.isMergeableCString() || K.isMergeableConst4() ||
88276479Sdim      K.isMergeableConst8() || K.isMergeableConst16())
89276479Sdim    Flags |= ELF::SHF_MERGE;
90276479Sdim
91276479Sdim  if (K.isMergeableCString())
92276479Sdim    Flags |= ELF::SHF_STRINGS;
93276479Sdim
94276479Sdim  return Flags;
95276479Sdim}
96276479Sdim
97314564SdimMCSection *XCoreTargetObjectFile::getExplicitSectionGlobal(
98314564Sdim    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
99314564Sdim  StringRef SectionName = GO->getSection();
100276479Sdim  // Infer section flags from the section name if we can.
101276479Sdim  bool IsCPRel = SectionName.startswith(".cp.");
102276479Sdim  if (IsCPRel && !Kind.isReadOnly())
103276479Sdim    report_fatal_error("Using .cp. section for writeable object.");
104276479Sdim  return getContext().getELFSection(SectionName, getXCoreSectionType(Kind),
105288943Sdim                                    getXCoreSectionFlags(Kind, IsCPRel));
106276479Sdim}
107276479Sdim
108314564SdimMCSection *XCoreTargetObjectFile::SelectSectionForGlobal(
109314564Sdim    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
110276479Sdim
111314564Sdim  bool UseCPRel = GO->hasLocalLinkage();
112276479Sdim
113276479Sdim  if (Kind.isText())                    return TextSection;
114276479Sdim  if (UseCPRel) {
115276479Sdim    if (Kind.isMergeable1ByteCString()) return CStringSection;
116276479Sdim    if (Kind.isMergeableConst4())       return MergeableConst4Section;
117276479Sdim    if (Kind.isMergeableConst8())       return MergeableConst8Section;
118276479Sdim    if (Kind.isMergeableConst16())      return MergeableConst16Section;
119276479Sdim  }
120314564Sdim  Type *ObjType = GO->getValueType();
121314564Sdim  auto &DL = GO->getParent()->getDataLayout();
122280031Sdim  if (TM.getCodeModel() == CodeModel::Small || !ObjType->isSized() ||
123296417Sdim      DL.getTypeAllocSize(ObjType) < CodeModelLargeSize) {
124276479Sdim    if (Kind.isReadOnly())              return UseCPRel? ReadOnlySection
125276479Sdim                                                       : DataRelROSection;
126276479Sdim    if (Kind.isBSS() || Kind.isCommon())return BSSSection;
127296417Sdim    if (Kind.isData())
128296417Sdim      return DataSection;
129276479Sdim    if (Kind.isReadOnlyWithRel())       return DataRelROSection;
130276479Sdim  } else {
131276479Sdim    if (Kind.isReadOnly())              return UseCPRel? ReadOnlySectionLarge
132276479Sdim                                                       : DataRelROSectionLarge;
133276479Sdim    if (Kind.isBSS() || Kind.isCommon())return BSSSectionLarge;
134296417Sdim    if (Kind.isData())
135296417Sdim      return DataSectionLarge;
136276479Sdim    if (Kind.isReadOnlyWithRel())       return DataRelROSectionLarge;
137276479Sdim  }
138276479Sdim
139276479Sdim  assert((Kind.isThreadLocal() || Kind.isCommon()) && "Unknown section kind");
140276479Sdim  report_fatal_error("Target does not support TLS or Common sections");
141276479Sdim}
142276479Sdim
143309124SdimMCSection *XCoreTargetObjectFile::getSectionForConstant(const DataLayout &DL,
144309124Sdim                                                        SectionKind Kind,
145309124Sdim                                                        const Constant *C,
146309124Sdim                                                        unsigned &Align) const {
147276479Sdim  if (Kind.isMergeableConst4())           return MergeableConst4Section;
148276479Sdim  if (Kind.isMergeableConst8())           return MergeableConst8Section;
149276479Sdim  if (Kind.isMergeableConst16())          return MergeableConst16Section;
150276479Sdim  assert((Kind.isReadOnly() || Kind.isReadOnlyWithRel()) &&
151276479Sdim         "Unknown section kind");
152276479Sdim  // We assume the size of the object is never greater than CodeModelLargeSize.
153276479Sdim  // To handle CodeModelLargeSize changes to AsmPrinter would be required.
154276479Sdim  return ReadOnlySection;
155276479Sdim}
156