1*9880d681SAndroid Build Coastguard Worker //===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file assembles .s files and emits ELF .o object files.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFStreamer.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmBackend.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmLayout.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAssembler.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCCodeEmitter.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectFileInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectStreamer.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectWriter.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSection.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionELF.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCValue.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker using namespace llvm;
40*9880d681SAndroid Build Coastguard Worker
isBundleLocked() const41*9880d681SAndroid Build Coastguard Worker bool MCELFStreamer::isBundleLocked() const {
42*9880d681SAndroid Build Coastguard Worker return getCurrentSectionOnly()->isBundleLocked();
43*9880d681SAndroid Build Coastguard Worker }
44*9880d681SAndroid Build Coastguard Worker
~MCELFStreamer()45*9880d681SAndroid Build Coastguard Worker MCELFStreamer::~MCELFStreamer() {
46*9880d681SAndroid Build Coastguard Worker }
47*9880d681SAndroid Build Coastguard Worker
mergeFragment(MCDataFragment * DF,MCDataFragment * EF)48*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::mergeFragment(MCDataFragment *DF,
49*9880d681SAndroid Build Coastguard Worker MCDataFragment *EF) {
50*9880d681SAndroid Build Coastguard Worker MCAssembler &Assembler = getAssembler();
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
53*9880d681SAndroid Build Coastguard Worker uint64_t FSize = EF->getContents().size();
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker if (FSize > Assembler.getBundleAlignSize())
56*9880d681SAndroid Build Coastguard Worker report_fatal_error("Fragment can't be larger than a bundle size");
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker uint64_t RequiredBundlePadding = computeBundlePadding(
59*9880d681SAndroid Build Coastguard Worker Assembler, EF, DF->getContents().size(), FSize);
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker if (RequiredBundlePadding > UINT8_MAX)
62*9880d681SAndroid Build Coastguard Worker report_fatal_error("Padding cannot exceed 255 bytes");
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker if (RequiredBundlePadding > 0) {
65*9880d681SAndroid Build Coastguard Worker SmallString<256> Code;
66*9880d681SAndroid Build Coastguard Worker raw_svector_ostream VecOS(Code);
67*9880d681SAndroid Build Coastguard Worker MCObjectWriter *OW = Assembler.getBackend().createObjectWriter(VecOS);
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker Assembler.writeFragmentPadding(*EF, FSize, OW);
72*9880d681SAndroid Build Coastguard Worker delete OW;
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker DF->getContents().append(Code.begin(), Code.end());
75*9880d681SAndroid Build Coastguard Worker }
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker flushPendingLabels(DF, DF->getContents().size());
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) {
81*9880d681SAndroid Build Coastguard Worker EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() +
82*9880d681SAndroid Build Coastguard Worker DF->getContents().size());
83*9880d681SAndroid Build Coastguard Worker DF->getFixups().push_back(EF->getFixups()[i]);
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker DF->setHasInstructions(true);
86*9880d681SAndroid Build Coastguard Worker DF->getContents().append(EF->getContents().begin(), EF->getContents().end());
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker
InitSections(bool NoExecStack)89*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::InitSections(bool NoExecStack) {
90*9880d681SAndroid Build Coastguard Worker MCContext &Ctx = getContext();
91*9880d681SAndroid Build Coastguard Worker SwitchSection(Ctx.getObjectFileInfo()->getTextSection());
92*9880d681SAndroid Build Coastguard Worker EmitCodeAlignment(4);
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker if (NoExecStack)
95*9880d681SAndroid Build Coastguard Worker SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker
EmitLabel(MCSymbol * S)98*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitLabel(MCSymbol *S) {
99*9880d681SAndroid Build Coastguard Worker auto *Symbol = cast<MCSymbolELF>(S);
100*9880d681SAndroid Build Coastguard Worker assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker MCObjectStreamer::EmitLabel(Symbol);
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker const MCSectionELF &Section =
105*9880d681SAndroid Build Coastguard Worker static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
106*9880d681SAndroid Build Coastguard Worker if (Section.getFlags() & ELF::SHF_TLS)
107*9880d681SAndroid Build Coastguard Worker Symbol->setType(ELF::STT_TLS);
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker
EmitAssemblerFlag(MCAssemblerFlag Flag)110*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
111*9880d681SAndroid Build Coastguard Worker // Let the target do whatever target specific stuff it needs to do.
112*9880d681SAndroid Build Coastguard Worker getAssembler().getBackend().handleAssemblerFlag(Flag);
113*9880d681SAndroid Build Coastguard Worker // Do any generic stuff we need to do.
114*9880d681SAndroid Build Coastguard Worker switch (Flag) {
115*9880d681SAndroid Build Coastguard Worker case MCAF_SyntaxUnified: return; // no-op here.
116*9880d681SAndroid Build Coastguard Worker case MCAF_Code16: return; // Change parsing mode; no-op here.
117*9880d681SAndroid Build Coastguard Worker case MCAF_Code32: return; // Change parsing mode; no-op here.
118*9880d681SAndroid Build Coastguard Worker case MCAF_Code64: return; // Change parsing mode; no-op here.
119*9880d681SAndroid Build Coastguard Worker case MCAF_SubsectionsViaSymbols:
120*9880d681SAndroid Build Coastguard Worker getAssembler().setSubsectionsViaSymbols(true);
121*9880d681SAndroid Build Coastguard Worker return;
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker llvm_unreachable("invalid assembler flag!");
125*9880d681SAndroid Build Coastguard Worker }
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker // If bundle alignment is used and there are any instructions in the section, it
128*9880d681SAndroid Build Coastguard Worker // needs to be aligned to at least the bundle size.
setSectionAlignmentForBundling(const MCAssembler & Assembler,MCSection * Section)129*9880d681SAndroid Build Coastguard Worker static void setSectionAlignmentForBundling(const MCAssembler &Assembler,
130*9880d681SAndroid Build Coastguard Worker MCSection *Section) {
131*9880d681SAndroid Build Coastguard Worker if (Section && Assembler.isBundlingEnabled() && Section->hasInstructions() &&
132*9880d681SAndroid Build Coastguard Worker Section->getAlignment() < Assembler.getBundleAlignSize())
133*9880d681SAndroid Build Coastguard Worker Section->setAlignment(Assembler.getBundleAlignSize());
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker
ChangeSection(MCSection * Section,const MCExpr * Subsection)136*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::ChangeSection(MCSection *Section,
137*9880d681SAndroid Build Coastguard Worker const MCExpr *Subsection) {
138*9880d681SAndroid Build Coastguard Worker MCSection *CurSection = getCurrentSectionOnly();
139*9880d681SAndroid Build Coastguard Worker if (CurSection && isBundleLocked())
140*9880d681SAndroid Build Coastguard Worker report_fatal_error("Unterminated .bundle_lock when changing a section");
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker MCAssembler &Asm = getAssembler();
143*9880d681SAndroid Build Coastguard Worker // Ensure the previous section gets aligned if necessary.
144*9880d681SAndroid Build Coastguard Worker setSectionAlignmentForBundling(Asm, CurSection);
145*9880d681SAndroid Build Coastguard Worker auto *SectionELF = static_cast<const MCSectionELF *>(Section);
146*9880d681SAndroid Build Coastguard Worker const MCSymbol *Grp = SectionELF->getGroup();
147*9880d681SAndroid Build Coastguard Worker if (Grp)
148*9880d681SAndroid Build Coastguard Worker Asm.registerSymbol(*Grp);
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker this->MCObjectStreamer::ChangeSection(Section, Subsection);
151*9880d681SAndroid Build Coastguard Worker MCContext &Ctx = getContext();
152*9880d681SAndroid Build Coastguard Worker auto *Begin = cast_or_null<MCSymbolELF>(Section->getBeginSymbol());
153*9880d681SAndroid Build Coastguard Worker if (!Begin) {
154*9880d681SAndroid Build Coastguard Worker Begin = Ctx.getOrCreateSectionSymbol(*SectionELF);
155*9880d681SAndroid Build Coastguard Worker Section->setBeginSymbol(Begin);
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker if (Begin->isUndefined()) {
158*9880d681SAndroid Build Coastguard Worker Asm.registerSymbol(*Begin);
159*9880d681SAndroid Build Coastguard Worker Begin->setType(ELF::STT_SECTION);
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
EmitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)163*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
164*9880d681SAndroid Build Coastguard Worker getAssembler().registerSymbol(*Symbol);
165*9880d681SAndroid Build Coastguard Worker const MCExpr *Value = MCSymbolRefExpr::create(
166*9880d681SAndroid Build Coastguard Worker Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext());
167*9880d681SAndroid Build Coastguard Worker Alias->setVariableValue(Value);
168*9880d681SAndroid Build Coastguard Worker }
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker // When GNU as encounters more than one .type declaration for an object it seems
171*9880d681SAndroid Build Coastguard Worker // to use a mechanism similar to the one below to decide which type is actually
172*9880d681SAndroid Build Coastguard Worker // used in the object file. The greater of T1 and T2 is selected based on the
173*9880d681SAndroid Build Coastguard Worker // following ordering:
174*9880d681SAndroid Build Coastguard Worker // STT_NOTYPE < STT_OBJECT < STT_FUNC < STT_GNU_IFUNC < STT_TLS < anything else
175*9880d681SAndroid Build Coastguard Worker // If neither T1 < T2 nor T2 < T1 according to this ordering, use T2 (the user
176*9880d681SAndroid Build Coastguard Worker // provided type).
CombineSymbolTypes(unsigned T1,unsigned T2)177*9880d681SAndroid Build Coastguard Worker static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) {
178*9880d681SAndroid Build Coastguard Worker for (unsigned Type : {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC,
179*9880d681SAndroid Build Coastguard Worker ELF::STT_GNU_IFUNC, ELF::STT_TLS}) {
180*9880d681SAndroid Build Coastguard Worker if (T1 == Type)
181*9880d681SAndroid Build Coastguard Worker return T2;
182*9880d681SAndroid Build Coastguard Worker if (T2 == Type)
183*9880d681SAndroid Build Coastguard Worker return T1;
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker return T2;
187*9880d681SAndroid Build Coastguard Worker }
188*9880d681SAndroid Build Coastguard Worker
EmitSymbolAttribute(MCSymbol * S,MCSymbolAttr Attribute)189*9880d681SAndroid Build Coastguard Worker bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
190*9880d681SAndroid Build Coastguard Worker auto *Symbol = cast<MCSymbolELF>(S);
191*9880d681SAndroid Build Coastguard Worker // Indirect symbols are handled differently, to match how 'as' handles
192*9880d681SAndroid Build Coastguard Worker // them. This makes writing matching .o files easier.
193*9880d681SAndroid Build Coastguard Worker if (Attribute == MCSA_IndirectSymbol) {
194*9880d681SAndroid Build Coastguard Worker // Note that we intentionally cannot use the symbol data here; this is
195*9880d681SAndroid Build Coastguard Worker // important for matching the string table that 'as' generates.
196*9880d681SAndroid Build Coastguard Worker IndirectSymbolData ISD;
197*9880d681SAndroid Build Coastguard Worker ISD.Symbol = Symbol;
198*9880d681SAndroid Build Coastguard Worker ISD.Section = getCurrentSectionOnly();
199*9880d681SAndroid Build Coastguard Worker getAssembler().getIndirectSymbols().push_back(ISD);
200*9880d681SAndroid Build Coastguard Worker return true;
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker // Adding a symbol attribute always introduces the symbol, note that an
204*9880d681SAndroid Build Coastguard Worker // important side effect of calling registerSymbol here is to register
205*9880d681SAndroid Build Coastguard Worker // the symbol with the assembler.
206*9880d681SAndroid Build Coastguard Worker getAssembler().registerSymbol(*Symbol);
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker // The implementation of symbol attributes is designed to match 'as', but it
209*9880d681SAndroid Build Coastguard Worker // leaves much to desired. It doesn't really make sense to arbitrarily add and
210*9880d681SAndroid Build Coastguard Worker // remove flags, but 'as' allows this (in particular, see .desc).
211*9880d681SAndroid Build Coastguard Worker //
212*9880d681SAndroid Build Coastguard Worker // In the future it might be worth trying to make these operations more well
213*9880d681SAndroid Build Coastguard Worker // defined.
214*9880d681SAndroid Build Coastguard Worker switch (Attribute) {
215*9880d681SAndroid Build Coastguard Worker case MCSA_LazyReference:
216*9880d681SAndroid Build Coastguard Worker case MCSA_Reference:
217*9880d681SAndroid Build Coastguard Worker case MCSA_SymbolResolver:
218*9880d681SAndroid Build Coastguard Worker case MCSA_PrivateExtern:
219*9880d681SAndroid Build Coastguard Worker case MCSA_WeakDefinition:
220*9880d681SAndroid Build Coastguard Worker case MCSA_WeakDefAutoPrivate:
221*9880d681SAndroid Build Coastguard Worker case MCSA_Invalid:
222*9880d681SAndroid Build Coastguard Worker case MCSA_IndirectSymbol:
223*9880d681SAndroid Build Coastguard Worker return false;
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker case MCSA_NoDeadStrip:
226*9880d681SAndroid Build Coastguard Worker // Ignore for now.
227*9880d681SAndroid Build Coastguard Worker break;
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker case MCSA_ELF_TypeGnuUniqueObject:
230*9880d681SAndroid Build Coastguard Worker Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
231*9880d681SAndroid Build Coastguard Worker Symbol->setBinding(ELF::STB_GNU_UNIQUE);
232*9880d681SAndroid Build Coastguard Worker Symbol->setExternal(true);
233*9880d681SAndroid Build Coastguard Worker break;
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker case MCSA_Global:
236*9880d681SAndroid Build Coastguard Worker Symbol->setBinding(ELF::STB_GLOBAL);
237*9880d681SAndroid Build Coastguard Worker Symbol->setExternal(true);
238*9880d681SAndroid Build Coastguard Worker break;
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker case MCSA_WeakReference:
241*9880d681SAndroid Build Coastguard Worker case MCSA_Weak:
242*9880d681SAndroid Build Coastguard Worker Symbol->setBinding(ELF::STB_WEAK);
243*9880d681SAndroid Build Coastguard Worker Symbol->setExternal(true);
244*9880d681SAndroid Build Coastguard Worker break;
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker case MCSA_Local:
247*9880d681SAndroid Build Coastguard Worker Symbol->setBinding(ELF::STB_LOCAL);
248*9880d681SAndroid Build Coastguard Worker Symbol->setExternal(false);
249*9880d681SAndroid Build Coastguard Worker break;
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker case MCSA_ELF_TypeFunction:
252*9880d681SAndroid Build Coastguard Worker Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_FUNC));
253*9880d681SAndroid Build Coastguard Worker break;
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker case MCSA_ELF_TypeIndFunction:
256*9880d681SAndroid Build Coastguard Worker Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC));
257*9880d681SAndroid Build Coastguard Worker break;
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker case MCSA_ELF_TypeObject:
260*9880d681SAndroid Build Coastguard Worker Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
261*9880d681SAndroid Build Coastguard Worker break;
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker case MCSA_ELF_TypeTLS:
264*9880d681SAndroid Build Coastguard Worker Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_TLS));
265*9880d681SAndroid Build Coastguard Worker break;
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker case MCSA_ELF_TypeCommon:
268*9880d681SAndroid Build Coastguard Worker // TODO: Emit these as a common symbol.
269*9880d681SAndroid Build Coastguard Worker Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
270*9880d681SAndroid Build Coastguard Worker break;
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker case MCSA_ELF_TypeNoType:
273*9880d681SAndroid Build Coastguard Worker Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_NOTYPE));
274*9880d681SAndroid Build Coastguard Worker break;
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker case MCSA_Protected:
277*9880d681SAndroid Build Coastguard Worker Symbol->setVisibility(ELF::STV_PROTECTED);
278*9880d681SAndroid Build Coastguard Worker break;
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker case MCSA_Hidden:
281*9880d681SAndroid Build Coastguard Worker Symbol->setVisibility(ELF::STV_HIDDEN);
282*9880d681SAndroid Build Coastguard Worker break;
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker case MCSA_Internal:
285*9880d681SAndroid Build Coastguard Worker Symbol->setVisibility(ELF::STV_INTERNAL);
286*9880d681SAndroid Build Coastguard Worker break;
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker case MCSA_AltEntry:
289*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support the .alt_entry attribute");
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker
292*9880d681SAndroid Build Coastguard Worker return true;
293*9880d681SAndroid Build Coastguard Worker }
294*9880d681SAndroid Build Coastguard Worker
EmitCommonSymbol(MCSymbol * S,uint64_t Size,unsigned ByteAlignment)295*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
296*9880d681SAndroid Build Coastguard Worker unsigned ByteAlignment) {
297*9880d681SAndroid Build Coastguard Worker auto *Symbol = cast<MCSymbolELF>(S);
298*9880d681SAndroid Build Coastguard Worker getAssembler().registerSymbol(*Symbol);
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker if (!Symbol->isBindingSet()) {
301*9880d681SAndroid Build Coastguard Worker Symbol->setBinding(ELF::STB_GLOBAL);
302*9880d681SAndroid Build Coastguard Worker Symbol->setExternal(true);
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker Symbol->setType(ELF::STT_OBJECT);
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker if (Symbol->getBinding() == ELF::STB_LOCAL) {
308*9880d681SAndroid Build Coastguard Worker MCSection &Section = *getAssembler().getContext().getELFSection(
309*9880d681SAndroid Build Coastguard Worker ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
310*9880d681SAndroid Build Coastguard Worker MCSectionSubPair P = getCurrentSection();
311*9880d681SAndroid Build Coastguard Worker SwitchSection(&Section);
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker EmitValueToAlignment(ByteAlignment, 0, 1, 0);
314*9880d681SAndroid Build Coastguard Worker EmitLabel(Symbol);
315*9880d681SAndroid Build Coastguard Worker EmitZeros(Size);
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Worker // Update the maximum alignment of the section if necessary.
318*9880d681SAndroid Build Coastguard Worker if (ByteAlignment > Section.getAlignment())
319*9880d681SAndroid Build Coastguard Worker Section.setAlignment(ByteAlignment);
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker SwitchSection(P.first, P.second);
322*9880d681SAndroid Build Coastguard Worker } else {
323*9880d681SAndroid Build Coastguard Worker if(Symbol->declareCommon(Size, ByteAlignment))
324*9880d681SAndroid Build Coastguard Worker report_fatal_error("Symbol: " + Symbol->getName() +
325*9880d681SAndroid Build Coastguard Worker " redeclared as different type");
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker cast<MCSymbolELF>(Symbol)
329*9880d681SAndroid Build Coastguard Worker ->setSize(MCConstantExpr::create(Size, getContext()));
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker
emitELFSize(MCSymbolELF * Symbol,const MCExpr * Value)332*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) {
333*9880d681SAndroid Build Coastguard Worker Symbol->setSize(Value);
334*9880d681SAndroid Build Coastguard Worker }
335*9880d681SAndroid Build Coastguard Worker
EmitLocalCommonSymbol(MCSymbol * S,uint64_t Size,unsigned ByteAlignment)336*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
337*9880d681SAndroid Build Coastguard Worker unsigned ByteAlignment) {
338*9880d681SAndroid Build Coastguard Worker auto *Symbol = cast<MCSymbolELF>(S);
339*9880d681SAndroid Build Coastguard Worker // FIXME: Should this be caught and done earlier?
340*9880d681SAndroid Build Coastguard Worker getAssembler().registerSymbol(*Symbol);
341*9880d681SAndroid Build Coastguard Worker Symbol->setBinding(ELF::STB_LOCAL);
342*9880d681SAndroid Build Coastguard Worker Symbol->setExternal(false);
343*9880d681SAndroid Build Coastguard Worker EmitCommonSymbol(Symbol, Size, ByteAlignment);
344*9880d681SAndroid Build Coastguard Worker }
345*9880d681SAndroid Build Coastguard Worker
EmitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)346*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
347*9880d681SAndroid Build Coastguard Worker SMLoc Loc) {
348*9880d681SAndroid Build Coastguard Worker if (isBundleLocked())
349*9880d681SAndroid Build Coastguard Worker report_fatal_error("Emitting values inside a locked bundle is forbidden");
350*9880d681SAndroid Build Coastguard Worker fixSymbolsInTLSFixups(Value);
351*9880d681SAndroid Build Coastguard Worker MCObjectStreamer::EmitValueImpl(Value, Size, Loc);
352*9880d681SAndroid Build Coastguard Worker }
353*9880d681SAndroid Build Coastguard Worker
EmitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)354*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
355*9880d681SAndroid Build Coastguard Worker int64_t Value,
356*9880d681SAndroid Build Coastguard Worker unsigned ValueSize,
357*9880d681SAndroid Build Coastguard Worker unsigned MaxBytesToEmit) {
358*9880d681SAndroid Build Coastguard Worker if (isBundleLocked())
359*9880d681SAndroid Build Coastguard Worker report_fatal_error("Emitting values inside a locked bundle is forbidden");
360*9880d681SAndroid Build Coastguard Worker MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value,
361*9880d681SAndroid Build Coastguard Worker ValueSize, MaxBytesToEmit);
362*9880d681SAndroid Build Coastguard Worker }
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker // Add a symbol for the file name of this module. They start after the
365*9880d681SAndroid Build Coastguard Worker // null symbol and don't count as normal symbol, i.e. a non-STT_FILE symbol
366*9880d681SAndroid Build Coastguard Worker // with the same name may appear.
EmitFileDirective(StringRef Filename)367*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitFileDirective(StringRef Filename) {
368*9880d681SAndroid Build Coastguard Worker getAssembler().addFileName(Filename);
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
EmitIdent(StringRef IdentString)371*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitIdent(StringRef IdentString) {
372*9880d681SAndroid Build Coastguard Worker MCSection *Comment = getAssembler().getContext().getELFSection(
373*9880d681SAndroid Build Coastguard Worker ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
374*9880d681SAndroid Build Coastguard Worker PushSection();
375*9880d681SAndroid Build Coastguard Worker SwitchSection(Comment);
376*9880d681SAndroid Build Coastguard Worker if (!SeenIdent) {
377*9880d681SAndroid Build Coastguard Worker EmitIntValue(0, 1);
378*9880d681SAndroid Build Coastguard Worker SeenIdent = true;
379*9880d681SAndroid Build Coastguard Worker }
380*9880d681SAndroid Build Coastguard Worker EmitBytes(IdentString);
381*9880d681SAndroid Build Coastguard Worker EmitIntValue(0, 1);
382*9880d681SAndroid Build Coastguard Worker PopSection();
383*9880d681SAndroid Build Coastguard Worker }
384*9880d681SAndroid Build Coastguard Worker
fixSymbolsInTLSFixups(const MCExpr * expr)385*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
386*9880d681SAndroid Build Coastguard Worker switch (expr->getKind()) {
387*9880d681SAndroid Build Coastguard Worker case MCExpr::Target:
388*9880d681SAndroid Build Coastguard Worker cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler());
389*9880d681SAndroid Build Coastguard Worker break;
390*9880d681SAndroid Build Coastguard Worker case MCExpr::Constant:
391*9880d681SAndroid Build Coastguard Worker break;
392*9880d681SAndroid Build Coastguard Worker
393*9880d681SAndroid Build Coastguard Worker case MCExpr::Binary: {
394*9880d681SAndroid Build Coastguard Worker const MCBinaryExpr *be = cast<MCBinaryExpr>(expr);
395*9880d681SAndroid Build Coastguard Worker fixSymbolsInTLSFixups(be->getLHS());
396*9880d681SAndroid Build Coastguard Worker fixSymbolsInTLSFixups(be->getRHS());
397*9880d681SAndroid Build Coastguard Worker break;
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker case MCExpr::SymbolRef: {
401*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr);
402*9880d681SAndroid Build Coastguard Worker switch (symRef.getKind()) {
403*9880d681SAndroid Build Coastguard Worker default:
404*9880d681SAndroid Build Coastguard Worker return;
405*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_GOTTPOFF:
406*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_INDNTPOFF:
407*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_NTPOFF:
408*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_GOTNTPOFF:
409*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_TLSGD:
410*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_TLSLD:
411*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_TLSLDM:
412*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_TPOFF:
413*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_TPREL:
414*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_DTPOFF:
415*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_DTPREL:
416*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPMOD:
417*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TPREL_LO:
418*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TPREL_HI:
419*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TPREL_HA:
420*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
421*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
422*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
423*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
424*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
425*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
426*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
427*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
428*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
429*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
430*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
431*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
432*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
433*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
434*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
435*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
436*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
437*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
438*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
439*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TLS:
440*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
441*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
442*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
443*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
444*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TLSGD:
445*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
446*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
447*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
448*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
449*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TLSLD:
450*9880d681SAndroid Build Coastguard Worker break;
451*9880d681SAndroid Build Coastguard Worker }
452*9880d681SAndroid Build Coastguard Worker getAssembler().registerSymbol(symRef.getSymbol());
453*9880d681SAndroid Build Coastguard Worker cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
454*9880d681SAndroid Build Coastguard Worker break;
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker
457*9880d681SAndroid Build Coastguard Worker case MCExpr::Unary:
458*9880d681SAndroid Build Coastguard Worker fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr());
459*9880d681SAndroid Build Coastguard Worker break;
460*9880d681SAndroid Build Coastguard Worker }
461*9880d681SAndroid Build Coastguard Worker }
462*9880d681SAndroid Build Coastguard Worker
EmitInstToFragment(const MCInst & Inst,const MCSubtargetInfo & STI)463*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitInstToFragment(const MCInst &Inst,
464*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) {
465*9880d681SAndroid Build Coastguard Worker this->MCObjectStreamer::EmitInstToFragment(Inst, STI);
466*9880d681SAndroid Build Coastguard Worker MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment());
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i)
469*9880d681SAndroid Build Coastguard Worker fixSymbolsInTLSFixups(F.getFixups()[i].getValue());
470*9880d681SAndroid Build Coastguard Worker }
471*9880d681SAndroid Build Coastguard Worker
EmitInstToData(const MCInst & Inst,const MCSubtargetInfo & STI)472*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitInstToData(const MCInst &Inst,
473*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) {
474*9880d681SAndroid Build Coastguard Worker MCAssembler &Assembler = getAssembler();
475*9880d681SAndroid Build Coastguard Worker SmallVector<MCFixup, 4> Fixups;
476*9880d681SAndroid Build Coastguard Worker SmallString<256> Code;
477*9880d681SAndroid Build Coastguard Worker raw_svector_ostream VecOS(Code);
478*9880d681SAndroid Build Coastguard Worker Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
481*9880d681SAndroid Build Coastguard Worker fixSymbolsInTLSFixups(Fixups[i].getValue());
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Worker // There are several possibilities here:
484*9880d681SAndroid Build Coastguard Worker //
485*9880d681SAndroid Build Coastguard Worker // If bundling is disabled, append the encoded instruction to the current data
486*9880d681SAndroid Build Coastguard Worker // fragment (or create a new such fragment if the current fragment is not a
487*9880d681SAndroid Build Coastguard Worker // data fragment).
488*9880d681SAndroid Build Coastguard Worker //
489*9880d681SAndroid Build Coastguard Worker // If bundling is enabled:
490*9880d681SAndroid Build Coastguard Worker // - If we're not in a bundle-locked group, emit the instruction into a
491*9880d681SAndroid Build Coastguard Worker // fragment of its own. If there are no fixups registered for the
492*9880d681SAndroid Build Coastguard Worker // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a
493*9880d681SAndroid Build Coastguard Worker // MCDataFragment.
494*9880d681SAndroid Build Coastguard Worker // - If we're in a bundle-locked group, append the instruction to the current
495*9880d681SAndroid Build Coastguard Worker // data fragment because we want all the instructions in a group to get into
496*9880d681SAndroid Build Coastguard Worker // the same fragment. Be careful not to do that for the first instruction in
497*9880d681SAndroid Build Coastguard Worker // the group, though.
498*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF;
499*9880d681SAndroid Build Coastguard Worker
500*9880d681SAndroid Build Coastguard Worker if (Assembler.isBundlingEnabled()) {
501*9880d681SAndroid Build Coastguard Worker MCSection &Sec = *getCurrentSectionOnly();
502*9880d681SAndroid Build Coastguard Worker if (Assembler.getRelaxAll() && isBundleLocked())
503*9880d681SAndroid Build Coastguard Worker // If the -mc-relax-all flag is used and we are bundle-locked, we re-use
504*9880d681SAndroid Build Coastguard Worker // the current bundle group.
505*9880d681SAndroid Build Coastguard Worker DF = BundleGroups.back();
506*9880d681SAndroid Build Coastguard Worker else if (Assembler.getRelaxAll() && !isBundleLocked())
507*9880d681SAndroid Build Coastguard Worker // When not in a bundle-locked group and the -mc-relax-all flag is used,
508*9880d681SAndroid Build Coastguard Worker // we create a new temporary fragment which will be later merged into
509*9880d681SAndroid Build Coastguard Worker // the current fragment.
510*9880d681SAndroid Build Coastguard Worker DF = new MCDataFragment();
511*9880d681SAndroid Build Coastguard Worker else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst())
512*9880d681SAndroid Build Coastguard Worker // If we are bundle-locked, we re-use the current fragment.
513*9880d681SAndroid Build Coastguard Worker // The bundle-locking directive ensures this is a new data fragment.
514*9880d681SAndroid Build Coastguard Worker DF = cast<MCDataFragment>(getCurrentFragment());
515*9880d681SAndroid Build Coastguard Worker else if (!isBundleLocked() && Fixups.size() == 0) {
516*9880d681SAndroid Build Coastguard Worker // Optimize memory usage by emitting the instruction to a
517*9880d681SAndroid Build Coastguard Worker // MCCompactEncodedInstFragment when not in a bundle-locked group and
518*9880d681SAndroid Build Coastguard Worker // there are no fixups registered.
519*9880d681SAndroid Build Coastguard Worker MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment();
520*9880d681SAndroid Build Coastguard Worker insert(CEIF);
521*9880d681SAndroid Build Coastguard Worker CEIF->getContents().append(Code.begin(), Code.end());
522*9880d681SAndroid Build Coastguard Worker return;
523*9880d681SAndroid Build Coastguard Worker } else {
524*9880d681SAndroid Build Coastguard Worker DF = new MCDataFragment();
525*9880d681SAndroid Build Coastguard Worker insert(DF);
526*9880d681SAndroid Build Coastguard Worker }
527*9880d681SAndroid Build Coastguard Worker if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) {
528*9880d681SAndroid Build Coastguard Worker // If this fragment is for a group marked "align_to_end", set a flag
529*9880d681SAndroid Build Coastguard Worker // in the fragment. This can happen after the fragment has already been
530*9880d681SAndroid Build Coastguard Worker // created if there are nested bundle_align groups and an inner one
531*9880d681SAndroid Build Coastguard Worker // is the one marked align_to_end.
532*9880d681SAndroid Build Coastguard Worker DF->setAlignToBundleEnd(true);
533*9880d681SAndroid Build Coastguard Worker }
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard Worker // We're now emitting an instruction in a bundle group, so this flag has
536*9880d681SAndroid Build Coastguard Worker // to be turned off.
537*9880d681SAndroid Build Coastguard Worker Sec.setBundleGroupBeforeFirstInst(false);
538*9880d681SAndroid Build Coastguard Worker } else {
539*9880d681SAndroid Build Coastguard Worker DF = getOrCreateDataFragment();
540*9880d681SAndroid Build Coastguard Worker }
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker // Add the fixups and data.
543*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
544*9880d681SAndroid Build Coastguard Worker Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
545*9880d681SAndroid Build Coastguard Worker DF->getFixups().push_back(Fixups[i]);
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker DF->setHasInstructions(true);
548*9880d681SAndroid Build Coastguard Worker DF->getContents().append(Code.begin(), Code.end());
549*9880d681SAndroid Build Coastguard Worker
550*9880d681SAndroid Build Coastguard Worker if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
551*9880d681SAndroid Build Coastguard Worker if (!isBundleLocked()) {
552*9880d681SAndroid Build Coastguard Worker mergeFragment(getOrCreateDataFragment(), DF);
553*9880d681SAndroid Build Coastguard Worker delete DF;
554*9880d681SAndroid Build Coastguard Worker }
555*9880d681SAndroid Build Coastguard Worker }
556*9880d681SAndroid Build Coastguard Worker }
557*9880d681SAndroid Build Coastguard Worker
EmitBundleAlignMode(unsigned AlignPow2)558*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
559*9880d681SAndroid Build Coastguard Worker assert(AlignPow2 <= 30 && "Invalid bundle alignment");
560*9880d681SAndroid Build Coastguard Worker MCAssembler &Assembler = getAssembler();
561*9880d681SAndroid Build Coastguard Worker if (AlignPow2 > 0 && (Assembler.getBundleAlignSize() == 0 ||
562*9880d681SAndroid Build Coastguard Worker Assembler.getBundleAlignSize() == 1U << AlignPow2))
563*9880d681SAndroid Build Coastguard Worker Assembler.setBundleAlignSize(1U << AlignPow2);
564*9880d681SAndroid Build Coastguard Worker else
565*9880d681SAndroid Build Coastguard Worker report_fatal_error(".bundle_align_mode cannot be changed once set");
566*9880d681SAndroid Build Coastguard Worker }
567*9880d681SAndroid Build Coastguard Worker
EmitBundleLock(bool AlignToEnd)568*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
569*9880d681SAndroid Build Coastguard Worker MCSection &Sec = *getCurrentSectionOnly();
570*9880d681SAndroid Build Coastguard Worker
571*9880d681SAndroid Build Coastguard Worker // Sanity checks
572*9880d681SAndroid Build Coastguard Worker //
573*9880d681SAndroid Build Coastguard Worker if (!getAssembler().isBundlingEnabled())
574*9880d681SAndroid Build Coastguard Worker report_fatal_error(".bundle_lock forbidden when bundling is disabled");
575*9880d681SAndroid Build Coastguard Worker
576*9880d681SAndroid Build Coastguard Worker if (!isBundleLocked())
577*9880d681SAndroid Build Coastguard Worker Sec.setBundleGroupBeforeFirstInst(true);
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Worker if (getAssembler().getRelaxAll() && !isBundleLocked()) {
580*9880d681SAndroid Build Coastguard Worker // TODO: drop the lock state and set directly in the fragment
581*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = new MCDataFragment();
582*9880d681SAndroid Build Coastguard Worker BundleGroups.push_back(DF);
583*9880d681SAndroid Build Coastguard Worker }
584*9880d681SAndroid Build Coastguard Worker
585*9880d681SAndroid Build Coastguard Worker Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd
586*9880d681SAndroid Build Coastguard Worker : MCSection::BundleLocked);
587*9880d681SAndroid Build Coastguard Worker }
588*9880d681SAndroid Build Coastguard Worker
EmitBundleUnlock()589*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitBundleUnlock() {
590*9880d681SAndroid Build Coastguard Worker MCSection &Sec = *getCurrentSectionOnly();
591*9880d681SAndroid Build Coastguard Worker
592*9880d681SAndroid Build Coastguard Worker // Sanity checks
593*9880d681SAndroid Build Coastguard Worker if (!getAssembler().isBundlingEnabled())
594*9880d681SAndroid Build Coastguard Worker report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
595*9880d681SAndroid Build Coastguard Worker else if (!isBundleLocked())
596*9880d681SAndroid Build Coastguard Worker report_fatal_error(".bundle_unlock without matching lock");
597*9880d681SAndroid Build Coastguard Worker else if (Sec.isBundleGroupBeforeFirstInst())
598*9880d681SAndroid Build Coastguard Worker report_fatal_error("Empty bundle-locked group is forbidden");
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker // When the -mc-relax-all flag is used, we emit instructions to fragments
601*9880d681SAndroid Build Coastguard Worker // stored on a stack. When the bundle unlock is emitted, we pop a fragment
602*9880d681SAndroid Build Coastguard Worker // from the stack a merge it to the one below.
603*9880d681SAndroid Build Coastguard Worker if (getAssembler().getRelaxAll()) {
604*9880d681SAndroid Build Coastguard Worker assert(!BundleGroups.empty() && "There are no bundle groups");
605*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = BundleGroups.back();
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker // FIXME: Use BundleGroups to track the lock state instead.
608*9880d681SAndroid Build Coastguard Worker Sec.setBundleLockState(MCSection::NotBundleLocked);
609*9880d681SAndroid Build Coastguard Worker
610*9880d681SAndroid Build Coastguard Worker // FIXME: Use more separate fragments for nested groups.
611*9880d681SAndroid Build Coastguard Worker if (!isBundleLocked()) {
612*9880d681SAndroid Build Coastguard Worker mergeFragment(getOrCreateDataFragment(), DF);
613*9880d681SAndroid Build Coastguard Worker BundleGroups.pop_back();
614*9880d681SAndroid Build Coastguard Worker delete DF;
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker
617*9880d681SAndroid Build Coastguard Worker if (Sec.getBundleLockState() != MCSection::BundleLockedAlignToEnd)
618*9880d681SAndroid Build Coastguard Worker getOrCreateDataFragment()->setAlignToBundleEnd(false);
619*9880d681SAndroid Build Coastguard Worker } else
620*9880d681SAndroid Build Coastguard Worker Sec.setBundleLockState(MCSection::NotBundleLocked);
621*9880d681SAndroid Build Coastguard Worker }
622*9880d681SAndroid Build Coastguard Worker
FinishImpl()623*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::FinishImpl() {
624*9880d681SAndroid Build Coastguard Worker // Ensure the last section gets aligned if necessary.
625*9880d681SAndroid Build Coastguard Worker MCSection *CurSection = getCurrentSectionOnly();
626*9880d681SAndroid Build Coastguard Worker setSectionAlignmentForBundling(getAssembler(), CurSection);
627*9880d681SAndroid Build Coastguard Worker
628*9880d681SAndroid Build Coastguard Worker EmitFrames(nullptr);
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker this->MCObjectStreamer::FinishImpl();
631*9880d681SAndroid Build Coastguard Worker }
632*9880d681SAndroid Build Coastguard Worker
createELFStreamer(MCContext & Context,MCAsmBackend & MAB,raw_pwrite_stream & OS,MCCodeEmitter * CE,bool RelaxAll)633*9880d681SAndroid Build Coastguard Worker MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
634*9880d681SAndroid Build Coastguard Worker raw_pwrite_stream &OS, MCCodeEmitter *CE,
635*9880d681SAndroid Build Coastguard Worker bool RelaxAll) {
636*9880d681SAndroid Build Coastguard Worker MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
637*9880d681SAndroid Build Coastguard Worker if (RelaxAll)
638*9880d681SAndroid Build Coastguard Worker S->getAssembler().setRelaxAll(true);
639*9880d681SAndroid Build Coastguard Worker return S;
640*9880d681SAndroid Build Coastguard Worker }
641*9880d681SAndroid Build Coastguard Worker
EmitThumbFunc(MCSymbol * Func)642*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
643*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Generic ELF doesn't support this directive");
644*9880d681SAndroid Build Coastguard Worker }
645*9880d681SAndroid Build Coastguard Worker
EmitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)646*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
647*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support this directive");
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker
BeginCOFFSymbolDef(const MCSymbol * Symbol)650*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
651*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support this directive");
652*9880d681SAndroid Build Coastguard Worker }
653*9880d681SAndroid Build Coastguard Worker
EmitCOFFSymbolStorageClass(int StorageClass)654*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
655*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support this directive");
656*9880d681SAndroid Build Coastguard Worker }
657*9880d681SAndroid Build Coastguard Worker
EmitCOFFSymbolType(int Type)658*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitCOFFSymbolType(int Type) {
659*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support this directive");
660*9880d681SAndroid Build Coastguard Worker }
661*9880d681SAndroid Build Coastguard Worker
EndCOFFSymbolDef()662*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EndCOFFSymbolDef() {
663*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support this directive");
664*9880d681SAndroid Build Coastguard Worker }
665*9880d681SAndroid Build Coastguard Worker
EmitZerofill(MCSection * Section,MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)666*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
667*9880d681SAndroid Build Coastguard Worker uint64_t Size, unsigned ByteAlignment) {
668*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support this directive");
669*9880d681SAndroid Build Coastguard Worker }
670*9880d681SAndroid Build Coastguard Worker
EmitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)671*9880d681SAndroid Build Coastguard Worker void MCELFStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
672*9880d681SAndroid Build Coastguard Worker uint64_t Size, unsigned ByteAlignment) {
673*9880d681SAndroid Build Coastguard Worker llvm_unreachable("ELF doesn't support this directive");
674*9880d681SAndroid Build Coastguard Worker }
675