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 | |
17 | using namespace llvm; |
18 | |
19 | |
20 | void 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 | |
65 | static unsigned getXCoreSectionType(SectionKind K) { |
66 | if (K.isBSS()) |
67 | return ELF::SHT_NOBITS; |
68 | return ELF::SHT_PROGBITS; |
69 | } |
70 | |
71 | static 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 | |
97 | MCSection *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 | |
108 | MCSection *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 | |
143 | MCSection *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 | |