xref: /aosp_15_r20/external/llvm/lib/MC/MCELFStreamer.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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