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(Section: ".dp.bss", Type: ELF::SHT_NOBITS,
24 Flags: ELF::SHF_ALLOC | ELF::SHF_WRITE |
25 ELF::XCORE_SHF_DP_SECTION);
26 BSSSectionLarge = Ctx.getELFSection(Section: ".dp.bss.large", Type: ELF::SHT_NOBITS,
27 Flags: ELF::SHF_ALLOC | ELF::SHF_WRITE |
28 ELF::XCORE_SHF_DP_SECTION);
29 DataSection = Ctx.getELFSection(Section: ".dp.data", Type: ELF::SHT_PROGBITS,
30 Flags: ELF::SHF_ALLOC | ELF::SHF_WRITE |
31 ELF::XCORE_SHF_DP_SECTION);
32 DataSectionLarge = Ctx.getELFSection(Section: ".dp.data.large", Type: ELF::SHT_PROGBITS,
33 Flags: ELF::SHF_ALLOC | ELF::SHF_WRITE |
34 ELF::XCORE_SHF_DP_SECTION);
35 DataRelROSection = Ctx.getELFSection(Section: ".dp.rodata", Type: ELF::SHT_PROGBITS,
36 Flags: ELF::SHF_ALLOC | ELF::SHF_WRITE |
37 ELF::XCORE_SHF_DP_SECTION);
38 DataRelROSectionLarge = Ctx.getELFSection(
39 Section: ".dp.rodata.large", Type: ELF::SHT_PROGBITS,
40 Flags: ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION);
41 ReadOnlySection =
42 Ctx.getELFSection(Section: ".cp.rodata", Type: ELF::SHT_PROGBITS,
43 Flags: ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
44 ReadOnlySectionLarge =
45 Ctx.getELFSection(Section: ".cp.rodata.large", Type: ELF::SHT_PROGBITS,
46 Flags: ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
47 MergeableConst4Section = Ctx.getELFSection(
48 Section: ".cp.rodata.cst4", Type: ELF::SHT_PROGBITS,
49 Flags: ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, EntrySize: 4);
50 MergeableConst8Section = Ctx.getELFSection(
51 Section: ".cp.rodata.cst8", Type: ELF::SHT_PROGBITS,
52 Flags: ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, EntrySize: 8);
53 MergeableConst16Section = Ctx.getELFSection(
54 Section: ".cp.rodata.cst16", Type: ELF::SHT_PROGBITS,
55 Flags: ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, EntrySize: 16);
56 CStringSection =
57 Ctx.getELFSection(Section: ".cp.rodata.string", Type: ELF::SHT_PROGBITS,
58 Flags: 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.starts_with(Prefix: ".cp.");
102 if (IsCPRel && !Kind.isReadOnly())
103 report_fatal_error(reason: "Using .cp. section for writeable object.");
104 return getContext().getELFSection(Section: SectionName, Type: getXCoreSectionType(K: Kind),
105 Flags: getXCoreSectionFlags(K: 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->getDataLayout();
122 if (TM.getCodeModel() == CodeModel::Small || !ObjType->isSized() ||
123 DL.getTypeAllocSize(Ty: 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(reason: "Target does not support TLS or Common sections");
141}
142
143MCSection *XCoreTargetObjectFile::getSectionForConstant(
144 const DataLayout &DL, SectionKind Kind, const Constant *C,
145 Align &Alignment) const {
146 if (Kind.isMergeableConst4()) return MergeableConst4Section;
147 if (Kind.isMergeableConst8()) return MergeableConst8Section;
148 if (Kind.isMergeableConst16()) return MergeableConst16Section;
149 assert((Kind.isReadOnly() || Kind.isReadOnlyWithRel()) &&
150 "Unknown section kind");
151 // We assume the size of the object is never greater than CodeModelLargeSize.
152 // To handle CodeModelLargeSize changes to AsmPrinter would be required.
153 return ReadOnlySection;
154}
155