1//===-- XCoreTargetObjectFile.cpp - XCore object files --------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "XCoreTargetObjectFile.h"
10#include "XCoreSubtarget.h"
11#include "llvm/BinaryFormat/ELF.h"
12#include "llvm/IR/DataLayout.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCSectionELF.h"
15#include "llvm/Target/TargetMachine.h"
16
17using namespace llvm;
18
19
20void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
21  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
22
23  BSSSection = Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS,
24                                 ELF::SHF_ALLOC | ELF::SHF_WRITE |
25                                     ELF::XCORE_SHF_DP_SECTION);
26  BSSSectionLarge = Ctx.getELFSection(".dp.bss.large", ELF::SHT_NOBITS,
27                                      ELF::SHF_ALLOC | ELF::SHF_WRITE |
28                                          ELF::XCORE_SHF_DP_SECTION);
29  DataSection = Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS,
30                                  ELF::SHF_ALLOC | ELF::SHF_WRITE |
31                                      ELF::XCORE_SHF_DP_SECTION);
32  DataSectionLarge = Ctx.getELFSection(".dp.data.large", ELF::SHT_PROGBITS,
33                                       ELF::SHF_ALLOC | ELF::SHF_WRITE |
34                                           ELF::XCORE_SHF_DP_SECTION);
35  DataRelROSection = Ctx.getELFSection(".dp.rodata", ELF::SHT_PROGBITS,
36                                       ELF::SHF_ALLOC | ELF::SHF_WRITE |
37                                           ELF::XCORE_SHF_DP_SECTION);
38  DataRelROSectionLarge = Ctx.getELFSection(
39      ".dp.rodata.large", ELF::SHT_PROGBITS,
40      ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION);
41  ReadOnlySection =
42      Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS,
43                        ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
44  ReadOnlySectionLarge =
45      Ctx.getELFSection(".cp.rodata.large", ELF::SHT_PROGBITS,
46                        ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
47  MergeableConst4Section = Ctx.getELFSection(
48      ".cp.rodata.cst4", ELF::SHT_PROGBITS,
49      ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 4, "");
50  MergeableConst8Section = Ctx.getELFSection(
51      ".cp.rodata.cst8", ELF::SHT_PROGBITS,
52      ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 8, "");
53  MergeableConst16Section = Ctx.getELFSection(
54      ".cp.rodata.cst16", ELF::SHT_PROGBITS,
55      ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 16, "");
56  CStringSection =
57      Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS,
58                        ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS |
59                            ELF::XCORE_SHF_CP_SECTION);
60  // TextSection       - see MObjectFileInfo.cpp
61  // StaticCtorSection - see MObjectFileInfo.cpp
62  // StaticDtorSection - see MObjectFileInfo.cpp
63 }
64
65static unsigned getXCoreSectionType(SectionKind K) {
66  if (K.isBSS())
67    return ELF::SHT_NOBITS;
68  return ELF::SHT_PROGBITS;
69}
70
71static unsigned getXCoreSectionFlags(SectionKind K, bool IsCPRel) {
72  unsigned Flags = 0;
73
74  if (!K.isMetadata())
75    Flags |= ELF::SHF_ALLOC;
76
77  if (K.isText())
78    Flags |= ELF::SHF_EXECINSTR;
79  else if (IsCPRel)
80    Flags |= ELF::XCORE_SHF_CP_SECTION;
81  else
82    Flags |= ELF::XCORE_SHF_DP_SECTION;
83
84  if (K.isWriteable())
85    Flags |= ELF::SHF_WRITE;
86
87  if (K.isMergeableCString() || K.isMergeableConst4() ||
88      K.isMergeableConst8() || K.isMergeableConst16())
89    Flags |= ELF::SHF_MERGE;
90
91  if (K.isMergeableCString())
92    Flags |= ELF::SHF_STRINGS;
93
94  return Flags;
95}
96
97MCSection *XCoreTargetObjectFile::getExplicitSectionGlobal(
98    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
99  StringRef SectionName = GO->getSection();
100  // Infer section flags from the section name if we can.
101  bool IsCPRel = SectionName.startswith(".cp.");
102  if (IsCPRel && !Kind.isReadOnly())
103    report_fatal_error("Using .cp. section for writeable object.");
104  return getContext().getELFSection(SectionName, getXCoreSectionType(Kind),
105                                    getXCoreSectionFlags(Kind, IsCPRel));
106}
107
108MCSection *XCoreTargetObjectFile::SelectSectionForGlobal(
109    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
110
111  bool UseCPRel = GO->hasLocalLinkage();
112
113  if (Kind.isText())                    return TextSection;
114  if (UseCPRel) {
115    if (Kind.isMergeable1ByteCString()) return CStringSection;
116    if (Kind.isMergeableConst4())       return MergeableConst4Section;
117    if (Kind.isMergeableConst8())       return MergeableConst8Section;
118    if (Kind.isMergeableConst16())      return MergeableConst16Section;
119  }
120  Type *ObjType = GO->getValueType();
121  auto &DL = GO->getParent()->getDataLayout();
122  if (TM.getCodeModel() == CodeModel::Small || !ObjType->isSized() ||
123      DL.getTypeAllocSize(ObjType) < CodeModelLargeSize) {
124    if (Kind.isReadOnly())              return UseCPRel? ReadOnlySection
125                                                       : DataRelROSection;
126    if (Kind.isBSS() || Kind.isCommon())return BSSSection;
127    if (Kind.isData())
128      return DataSection;
129    if (Kind.isReadOnlyWithRel())       return DataRelROSection;
130  } else {
131    if (Kind.isReadOnly())              return UseCPRel? ReadOnlySectionLarge
132                                                       : DataRelROSectionLarge;
133    if (Kind.isBSS() || Kind.isCommon())return BSSSectionLarge;
134    if (Kind.isData())
135      return DataSectionLarge;
136    if (Kind.isReadOnlyWithRel())       return DataRelROSectionLarge;
137  }
138
139  assert((Kind.isThreadLocal() || Kind.isCommon()) && "Unknown section kind");
140  report_fatal_error("Target does not support TLS or Common sections");
141}
142
143MCSection *XCoreTargetObjectFile::getSectionForConstant(const DataLayout &DL,
144                                                        SectionKind Kind,
145                                                        const Constant *C,
146                                                        unsigned &Align) const {
147  if (Kind.isMergeableConst4())           return MergeableConst4Section;
148  if (Kind.isMergeableConst8())           return MergeableConst8Section;
149  if (Kind.isMergeableConst16())          return MergeableConst16Section;
150  assert((Kind.isReadOnly() || Kind.isReadOnlyWithRel()) &&
151         "Unknown section kind");
152  // We assume the size of the object is never greater than CodeModelLargeSize.
153  // To handle CodeModelLargeSize changes to AsmPrinter would be required.
154  return ReadOnlySection;
155}
156