1 //===- bolt/Core/BinaryEmitter.cpp - Emit code and data -------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the collection of functions and classes used for
10 // emission of code and data into object/binary file.
12 //===----------------------------------------------------------------------===//
14 #include "bolt/Core/BinaryEmitter.h"
15 #include "bolt/Core/BinaryContext.h"
16 #include "bolt/Core/BinaryFunction.h"
17 #include "bolt/Core/DebugData.h"
18 #include "bolt/Core/FunctionLayout.h"
19 #include "bolt/Utils/CommandLineOpts.h"
20 #include "bolt/Utils/Utils.h"
21 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
22 #include "llvm/MC/MCSection.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/Support/CommandLine.h"
25 #include "llvm/Support/LEB128.h"
26 #include "llvm/Support/SMLoc.h"
28 #define DEBUG_TYPE "bolt"
35 extern cl::opt
<JumpTableSupportLevel
> JumpTables
;
36 extern cl::opt
<bool> PreserveBlocksAlignment
;
38 cl::opt
<bool> AlignBlocks("align-blocks", cl::desc("align basic blocks"),
39 cl::cat(BoltOptCategory
));
41 static cl::list
<std::string
>
42 BreakFunctionNames("break-funcs",
44 cl::desc("list of functions to core dump on (debugging)"),
45 cl::value_desc("func1,func2,func3,..."),
47 cl::cat(BoltCategory
));
50 FunctionPadSpec("pad-funcs", cl::CommaSeparated
,
51 cl::desc("list of functions to pad with amount of bytes"),
52 cl::value_desc("func1:pad1,func2:pad2,func3:pad3,..."),
53 cl::Hidden
, cl::cat(BoltCategory
));
55 cl::list
<std::string
> FunctionPadBeforeSpec(
56 "pad-funcs-before", cl::CommaSeparated
,
57 cl::desc("list of functions to pad with amount of bytes"),
58 cl::value_desc("func1:pad1,func2:pad2,func3:pad3,..."), cl::Hidden
,
59 cl::cat(BoltCategory
));
61 static cl::opt
<bool> MarkFuncs(
63 cl::desc("mark function boundaries with break instruction to make "
64 "sure we accidentally don't cross them"),
65 cl::ReallyHidden
, cl::cat(BoltCategory
));
67 static cl::opt
<bool> PrintJumpTables("print-jump-tables",
68 cl::desc("print jump tables"), cl::Hidden
,
69 cl::cat(BoltCategory
));
72 X86AlignBranchBoundaryHotOnly("x86-align-branch-boundary-hot-only",
73 cl::desc("only apply branch boundary alignment in hot code"),
75 cl::cat(BoltOptCategory
));
77 size_t padFunction(const cl::list
<std::string
> &Spec
,
78 const BinaryFunction
&Function
) {
79 static std::map
<std::string
, size_t> FunctionPadding
;
81 if (FunctionPadding
.empty() && !Spec
.empty()) {
82 for (const std::string
&Spec
: Spec
) {
83 size_t N
= Spec
.find(':');
84 if (N
== std::string::npos
)
86 std::string Name
= Spec
.substr(0, N
);
87 size_t Padding
= std::stoull(Spec
.substr(N
+ 1));
88 FunctionPadding
[Name
] = Padding
;
92 for (auto &FPI
: FunctionPadding
) {
93 std::string Name
= FPI
.first
;
94 size_t Padding
= FPI
.second
;
95 if (Function
.hasNameRegex(Name
))
105 using JumpTable
= bolt::JumpTable
;
107 class BinaryEmitter
{
109 BinaryEmitter(const BinaryEmitter
&) = delete;
110 BinaryEmitter
&operator=(const BinaryEmitter
&) = delete;
112 MCStreamer
&Streamer
;
116 BinaryEmitter(MCStreamer
&Streamer
, BinaryContext
&BC
)
117 : Streamer(Streamer
), BC(BC
) {}
119 /// Emit all code and data.
120 void emitAll(StringRef OrgSecPrefix
);
122 /// Emit function code. The caller is responsible for emitting function
123 /// symbol(s) and setting the section to emit the code to.
124 void emitFunctionBody(BinaryFunction
&BF
, FunctionFragment
&FF
,
125 bool EmitCodeOnly
= false);
128 /// Emit function code.
129 void emitFunctions();
131 /// Emit a single function.
132 bool emitFunction(BinaryFunction
&BF
, FunctionFragment
&FF
);
134 /// Helper for emitFunctionBody to write data inside a function
135 /// (used for AArch64)
136 void emitConstantIslands(BinaryFunction
&BF
, bool EmitColdPart
,
137 BinaryFunction
*OnBehalfOf
= nullptr);
139 /// Emit jump tables for the function.
140 void emitJumpTables(const BinaryFunction
&BF
);
142 /// Emit jump table data. Callee supplies sections for the data.
143 void emitJumpTable(const JumpTable
&JT
, MCSection
*HotSection
,
144 MCSection
*ColdSection
);
146 void emitCFIInstruction(const MCCFIInstruction
&Inst
) const;
148 /// Emit exception handling ranges for the function fragment.
149 void emitLSDA(BinaryFunction
&BF
, const FunctionFragment
&FF
);
151 /// Emit line number information corresponding to \p NewLoc. \p PrevLoc
152 /// provides a context for de-duplication of line number info.
153 /// \p FirstInstr indicates if \p NewLoc represents the first instruction
154 /// in a sequence, such as a function fragment.
156 /// If \p NewLoc location matches \p PrevLoc, no new line number entry will be
157 /// created and the function will return \p PrevLoc while \p InstrLabel will
158 /// be ignored. Otherwise, the caller should use \p InstrLabel to mark the
159 /// corresponding instruction by emitting \p InstrLabel before it.
160 /// If \p InstrLabel is set by the caller, its value will be used with \p
161 /// \p NewLoc. If it was nullptr on entry, it will be populated with a pointer
162 /// to a new temp symbol used with \p NewLoc.
164 /// Return new current location which is either \p NewLoc or \p PrevLoc.
165 SMLoc
emitLineInfo(const BinaryFunction
&BF
, SMLoc NewLoc
, SMLoc PrevLoc
,
166 bool FirstInstr
, MCSymbol
*&InstrLabel
);
168 /// Use \p FunctionEndSymbol to mark the end of the line info sequence.
169 /// Note that it does not automatically result in the insertion of the EOS
170 /// marker in the line table program, but provides one to the DWARF generator
171 /// when it needs it.
172 void emitLineInfoEnd(const BinaryFunction
&BF
, MCSymbol
*FunctionEndSymbol
);
174 /// Emit debug line info for unprocessed functions from CUs that include
175 /// emitted functions.
176 void emitDebugLineInfoForOriginalFunctions();
178 /// Emit debug line for CUs that were not modified.
179 void emitDebugLineInfoForUnprocessedCUs();
181 /// Emit data sections that have code references in them.
182 void emitDataSections(StringRef OrgSecPrefix
);
185 } // anonymous namespace
187 void BinaryEmitter::emitAll(StringRef OrgSecPrefix
) {
188 Streamer
.initSections(false, *BC
.STI
);
189 Streamer
.setUseAssemblerInfoForParsing(false);
191 if (opts::UpdateDebugSections
&& BC
.isELF()) {
192 // Force the emission of debug line info into allocatable section to ensure
193 // JITLink will process it.
195 // NB: on MachO all sections are required for execution, hence no need
196 // to change flags/attributes.
197 MCSectionELF
*ELFDwarfLineSection
=
198 static_cast<MCSectionELF
*>(BC
.MOFI
->getDwarfLineSection());
199 ELFDwarfLineSection
->setFlags(ELF::SHF_ALLOC
);
200 MCSectionELF
*ELFDwarfLineStrSection
=
201 static_cast<MCSectionELF
*>(BC
.MOFI
->getDwarfLineStrSection());
202 ELFDwarfLineStrSection
->setFlags(ELF::SHF_ALLOC
);
205 if (RuntimeLibrary
*RtLibrary
= BC
.getRuntimeLibrary())
206 RtLibrary
->emitBinary(BC
, Streamer
);
208 BC
.getTextSection()->setAlignment(Align(opts::AlignText
));
212 if (opts::UpdateDebugSections
) {
213 emitDebugLineInfoForOriginalFunctions();
214 DwarfLineTable::emit(BC
, Streamer
);
217 emitDataSections(OrgSecPrefix
);
219 // TODO Enable for Mach-O once BinaryContext::getDataSection supports it.
221 AddressMap::emit(Streamer
, BC
);
222 Streamer
.setUseAssemblerInfoForParsing(true);
225 void BinaryEmitter::emitFunctions() {
226 auto emit
= [&](const std::vector
<BinaryFunction
*> &Functions
) {
227 const bool HasProfile
= BC
.NumProfiledFuncs
> 0;
228 const bool OriginalAllowAutoPadding
= Streamer
.getAllowAutoPadding();
229 for (BinaryFunction
*Function
: Functions
) {
230 if (!BC
.shouldEmit(*Function
))
233 LLVM_DEBUG(dbgs() << "BOLT: generating code for function \"" << *Function
234 << "\" : " << Function
->getFunctionNumber() << '\n');
236 // Was any part of the function emitted.
237 bool Emitted
= false;
239 // Turn off Intel JCC Erratum mitigation for cold code if requested
240 if (HasProfile
&& opts::X86AlignBranchBoundaryHotOnly
&&
241 !Function
->hasValidProfile())
242 Streamer
.setAllowAutoPadding(false);
244 FunctionLayout
&Layout
= Function
->getLayout();
245 Emitted
|= emitFunction(*Function
, Layout
.getMainFragment());
247 if (Function
->isSplit()) {
248 if (opts::X86AlignBranchBoundaryHotOnly
)
249 Streamer
.setAllowAutoPadding(false);
251 assert((Layout
.fragment_size() == 1 || Function
->isSimple()) &&
252 "Only simple functions can have fragments");
253 for (FunctionFragment
&FF
: Layout
.getSplitFragments()) {
254 // Skip empty fragments so no symbols and sections for empty fragments
256 if (FF
.empty() && !Function
->hasConstantIsland())
258 Emitted
|= emitFunction(*Function
, FF
);
262 Streamer
.setAllowAutoPadding(OriginalAllowAutoPadding
);
265 Function
->setEmitted(/*KeepCFG=*/opts::PrintCacheMetrics
);
269 // Mark the start of hot text.
271 Streamer
.switchSection(BC
.getTextSection());
272 Streamer
.emitLabel(BC
.getHotTextStartSymbol());
275 // Emit functions in sorted order.
276 std::vector
<BinaryFunction
*> SortedFunctions
= BC
.getSortedFunctions();
277 emit(SortedFunctions
);
279 // Emit functions added by BOLT.
280 emit(BC
.getInjectedBinaryFunctions());
282 // Mark the end of hot text.
284 if (BC
.HasWarmSection
)
285 Streamer
.switchSection(BC
.getCodeSection(BC
.getWarmCodeSectionName()));
287 Streamer
.switchSection(BC
.getTextSection());
288 Streamer
.emitLabel(BC
.getHotTextEndSymbol());
292 bool BinaryEmitter::emitFunction(BinaryFunction
&Function
,
293 FunctionFragment
&FF
) {
294 if (Function
.size() == 0 && !Function
.hasIslandsInfo())
297 if (Function
.getState() == BinaryFunction::State::Empty
)
300 // Avoid emitting function without instructions when overwriting the original
301 // function in-place. Otherwise, emit the empty function to define the symbol.
302 if (!BC
.HasRelocations
&& !Function
.hasNonPseudoInstructions())
306 BC
.getCodeSection(Function
.getCodeSectionName(FF
.getFragmentNum()));
307 Streamer
.switchSection(Section
);
308 Section
->setHasInstructions(true);
309 BC
.Ctx
->addGenDwarfSection(Section
);
311 if (BC
.HasRelocations
) {
312 // Set section alignment to at least maximum possible object alignment.
313 // We need this to support LongJmp and other passes that calculates
315 Section
->ensureMinAlignment(Align(opts::AlignFunctions
));
317 Streamer
.emitCodeAlignment(Function
.getMinAlign(), &*BC
.STI
);
318 uint16_t MaxAlignBytes
= FF
.isSplitFragment()
319 ? Function
.getMaxColdAlignmentBytes()
320 : Function
.getMaxAlignmentBytes();
321 if (MaxAlignBytes
> 0)
322 Streamer
.emitCodeAlignment(Function
.getAlign(), &*BC
.STI
, MaxAlignBytes
);
324 Streamer
.emitCodeAlignment(Function
.getAlign(), &*BC
.STI
);
328 opts::padFunction(opts::FunctionPadBeforeSpec
, Function
)) {
329 // Handle padFuncsBefore after the above alignment logic but before
330 // symbol addresses are decided.
331 if (!BC
.HasRelocations
) {
332 BC
.errs() << "BOLT-ERROR: -pad-before-funcs is not supported in "
333 << "non-relocation mode\n";
337 // Preserve Function.getMinAlign().
338 if (!isAligned(Function
.getMinAlign(), Padding
)) {
339 BC
.errs() << "BOLT-ERROR: user-requested " << Padding
340 << " padding bytes before function " << Function
341 << " is not a multiple of the minimum function alignment ("
342 << Function
.getMinAlign().value() << ").\n";
346 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: padding before function " << Function
347 << " with " << Padding
<< " bytes\n");
349 // Since the padding is not executed, it can be null bytes.
350 Streamer
.emitFill(Padding
, 0);
353 MCContext
&Context
= Streamer
.getContext();
354 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
356 MCSymbol
*const StartSymbol
= Function
.getSymbol(FF
.getFragmentNum());
358 // Emit all symbols associated with the main function entry.
359 if (FF
.isMainFragment()) {
360 for (MCSymbol
*Symbol
: Function
.getSymbols()) {
361 Streamer
.emitSymbolAttribute(Symbol
, MCSA_ELF_TypeFunction
);
362 Streamer
.emitLabel(Symbol
);
365 Streamer
.emitSymbolAttribute(StartSymbol
, MCSA_ELF_TypeFunction
);
366 Streamer
.emitLabel(StartSymbol
);
370 if (Function
.hasCFI()) {
371 Streamer
.emitCFIStartProc(/*IsSimple=*/false);
372 if (Function
.getPersonalityFunction() != nullptr)
373 Streamer
.emitCFIPersonality(Function
.getPersonalityFunction(),
374 Function
.getPersonalityEncoding());
375 MCSymbol
*LSDASymbol
= Function
.getLSDASymbol(FF
.getFragmentNum());
377 Streamer
.emitCFILsda(LSDASymbol
, BC
.LSDAEncoding
);
379 Streamer
.emitCFILsda(0, dwarf::DW_EH_PE_omit
);
380 // Emit CFI instructions relative to the CIE
381 for (const MCCFIInstruction
&CFIInstr
: Function
.cie()) {
382 // Only write CIE CFI insns that LLVM will not already emit
383 const std::vector
<MCCFIInstruction
> &FrameInstrs
=
384 MAI
->getInitialFrameState();
385 if (!llvm::is_contained(FrameInstrs
, CFIInstr
))
386 emitCFIInstruction(CFIInstr
);
390 assert((Function
.empty() || !(*Function
.begin()).isCold()) &&
391 "first basic block should never be cold");
393 // Emit UD2 at the beginning if requested by user.
394 if (!opts::BreakFunctionNames
.empty()) {
395 for (std::string
&Name
: opts::BreakFunctionNames
) {
396 if (Function
.hasNameRegex(Name
)) {
397 Streamer
.emitIntValue(0x0B0F, 2); // UD2: 0F 0B
404 emitFunctionBody(Function
, FF
, /*EmitCodeOnly=*/false);
406 // Emit padding if requested.
407 if (size_t Padding
= opts::padFunction(opts::FunctionPadSpec
, Function
)) {
408 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: padding function " << Function
<< " with "
409 << Padding
<< " bytes\n");
410 Streamer
.emitFill(Padding
, MAI
->getTextAlignFillValue());
414 Streamer
.emitBytes(BC
.MIB
->getTrapFillValue());
417 if (Function
.hasCFI())
418 Streamer
.emitCFIEndProc();
420 MCSymbol
*EndSymbol
= Function
.getFunctionEndLabel(FF
.getFragmentNum());
421 Streamer
.emitLabel(EndSymbol
);
423 if (MAI
->hasDotTypeDotSizeDirective()) {
424 const MCExpr
*SizeExpr
= MCBinaryExpr::createSub(
425 MCSymbolRefExpr::create(EndSymbol
, Context
),
426 MCSymbolRefExpr::create(StartSymbol
, Context
), Context
);
427 Streamer
.emitELFSize(StartSymbol
, SizeExpr
);
430 if (opts::UpdateDebugSections
&& Function
.getDWARFUnit())
431 emitLineInfoEnd(Function
, EndSymbol
);
433 // Exception handling info for the function.
434 emitLSDA(Function
, FF
);
436 if (FF
.isMainFragment() && opts::JumpTables
> JTS_NONE
)
437 emitJumpTables(Function
);
442 void BinaryEmitter::emitFunctionBody(BinaryFunction
&BF
, FunctionFragment
&FF
,
444 if (!EmitCodeOnly
&& FF
.isSplitFragment() && BF
.hasConstantIsland()) {
445 assert(BF
.getLayout().isHotColdSplit() &&
446 "Constant island support only with hot/cold split");
447 BF
.duplicateConstantIslands();
450 // Track the first emitted instruction with debug info.
451 bool FirstInstr
= true;
452 for (BinaryBasicBlock
*const BB
: FF
) {
453 if ((opts::AlignBlocks
|| opts::PreserveBlocksAlignment
) &&
454 BB
->getAlignment() > 1)
455 Streamer
.emitCodeAlignment(BB
->getAlign(), &*BC
.STI
,
456 BB
->getAlignmentMaxBytes());
457 Streamer
.emitLabel(BB
->getLabel());
459 if (MCSymbol
*EntrySymbol
= BF
.getSecondaryEntryPointSymbol(*BB
))
460 Streamer
.emitLabel(EntrySymbol
);
464 for (auto I
= BB
->begin(), E
= BB
->end(); I
!= E
; ++I
) {
467 if (EmitCodeOnly
&& BC
.MIB
->isPseudo(Instr
))
470 // Handle pseudo instructions.
471 if (BC
.MIB
->isCFI(Instr
)) {
472 emitCFIInstruction(*BF
.getCFIFor(Instr
));
477 // A symbol to be emitted before the instruction to mark its location.
478 MCSymbol
*InstrLabel
= BC
.MIB
->getInstLabel(Instr
);
480 if (opts::UpdateDebugSections
&& BF
.getDWARFUnit()) {
481 LastLocSeen
= emitLineInfo(BF
, Instr
.getLoc(), LastLocSeen
,
482 FirstInstr
, InstrLabel
);
486 // Prepare to tag this location with a label if we need to keep track of
487 // the location of calls/returns for BOLT address translation maps
488 if (BF
.requiresAddressTranslation() && BC
.MIB
->getOffset(Instr
)) {
489 const uint32_t Offset
= *BC
.MIB
->getOffset(Instr
);
491 InstrLabel
= BC
.Ctx
->createTempSymbol();
492 BB
->getLocSyms().emplace_back(Offset
, InstrLabel
);
496 Streamer
.emitLabel(InstrLabel
);
499 // Emit sized NOPs via MCAsmBackend::writeNopData() interface on x86.
500 // This is a workaround for invalid NOPs handling by asm/disasm layer.
501 if (BC
.isX86() && BC
.MIB
->isNoop(Instr
)) {
502 if (std::optional
<uint32_t> Size
= BC
.MIB
->getSize(Instr
)) {
503 SmallString
<15> Code
;
504 raw_svector_ostream
VecOS(Code
);
505 BC
.MAB
->writeNopData(VecOS
, *Size
, BC
.STI
.get());
506 Streamer
.emitBytes(Code
);
511 Streamer
.emitInstruction(Instr
, *BC
.STI
);
516 emitConstantIslands(BF
, FF
.isSplitFragment());
519 void BinaryEmitter::emitConstantIslands(BinaryFunction
&BF
, bool EmitColdPart
,
520 BinaryFunction
*OnBehalfOf
) {
521 if (!BF
.hasIslandsInfo())
524 BinaryFunction::IslandInfo
&Islands
= BF
.getIslandInfo();
525 if (Islands
.DataOffsets
.empty() && Islands
.Dependency
.empty())
528 // AArch64 requires CI to be aligned to 8 bytes due to access instructions
529 // restrictions. E.g. the ldr with imm, where imm must be aligned to 8 bytes.
530 const uint16_t Alignment
= OnBehalfOf
531 ? OnBehalfOf
->getConstantIslandAlignment()
532 : BF
.getConstantIslandAlignment();
533 Streamer
.emitCodeAlignment(Align(Alignment
), &*BC
.STI
);
537 Streamer
.emitLabel(BF
.getFunctionConstantIslandLabel());
539 Streamer
.emitLabel(BF
.getFunctionColdConstantIslandLabel());
542 assert((!OnBehalfOf
|| Islands
.Proxies
[OnBehalfOf
].size() > 0) &&
543 "spurious OnBehalfOf constant island emission");
545 assert(!BF
.isInjected() &&
546 "injected functions should not have constant islands");
547 // Raw contents of the function.
548 StringRef SectionContents
= BF
.getOriginSection()->getContents();
550 // Raw contents of the function.
551 StringRef FunctionContents
= SectionContents
.substr(
552 BF
.getAddress() - BF
.getOriginSection()->getAddress(), BF
.getMaxSize());
554 if (opts::Verbosity
&& !OnBehalfOf
)
555 BC
.outs() << "BOLT-INFO: emitting constant island for function " << BF
558 // We split the island into smaller blocks and output labels between them.
559 auto IS
= Islands
.Offsets
.begin();
560 for (auto DataIter
= Islands
.DataOffsets
.begin();
561 DataIter
!= Islands
.DataOffsets
.end(); ++DataIter
) {
562 uint64_t FunctionOffset
= *DataIter
;
563 uint64_t EndOffset
= 0ULL;
565 // Determine size of this data chunk
566 auto NextData
= std::next(DataIter
);
567 auto CodeIter
= Islands
.CodeOffsets
.lower_bound(*DataIter
);
568 if (CodeIter
== Islands
.CodeOffsets
.end() &&
569 NextData
== Islands
.DataOffsets
.end())
570 EndOffset
= BF
.getMaxSize();
571 else if (CodeIter
== Islands
.CodeOffsets
.end())
572 EndOffset
= *NextData
;
573 else if (NextData
== Islands
.DataOffsets
.end())
574 EndOffset
= *CodeIter
;
576 EndOffset
= (*CodeIter
> *NextData
) ? *NextData
: *CodeIter
;
578 if (FunctionOffset
== EndOffset
)
579 continue; // Size is zero, nothing to emit
581 auto emitCI
= [&](uint64_t &FunctionOffset
, uint64_t EndOffset
) {
582 if (FunctionOffset
>= EndOffset
)
585 for (auto It
= Islands
.Relocations
.lower_bound(FunctionOffset
);
586 It
!= Islands
.Relocations
.end(); ++It
) {
587 if (It
->first
>= EndOffset
)
590 const Relocation
&Relocation
= It
->second
;
591 if (FunctionOffset
< Relocation
.Offset
) {
593 FunctionContents
.slice(FunctionOffset
, Relocation
.Offset
));
594 FunctionOffset
= Relocation
.Offset
;
598 dbgs() << "BOLT-DEBUG: emitting constant island relocation"
599 << " for " << BF
<< " at offset 0x"
600 << Twine::utohexstr(Relocation
.Offset
) << " with size "
601 << Relocation::getSizeForType(Relocation
.Type
) << '\n');
603 FunctionOffset
+= Relocation
.emit(&Streamer
);
606 assert(FunctionOffset
<= EndOffset
&& "overflow error");
607 if (FunctionOffset
< EndOffset
) {
608 Streamer
.emitBytes(FunctionContents
.slice(FunctionOffset
, EndOffset
));
609 FunctionOffset
= EndOffset
;
613 // Emit labels, relocs and data
614 while (IS
!= Islands
.Offsets
.end() && IS
->first
< EndOffset
) {
615 auto NextLabelOffset
=
616 IS
== Islands
.Offsets
.end() ? EndOffset
: IS
->first
;
617 auto NextStop
= std::min(NextLabelOffset
, EndOffset
);
618 assert(NextStop
<= EndOffset
&& "internal overflow error");
619 emitCI(FunctionOffset
, NextStop
);
620 if (IS
!= Islands
.Offsets
.end() && FunctionOffset
== IS
->first
) {
621 // This is a slightly complex code to decide which label to emit. We
622 // have 4 cases to handle: regular symbol, cold symbol, regular or cold
623 // symbol being emitted on behalf of an external function.
626 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: emitted label "
627 << IS
->second
->getName() << " at offset 0x"
628 << Twine::utohexstr(IS
->first
) << '\n');
629 if (IS
->second
->isUndefined())
630 Streamer
.emitLabel(IS
->second
);
632 assert(BF
.hasName(std::string(IS
->second
->getName())));
633 } else if (Islands
.ColdSymbols
.count(IS
->second
) != 0) {
635 << "BOLT-DEBUG: emitted label "
636 << Islands
.ColdSymbols
[IS
->second
]->getName() << '\n');
637 if (Islands
.ColdSymbols
[IS
->second
]->isUndefined())
638 Streamer
.emitLabel(Islands
.ColdSymbols
[IS
->second
]);
642 if (MCSymbol
*Sym
= Islands
.Proxies
[OnBehalfOf
][IS
->second
]) {
643 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: emitted label "
644 << Sym
->getName() << '\n');
645 Streamer
.emitLabel(Sym
);
647 } else if (MCSymbol
*Sym
=
648 Islands
.ColdProxies
[OnBehalfOf
][IS
->second
]) {
649 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: emitted label " << Sym
->getName()
651 Streamer
.emitLabel(Sym
);
657 assert(FunctionOffset
<= EndOffset
&& "overflow error");
658 emitCI(FunctionOffset
, EndOffset
);
660 assert(IS
== Islands
.Offsets
.end() && "some symbols were not emitted!");
664 // Now emit constant islands from other functions that we may have used in
666 for (BinaryFunction
*ExternalFunc
: Islands
.Dependency
)
667 emitConstantIslands(*ExternalFunc
, EmitColdPart
, &BF
);
670 SMLoc
BinaryEmitter::emitLineInfo(const BinaryFunction
&BF
, SMLoc NewLoc
,
671 SMLoc PrevLoc
, bool FirstInstr
,
672 MCSymbol
*&InstrLabel
) {
673 DWARFUnit
*FunctionCU
= BF
.getDWARFUnit();
674 const DWARFDebugLine::LineTable
*FunctionLineTable
= BF
.getDWARFLineTable();
675 assert(FunctionCU
&& "cannot emit line info for function without CU");
677 DebugLineTableRowRef RowReference
= DebugLineTableRowRef::fromSMLoc(NewLoc
);
679 // Check if no new line info needs to be emitted.
680 if (RowReference
== DebugLineTableRowRef::NULL_ROW
||
681 NewLoc
.getPointer() == PrevLoc
.getPointer())
684 unsigned CurrentFilenum
= 0;
685 const DWARFDebugLine::LineTable
*CurrentLineTable
= FunctionLineTable
;
687 // If the CU id from the current instruction location does not
688 // match the CU id from the current function, it means that we
689 // have come across some inlined code. We must look up the CU
690 // for the instruction's original function and get the line table
692 const uint64_t FunctionUnitIndex
= FunctionCU
->getOffset();
693 const uint32_t CurrentUnitIndex
= RowReference
.DwCompileUnitIndex
;
694 if (CurrentUnitIndex
!= FunctionUnitIndex
) {
695 CurrentLineTable
= BC
.DwCtx
->getLineTableForUnit(
696 BC
.DwCtx
->getCompileUnitForOffset(CurrentUnitIndex
));
697 // Add filename from the inlined function to the current CU.
698 CurrentFilenum
= BC
.addDebugFilenameToUnit(
699 FunctionUnitIndex
, CurrentUnitIndex
,
700 CurrentLineTable
->Rows
[RowReference
.RowIndex
- 1].File
);
703 const DWARFDebugLine::Row
&CurrentRow
=
704 CurrentLineTable
->Rows
[RowReference
.RowIndex
- 1];
706 CurrentFilenum
= CurrentRow
.File
;
708 unsigned Flags
= (DWARF2_FLAG_IS_STMT
* CurrentRow
.IsStmt
) |
709 (DWARF2_FLAG_BASIC_BLOCK
* CurrentRow
.BasicBlock
) |
710 (DWARF2_FLAG_PROLOGUE_END
* CurrentRow
.PrologueEnd
) |
711 (DWARF2_FLAG_EPILOGUE_BEGIN
* CurrentRow
.EpilogueBegin
);
713 // Always emit is_stmt at the beginning of function fragment.
715 Flags
|= DWARF2_FLAG_IS_STMT
;
717 BC
.Ctx
->setCurrentDwarfLoc(CurrentFilenum
, CurrentRow
.Line
, CurrentRow
.Column
,
718 Flags
, CurrentRow
.Isa
, CurrentRow
.Discriminator
);
719 const MCDwarfLoc
&DwarfLoc
= BC
.Ctx
->getCurrentDwarfLoc();
720 BC
.Ctx
->clearDwarfLocSeen();
723 InstrLabel
= BC
.Ctx
->createTempSymbol();
725 BC
.getDwarfLineTable(FunctionUnitIndex
)
727 .addLineEntry(MCDwarfLineEntry(InstrLabel
, DwarfLoc
),
728 Streamer
.getCurrentSectionOnly());
733 void BinaryEmitter::emitLineInfoEnd(const BinaryFunction
&BF
,
734 MCSymbol
*FunctionEndLabel
) {
735 DWARFUnit
*FunctionCU
= BF
.getDWARFUnit();
736 assert(FunctionCU
&& "DWARF unit expected");
737 BC
.Ctx
->setCurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_END_SEQUENCE
, 0, 0);
738 const MCDwarfLoc
&DwarfLoc
= BC
.Ctx
->getCurrentDwarfLoc();
739 BC
.Ctx
->clearDwarfLocSeen();
740 BC
.getDwarfLineTable(FunctionCU
->getOffset())
742 .addLineEntry(MCDwarfLineEntry(FunctionEndLabel
, DwarfLoc
),
743 Streamer
.getCurrentSectionOnly());
746 void BinaryEmitter::emitJumpTables(const BinaryFunction
&BF
) {
747 MCSection
*ReadOnlySection
= BC
.MOFI
->getReadOnlySection();
748 MCSection
*ReadOnlyColdSection
= BC
.MOFI
->getContext().getELFSection(
749 ".rodata.cold", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
751 if (!BF
.hasJumpTables())
754 if (opts::PrintJumpTables
)
755 BC
.outs() << "BOLT-INFO: jump tables for function " << BF
<< ":\n";
757 for (auto &JTI
: BF
.jumpTables()) {
758 JumpTable
&JT
= *JTI
.second
;
759 // Only emit shared jump tables once, when processing the first parent
760 if (JT
.Parents
.size() > 1 && JT
.Parents
[0] != &BF
)
762 if (opts::PrintJumpTables
)
764 if (opts::JumpTables
== JTS_BASIC
) {
767 MCSection
*HotSection
, *ColdSection
;
769 HotSection
= ReadOnlySection
;
770 ColdSection
= ReadOnlyColdSection
;
772 HotSection
= BF
.hasProfile() ? ReadOnlySection
: ReadOnlyColdSection
;
773 ColdSection
= HotSection
;
775 emitJumpTable(JT
, HotSection
, ColdSection
);
780 void BinaryEmitter::emitJumpTable(const JumpTable
&JT
, MCSection
*HotSection
,
781 MCSection
*ColdSection
) {
782 // Pre-process entries for aggressive splitting.
783 // Each label represents a separate switch table and gets its own count
784 // determining its destination.
785 std::map
<MCSymbol
*, uint64_t> LabelCounts
;
786 if (opts::JumpTables
> JTS_SPLIT
&& !JT
.Counts
.empty()) {
787 auto It
= JT
.Labels
.find(0);
788 assert(It
!= JT
.Labels
.end());
789 MCSymbol
*CurrentLabel
= It
->second
;
790 uint64_t CurrentLabelCount
= 0;
791 for (unsigned Index
= 0; Index
< JT
.Entries
.size(); ++Index
) {
792 auto LI
= JT
.Labels
.find(Index
* JT
.EntrySize
);
793 if (LI
!= JT
.Labels
.end()) {
794 LabelCounts
[CurrentLabel
] = CurrentLabelCount
;
795 CurrentLabel
= LI
->second
;
796 CurrentLabelCount
= 0;
798 CurrentLabelCount
+= JT
.Counts
[Index
].Count
;
800 LabelCounts
[CurrentLabel
] = CurrentLabelCount
;
802 Streamer
.switchSection(JT
.Count
> 0 ? HotSection
: ColdSection
);
803 Streamer
.emitValueToAlignment(Align(JT
.EntrySize
));
805 MCSymbol
*LastLabel
= nullptr;
807 for (MCSymbol
*Entry
: JT
.Entries
) {
808 auto LI
= JT
.Labels
.find(Offset
);
809 if (LI
!= JT
.Labels
.end()) {
811 dbgs() << "BOLT-DEBUG: emitting jump table " << LI
->second
->getName()
812 << " (originally was at address 0x"
813 << Twine::utohexstr(JT
.getAddress() + Offset
)
814 << (Offset
? ") as part of larger jump table\n" : ")\n");
816 if (!LabelCounts
.empty()) {
817 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: jump table count: "
818 << LabelCounts
[LI
->second
] << '\n');
819 if (LabelCounts
[LI
->second
] > 0)
820 Streamer
.switchSection(HotSection
);
822 Streamer
.switchSection(ColdSection
);
823 Streamer
.emitValueToAlignment(Align(JT
.EntrySize
));
825 // Emit all labels registered at the address of this jump table
826 // to sync with our global symbol table. We may have two labels
827 // registered at this address if one label was created via
828 // getOrCreateGlobalSymbol() (e.g. LEA instructions referencing
829 // this location) and another via getOrCreateJumpTable(). This
830 // creates a race where the symbols created by these two
831 // functions may or may not be the same, but they are both
832 // registered in our symbol table at the same address. By
833 // emitting them all here we make sure there is no ambiguity
834 // that depends on the order that these symbols were created, so
835 // whenever this address is referenced in the binary, it is
836 // certain to point to the jump table identified at this
838 if (BinaryData
*BD
= BC
.getBinaryDataByName(LI
->second
->getName())) {
839 for (MCSymbol
*S
: BD
->getSymbols())
840 Streamer
.emitLabel(S
);
842 Streamer
.emitLabel(LI
->second
);
844 LastLabel
= LI
->second
;
846 if (JT
.Type
== JumpTable::JTT_NORMAL
) {
847 Streamer
.emitSymbolValue(Entry
, JT
.OutputEntrySize
);
849 const MCSymbolRefExpr
*JTExpr
=
850 MCSymbolRefExpr::create(LastLabel
, Streamer
.getContext());
851 const MCSymbolRefExpr
*E
=
852 MCSymbolRefExpr::create(Entry
, Streamer
.getContext());
853 const MCBinaryExpr
*Value
=
854 MCBinaryExpr::createSub(E
, JTExpr
, Streamer
.getContext());
855 Streamer
.emitValue(Value
, JT
.EntrySize
);
857 Offset
+= JT
.EntrySize
;
861 void BinaryEmitter::emitCFIInstruction(const MCCFIInstruction
&Inst
) const {
862 switch (Inst
.getOperation()) {
864 llvm_unreachable("Unexpected instruction");
865 case MCCFIInstruction::OpDefCfaOffset
:
866 Streamer
.emitCFIDefCfaOffset(Inst
.getOffset());
868 case MCCFIInstruction::OpAdjustCfaOffset
:
869 Streamer
.emitCFIAdjustCfaOffset(Inst
.getOffset());
871 case MCCFIInstruction::OpDefCfa
:
872 Streamer
.emitCFIDefCfa(Inst
.getRegister(), Inst
.getOffset());
874 case MCCFIInstruction::OpDefCfaRegister
:
875 Streamer
.emitCFIDefCfaRegister(Inst
.getRegister());
877 case MCCFIInstruction::OpOffset
:
878 Streamer
.emitCFIOffset(Inst
.getRegister(), Inst
.getOffset());
880 case MCCFIInstruction::OpRegister
:
881 Streamer
.emitCFIRegister(Inst
.getRegister(), Inst
.getRegister2());
883 case MCCFIInstruction::OpWindowSave
:
884 Streamer
.emitCFIWindowSave();
886 case MCCFIInstruction::OpNegateRAState
:
887 Streamer
.emitCFINegateRAState();
889 case MCCFIInstruction::OpSameValue
:
890 Streamer
.emitCFISameValue(Inst
.getRegister());
892 case MCCFIInstruction::OpGnuArgsSize
:
893 Streamer
.emitCFIGnuArgsSize(Inst
.getOffset());
895 case MCCFIInstruction::OpEscape
:
896 Streamer
.AddComment(Inst
.getComment());
897 Streamer
.emitCFIEscape(Inst
.getValues());
899 case MCCFIInstruction::OpRestore
:
900 Streamer
.emitCFIRestore(Inst
.getRegister());
902 case MCCFIInstruction::OpUndefined
:
903 Streamer
.emitCFIUndefined(Inst
.getRegister());
908 // The code is based on EHStreamer::emitExceptionTable().
909 void BinaryEmitter::emitLSDA(BinaryFunction
&BF
, const FunctionFragment
&FF
) {
910 const BinaryFunction::CallSitesRange Sites
=
911 BF
.getCallSites(FF
.getFragmentNum());
915 Streamer
.switchSection(BC
.MOFI
->getLSDASection());
917 const unsigned TTypeEncoding
= BF
.getLSDATypeEncoding();
918 const unsigned TTypeEncodingSize
= BC
.getDWARFEncodingSize(TTypeEncoding
);
919 const uint16_t TTypeAlignment
= 4;
921 // Type tables have to be aligned at 4 bytes.
922 Streamer
.emitValueToAlignment(Align(TTypeAlignment
));
924 // Emit the LSDA label.
925 MCSymbol
*LSDASymbol
= BF
.getLSDASymbol(FF
.getFragmentNum());
926 assert(LSDASymbol
&& "no LSDA symbol set");
927 Streamer
.emitLabel(LSDASymbol
);
929 // Corresponding FDE start.
930 const MCSymbol
*StartSymbol
= BF
.getSymbol(FF
.getFragmentNum());
932 // Emit the LSDA header.
934 // If LPStart is omitted, then the start of the FDE is used as a base for
935 // landing pad displacements. Then, if a cold fragment starts with
936 // a landing pad, this means that the first landing pad offset will be 0.
937 // However, C++ runtime will treat 0 as if there is no landing pad, thus we
938 // cannot emit LP offset as 0.
940 // As a solution, for fixed-address binaries we set LPStart to 0, and for
941 // position-independent binaries we offset LP start by one byte.
942 bool NeedsLPAdjustment
= false;
943 std::function
<void(const MCSymbol
*)> emitLandingPad
;
945 // Check if there's a symbol associated with a landing pad fragment.
946 const MCSymbol
*LPStartSymbol
= BF
.getLPStartSymbol(FF
.getFragmentNum());
947 if (!LPStartSymbol
) {
948 // Since landing pads are not in the same fragment, we fall back to emitting
949 // absolute addresses for this FDE.
950 if (opts::Verbosity
>= 2) {
951 BC
.outs() << "BOLT-INFO: falling back to generating absolute-address "
952 << "exception ranges for " << BF
<< '\n';
955 assert(BC
.HasFixedLoadAddress
&&
956 "Cannot emit absolute-address landing pads for PIE/DSO");
958 Streamer
.emitIntValue(dwarf::DW_EH_PE_udata4
, 1); // LPStart format
959 Streamer
.emitIntValue(0, 4); // LPStart
960 emitLandingPad
= [&](const MCSymbol
*LPSymbol
) {
962 Streamer
.emitSymbolValue(LPSymbol
, 4);
964 Streamer
.emitIntValue(0, 4);
967 std::optional
<FragmentNum
> LPFN
= BF
.getLPFragment(FF
.getFragmentNum());
968 const FunctionFragment
&LPFragment
= BF
.getLayout().getFragment(*LPFN
);
970 (!LPFragment
.empty() && LPFragment
.front()->isLandingPad());
972 // Emit LPStart encoding and optionally LPStart.
973 if (NeedsLPAdjustment
|| LPStartSymbol
!= StartSymbol
) {
974 Streamer
.emitIntValue(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
, 1);
975 MCSymbol
*DotSymbol
= BC
.Ctx
->createTempSymbol("LPBase");
976 Streamer
.emitLabel(DotSymbol
);
978 const MCExpr
*LPStartExpr
= MCBinaryExpr::createSub(
979 MCSymbolRefExpr::create(LPStartSymbol
, *BC
.Ctx
),
980 MCSymbolRefExpr::create(DotSymbol
, *BC
.Ctx
), *BC
.Ctx
);
981 if (NeedsLPAdjustment
)
982 LPStartExpr
= MCBinaryExpr::createSub(
983 LPStartExpr
, MCConstantExpr::create(1, *BC
.Ctx
), *BC
.Ctx
);
984 Streamer
.emitValue(LPStartExpr
, 4);
986 // DW_EH_PE_omit means FDE start (StartSymbol) will be used as LPStart.
987 Streamer
.emitIntValue(dwarf::DW_EH_PE_omit
, 1);
989 emitLandingPad
= [&](const MCSymbol
*LPSymbol
) {
991 const MCExpr
*LPOffsetExpr
= MCBinaryExpr::createSub(
992 MCSymbolRefExpr::create(LPSymbol
, *BC
.Ctx
),
993 MCSymbolRefExpr::create(LPStartSymbol
, *BC
.Ctx
), *BC
.Ctx
);
994 if (NeedsLPAdjustment
)
995 LPOffsetExpr
= MCBinaryExpr::createAdd(
996 LPOffsetExpr
, MCConstantExpr::create(1, *BC
.Ctx
), *BC
.Ctx
);
997 Streamer
.emitULEB128Value(LPOffsetExpr
);
999 Streamer
.emitULEB128IntValue(0);
1004 Streamer
.emitIntValue(TTypeEncoding
, 1); // TType format
1006 MCSymbol
*TTBaseLabel
= nullptr;
1007 if (TTypeEncoding
!= dwarf::DW_EH_PE_omit
) {
1008 TTBaseLabel
= BC
.Ctx
->createTempSymbol("TTBase");
1009 MCSymbol
*TTBaseRefLabel
= BC
.Ctx
->createTempSymbol("TTBaseRef");
1010 Streamer
.emitAbsoluteSymbolDiffAsULEB128(TTBaseLabel
, TTBaseRefLabel
);
1011 Streamer
.emitLabel(TTBaseRefLabel
);
1014 // Emit encoding of entries in the call site table. The format is used for the
1015 // call site start, length, and corresponding landing pad.
1017 Streamer
.emitIntValue(dwarf::DW_EH_PE_sdata4
, 1);
1019 Streamer
.emitIntValue(dwarf::DW_EH_PE_uleb128
, 1);
1021 MCSymbol
*CSTStartLabel
= BC
.Ctx
->createTempSymbol("CSTStart");
1022 MCSymbol
*CSTEndLabel
= BC
.Ctx
->createTempSymbol("CSTEnd");
1023 Streamer
.emitAbsoluteSymbolDiffAsULEB128(CSTEndLabel
, CSTStartLabel
);
1025 Streamer
.emitLabel(CSTStartLabel
);
1026 for (const auto &FragmentCallSite
: Sites
) {
1027 const BinaryFunction::CallSite
&CallSite
= FragmentCallSite
.second
;
1028 const MCSymbol
*BeginLabel
= CallSite
.Start
;
1029 const MCSymbol
*EndLabel
= CallSite
.End
;
1031 assert(BeginLabel
&& "start EH label expected");
1032 assert(EndLabel
&& "end EH label expected");
1034 // Start of the range is emitted relative to the start of current
1035 // function split part.
1036 if (!LPStartSymbol
) {
1037 Streamer
.emitAbsoluteSymbolDiff(BeginLabel
, StartSymbol
, 4);
1038 Streamer
.emitAbsoluteSymbolDiff(EndLabel
, BeginLabel
, 4);
1040 Streamer
.emitAbsoluteSymbolDiffAsULEB128(BeginLabel
, StartSymbol
);
1041 Streamer
.emitAbsoluteSymbolDiffAsULEB128(EndLabel
, BeginLabel
);
1043 emitLandingPad(CallSite
.LP
);
1044 Streamer
.emitULEB128IntValue(CallSite
.Action
);
1046 Streamer
.emitLabel(CSTEndLabel
);
1048 // Write out action, type, and type index tables at the end.
1050 // For action and type index tables there's no need to change the original
1051 // table format unless we are doing function splitting, in which case we can
1052 // split and optimize the tables.
1054 // For type table we (re-)encode the table using TTypeEncoding matching
1055 // the current assembler mode.
1056 for (uint8_t const &Byte
: BF
.getLSDAActionTable())
1057 Streamer
.emitIntValue(Byte
, 1);
1059 const BinaryFunction::LSDATypeTableTy
&TypeTable
=
1060 (TTypeEncoding
& dwarf::DW_EH_PE_indirect
) ? BF
.getLSDATypeAddressTable()
1061 : BF
.getLSDATypeTable();
1062 assert(TypeTable
.size() == BF
.getLSDATypeTable().size() &&
1063 "indirect type table size mismatch");
1065 Streamer
.emitValueToAlignment(Align(TTypeAlignment
));
1067 for (int Index
= TypeTable
.size() - 1; Index
>= 0; --Index
) {
1068 const uint64_t TypeAddress
= TypeTable
[Index
];
1069 switch (TTypeEncoding
& 0x70) {
1071 llvm_unreachable("unsupported TTypeEncoding");
1072 case dwarf::DW_EH_PE_absptr
:
1073 Streamer
.emitIntValue(TypeAddress
, TTypeEncodingSize
);
1075 case dwarf::DW_EH_PE_pcrel
: {
1077 const MCSymbol
*TypeSymbol
=
1078 BC
.getOrCreateGlobalSymbol(TypeAddress
, "TI", 0, TTypeAlignment
);
1079 MCSymbol
*DotSymbol
= BC
.Ctx
->createNamedTempSymbol();
1080 Streamer
.emitLabel(DotSymbol
);
1081 const MCBinaryExpr
*SubDotExpr
= MCBinaryExpr::createSub(
1082 MCSymbolRefExpr::create(TypeSymbol
, *BC
.Ctx
),
1083 MCSymbolRefExpr::create(DotSymbol
, *BC
.Ctx
), *BC
.Ctx
);
1084 Streamer
.emitValue(SubDotExpr
, TTypeEncodingSize
);
1086 Streamer
.emitIntValue(0, TTypeEncodingSize
);
1093 if (TTypeEncoding
!= dwarf::DW_EH_PE_omit
)
1094 Streamer
.emitLabel(TTBaseLabel
);
1096 for (uint8_t const &Byte
: BF
.getLSDATypeIndexTable())
1097 Streamer
.emitIntValue(Byte
, 1);
1100 void BinaryEmitter::emitDebugLineInfoForOriginalFunctions() {
1101 // If a function is in a CU containing at least one processed function, we
1102 // have to rewrite the whole line table for that CU. For unprocessed functions
1103 // we use data from the input line table.
1104 for (auto &It
: BC
.getBinaryFunctions()) {
1105 const BinaryFunction
&Function
= It
.second
;
1107 // If the function was emitted, its line info was emitted with it.
1108 if (Function
.isEmitted())
1111 const DWARFDebugLine::LineTable
*LineTable
= Function
.getDWARFLineTable();
1113 continue; // nothing to update for this function
1115 const uint64_t Address
= Function
.getAddress();
1116 std::vector
<uint32_t> Results
;
1117 if (!LineTable
->lookupAddressRange(
1118 {Address
, object::SectionedAddress::UndefSection
},
1119 Function
.getSize(), Results
))
1122 if (Results
.empty())
1125 // The first row returned could be the last row matching the start address.
1126 // Find the first row with the same address that is not the end of the
1128 uint64_t FirstRow
= Results
.front();
1129 while (FirstRow
> 0) {
1130 const DWARFDebugLine::Row
&PrevRow
= LineTable
->Rows
[FirstRow
- 1];
1131 if (PrevRow
.Address
.Address
!= Address
|| PrevRow
.EndSequence
)
1136 const uint64_t EndOfSequenceAddress
=
1137 Function
.getAddress() + Function
.getMaxSize();
1138 BC
.getDwarfLineTable(Function
.getDWARFUnit()->getOffset())
1139 .addLineTableSequence(LineTable
, FirstRow
, Results
.back(),
1140 EndOfSequenceAddress
);
1143 // For units that are completely unprocessed, use original debug line contents
1144 // eliminating the need to regenerate line info program.
1145 emitDebugLineInfoForUnprocessedCUs();
1148 void BinaryEmitter::emitDebugLineInfoForUnprocessedCUs() {
1149 // Sorted list of section offsets provides boundaries for section fragments,
1150 // where each fragment is the unit's contribution to debug line section.
1151 std::vector
<uint64_t> StmtListOffsets
;
1152 StmtListOffsets
.reserve(BC
.DwCtx
->getNumCompileUnits());
1153 for (const std::unique_ptr
<DWARFUnit
> &CU
: BC
.DwCtx
->compile_units()) {
1154 DWARFDie CUDie
= CU
->getUnitDIE();
1155 auto StmtList
= dwarf::toSectionOffset(CUDie
.find(dwarf::DW_AT_stmt_list
));
1159 StmtListOffsets
.push_back(*StmtList
);
1161 llvm::sort(StmtListOffsets
);
1163 // For each CU that was not processed, emit its line info as a binary blob.
1164 for (const std::unique_ptr
<DWARFUnit
> &CU
: BC
.DwCtx
->compile_units()) {
1165 if (BC
.ProcessedCUs
.count(CU
.get()))
1168 DWARFDie CUDie
= CU
->getUnitDIE();
1169 auto StmtList
= dwarf::toSectionOffset(CUDie
.find(dwarf::DW_AT_stmt_list
));
1173 StringRef DebugLineContents
= CU
->getLineSection().Data
;
1175 const uint64_t Begin
= *StmtList
;
1177 // Statement list ends where the next unit contribution begins, or at the
1178 // end of the section.
1179 auto It
= llvm::upper_bound(StmtListOffsets
, Begin
);
1180 const uint64_t End
=
1181 It
== StmtListOffsets
.end() ? DebugLineContents
.size() : *It
;
1183 BC
.getDwarfLineTable(CU
->getOffset())
1184 .addRawContents(DebugLineContents
.slice(Begin
, End
));
1188 void BinaryEmitter::emitDataSections(StringRef OrgSecPrefix
) {
1189 for (BinarySection
&Section
: BC
.sections()) {
1190 if (!Section
.hasRelocations())
1193 StringRef Prefix
= Section
.hasSectionRef() ? OrgSecPrefix
: "";
1194 Section
.emitAsData(Streamer
, Prefix
+ Section
.getName());
1195 Section
.clearRelocations();
1202 void emitBinaryContext(MCStreamer
&Streamer
, BinaryContext
&BC
,
1203 StringRef OrgSecPrefix
) {
1204 BinaryEmitter(Streamer
, BC
).emitAll(OrgSecPrefix
);
1207 void emitFunctionBody(MCStreamer
&Streamer
, BinaryFunction
&BF
,
1208 FunctionFragment
&FF
, bool EmitCodeOnly
) {
1209 BinaryEmitter(Streamer
, BF
.getBinaryContext())
1210 .emitFunctionBody(BF
, FF
, EmitCodeOnly
);