LLVM: lib/MC/MCAssembler.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

38#include

39#include

40#include

41#include

42

43using namespace llvm;

44

45namespace llvm {

47}

48

49#define DEBUG_TYPE "assembler"

50

51namespace {

53

54STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total");

55STATISTIC(EmittedRelaxableFragments,

56 "Number of emitted assembler fragments - relaxable");

58 "Number of emitted assembler fragments - data");

60 "Number of emitted assembler fragments - align");

62 "Number of emitted assembler fragments - fill");

63STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops");

64STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org");

65STATISTIC(evaluateFixup, "Number of evaluated fixups");

66STATISTIC(ObjectBytes, "Number of emitted object file bytes");

67STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");

68STATISTIC(RelaxedInstructions, "Number of relaxed instructions");

69

70}

71}

72

73

74

75

76

77

78

79

81 std::unique_ptr Backend,

82 std::unique_ptr Emitter,

83 std::unique_ptr Writer)

84 : Context(Context), Backend(std::move(Backend)),

86

88 RelaxAll = false;

90 Symbols.clear();

91 ThumbFuncs.clear();

92 BundleAlignSize = 0;

93

94

99 if (Writer)

100 Writer->reset();

101}

102

104 if (Section.isRegistered())

105 return false;

106 assert(Section.curFragList()->Head && "allocInitialFragment not called");

108 Section.setIsRegistered(true);

109 return true;

110}

111

113 if (ThumbFuncs.count(Symbol))

114 return true;

115

116 if (!Symbol->isVariable())

117 return false;

118

119 const MCExpr *Expr = Symbol->getVariableValue();

120

123 return false;

124

126 return false;

127

129 if (Ref)

130 return false;

131

133 return false;

134

137 return false;

138

139 ThumbFuncs.insert(Symbol);

140 return true;

141}

142

146 ++stats::evaluateFixup;

147

148

149

150

151

152

153

157 WasForced = false;

159 Ctx.reportError(Fixup.getLoc(), "expected relocatable expression");

160 return true;

161 }

165 "unsupported subtraction of qualified symbol");

166 return true;

167 }

168 }

169

173 Value, WasForced);

174

176 bool IsResolved = false;

177 if (IsPCRel) {

178 if (Target.getSymB()) {

179 IsResolved = false;

180 } else if (Target.getSymA()) {

181 IsResolved = false;

182 } else {

184 const MCSymbol &SA = A->getSymbol();

186 IsResolved = false;

187 } else {

190 *this, SA, *DF, false, true);

191 }

192 }

193 } else {

194 IsResolved = Target.isAbsolute();

195 }

196

198

201 if (Sym.isDefined())

203 }

206 if (Sym.isDefined())

208 }

209

211 assert((ShouldAlignPC ? IsPCRel : true) &&

212 "FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!");

213

214 if (IsPCRel) {

216

217

218

219 if (ShouldAlignPC) Offset &= ~0x3;

221 }

222

223

224 if (IsResolved &&

226 IsResolved = false;

227 WasForced = true;

228 }

229

230

231

232 if (!IsResolved && Target.getSymA() && Target.getSymB() &&

235 return true;

236

237 return IsResolved;

238}

239

242 switch (F.getKind()) {

244 return cast(F).getContents().size();

246 return cast(F).getContents().size();

248 auto &FF = cast(F);

249 int64_t NumValues = 0;

250 if (!FF.getNumValues().evaluateKnownAbsolute(NumValues, *this)) {

252 "expected assembly-time absolute expression");

253 return 0;

254 }

255 int64_t Size = NumValues * FF.getValueSize();

256 if (Size < 0) {

258 return 0;

259 }

261 }

262

264 return cast(F).getNumBytes();

265

267 return cast(F).getContents().size();

268

270 return cast(F).getSize();

271

273 return 4;

274

279

280

281

283 getBackend().shouldInsertExtraNopBytesForCodeAlign(AF, Size))

285

286

287

291 }

293 return 0;

295 }

296

302 "expected assembly-time absolute expression");

303 return 0;

304 }

305

307 int64_t TargetLocation = Value.getConstant();

312 return 0;

313 }

314 TargetLocation += Val;

315 }

316 int64_t Size = TargetLocation - FragmentOffset;

317 if (Size < 0 || Size >= 0x40000000) {

319 OF.getLoc(), "invalid .org offset '" + Twine(TargetLocation) +

320 "' (at offset '" + Twine(FragmentOffset) + "')");

321 return 0;

322 }

324 }

325

327 return cast(F).getContents().size();

329 return cast(F).getContents().size();

331 return cast(F).getContents().size();

333 return cast(F).getContents().size();

335 return cast(F).getContents().size();

338 }

339

341}

342

343

344

345

349 uint64_t OffsetInBundle = FOffset & (BundleSize - 1);

350 uint64_t EndOfFragment = OffsetInBundle + FSize;

351

352

353

354

355

356

357

358

359 if (F->alignToBundleEnd()) {

360

361

362

363

364

365

366

367

368

369

370 if (EndOfFragment == BundleSize)

371 return 0;

372 else if (EndOfFragment < BundleSize)

373 return BundleSize - EndOfFragment;

374 else {

375 return 2 * BundleSize - EndOfFragment;

376 }

377 } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)

378 return BundleSize - OffsetInBundle;

379 else

380 return 0;

381}

382

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405 assert(isa(F) &&

406 "Only MCEncodedFragment implementations have instructions");

409

412

413 uint64_t RequiredBundlePadding =

415 if (RequiredBundlePadding > UINT8_MAX)

418 EF->Offset += RequiredBundlePadding;

419 if (auto *DF = dyn_cast_or_null(Prev))

420 if (DF->getContents().empty())

421 DF->Offset = EF->Offset;

422}

423

426 return;

435 }

437 Prev = &F;

438 }

439}

440

443 return F.Offset;

444}

445

446

448 bool ReportError, uint64_t &Val) {

450 if (ReportError)

451 report_fatal_error("unable to evaluate offset to undefined symbol '" +

453 return false;

454 }

456 return true;

457}

458

460 bool ReportError, uint64_t &Val) {

463

464

469

471

473 if (A) {

475

476

477

478

480 return false;

482 }

483

485 if (B) {

488 return false;

490 }

491

493 return true;

494}

495

498}

499

503 return Val;

504}

505

508 if (!Symbol.isVariable())

509 return &Symbol;

510

511 const MCExpr *Expr = Symbol.getVariableValue();

515 "expression could not be evaluated");

516 return nullptr;

517 }

518

520 if (RefB) {

524 "' could not be evaluated in a subtraction expression");

525 return nullptr;

526 }

527

529 if (A)

530 return nullptr;

531

532 const MCSymbol &ASym = A->getSymbol();

535 "Common symbol '" + ASym.getName() +

536 "' cannot be used in assignment expr");

537 return nullptr;

538 }

539

540 return &ASym;

541}

542

545

548}

549

551

553 return 0;

555}

556

558 bool Changed = !Symbol.isRegistered();

559 if (Changed) {

560 Symbol.setIsRegistered(true);

561 Symbols.push_back(&Symbol);

562 }

563 return Changed;

564}

565

570

572 if (BundlePadding > 0) {

574 "Writing bundle padding with disabled bundling");

576 "Writing bundle padding for a fragment without instructions");

577

578 unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize);

581

582

583

584

585

586

587

588

590 if (getBackend().writeNopData(OS, DistanceToBoundary, STI))

592 Twine(DistanceToBoundary) + " bytes");

593 BundlePadding -= DistanceToBoundary;

594 }

595 if (getBackend().writeNopData(OS, BundlePadding, STI))

597 Twine(BundlePadding) + " bytes");

598 }

599}

600

601

604

605 uint64_t FragmentSize = Asm.computeFragmentSize(F);

606

608

610 Asm.writeFragmentPadding(OS, *EF, FragmentSize);

611

612

613

615 (void) Start;

616

617 ++stats::EmittedFragments;

618

619 switch (F.getKind()) {

621 ++stats::EmittedAlignFragments;

623 assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!");

624

626

627

628

629

630 if (Count * AF.getValueSize() != FragmentSize)

633 "' is not a divisor of padding size '" +

634 Twine(FragmentSize) + "'");

635

636

637

638

639

641 if (!Asm.getBackend().writeNopData(OS, Count, AF.getSubtargetInfo()))

643 Twine(Count) + " bytes");

644 break;

645 }

646

647

648 for (uint64_t i = 0; i != Count; ++i) {

652 case 2:

654 break;

655 case 4:

657 break;

658 case 8:

660 break;

661 }

662 }

663 break;

664 }

665

667 ++stats::EmittedDataFragments;

668 OS << cast(F).getContents();

669 break;

670

672 ++stats::EmittedRelaxableFragments;

673 OS << cast(F).getContents();

674 break;

675

677 ++stats::EmittedFillFragments;

681 const unsigned MaxChunkSize = 16;

682 char Data[MaxChunkSize];

683 assert(0 < VSize && VSize <= MaxChunkSize && "Illegal fragment fill size");

684

685

686 for (unsigned I = 0; I != VSize; ++I) {

689 }

690 for (unsigned I = VSize; I < MaxChunkSize; ++I)

692

693

694 const unsigned NumPerChunk = MaxChunkSize / VSize;

695

696 const unsigned ChunkSize = VSize * NumPerChunk;

697

698

700 for (uint64_t I = 0, E = FragmentSize / ChunkSize; I != E; ++I)

702

703

704 unsigned TrailingCount = FragmentSize % ChunkSize;

705 if (TrailingCount)

707 break;

708 }

709

711 ++stats::EmittedNopsFragments;

713

716 int64_t MaximumNopLength =

718

719 assert(NumBytes > 0 && "Expected positive NOPs fragment size");

720 assert(ControlledNopLength >= 0 && "Expected non-negative NOP size");

721

722 if (ControlledNopLength > MaximumNopLength) {

723 Asm.getContext().reportError(NF.getLoc(),

724 "illegal NOP size " +

725 std::to_string(ControlledNopLength) +

726 ". (expected within [0, " +

727 std::to_string(MaximumNopLength) + "])");

728

729

730 ControlledNopLength = MaximumNopLength;

731 }

732

733

734 if (!ControlledNopLength)

735 ControlledNopLength = MaximumNopLength;

736

737 while (NumBytes) {

739 (uint64_t)std::min(NumBytes, ControlledNopLength);

740 assert(NumBytesToEmit && "try to emit empty NOP instruction");

741 if (!Asm.getBackend().writeNopData(OS, NumBytesToEmit,

743 report_fatal_error("unable to write nop sequence of the remaining " +

744 Twine(NumBytesToEmit) + " bytes");

745 break;

746 }

747 NumBytes -= NumBytesToEmit;

748 }

749 break;

750 }

751

755 break;

756 }

757

760 if (!Asm.getBackend().writeNopData(OS, FragmentSize, BF.getSubtargetInfo()))

762 Twine(FragmentSize) + " bytes");

763 break;

764 }

765

769 break;

770 }

771

773 ++stats::EmittedOrgFragments;

775

776 for (uint64_t i = 0, e = FragmentSize; i != e; ++i)

778

779 break;

780 }

781

785 break;

786 }

790 break;

791 }

793 const auto &OF = cast(F);

794 OS << OF.getContents();

795 break;

796 }

798 const auto &DRF = cast(F);

799 OS << DRF.getContents();

800 break;

801 }

805 break;

806 }

809 }

810

812 "The stream should advance by fragment size");

813}

814

818

819

822

823

825 switch (F.getKind()) {

826 default: llvm_unreachable("Invalid fragment in virtual section!");

828

829

830

832 if (DF.getFixups().size())

834 " section '" + Sec->getName() +

835 "' cannot have fixups");

836 for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i)

837 if (DF.getContents()[i]) {

839 Sec->getVirtualSectionKind() +

840 " section '" + Sec->getName() +

841 "' cannot have non-zero initializers");

842 break;

843 }

844 break;

845 }

847

848

849 assert((cast(F).getValueSize() == 0 ||

850 cast(F).getValue() == 0) &&

851 "Invalid align in virtual section!");

852 break;

854 assert((cast(F).getValue() == 0) &&

855 "Invalid fill in virtual section!");

856 break;

858 break;

859 }

860 }

861

862 return;

863 }

864

866 (void)Start;

867

870

873}

874

875std::tuple<MCValue, uint64_t, bool>

878

881 bool WasForced;

882 bool IsResolved =

883 evaluateFixup(Fixup, &F, Target, STI, FixedValue, WasForced);

884 if (!IsResolved) {

885

886

887

889 }

890 return std::make_tuple(Target, FixedValue, IsResolved);

891}

892

896 errs() << "assembler backend - pre-layout\n--\n";

898

899

900 unsigned SectionIndex = 0;

903

904

905 if (Sec.Subsections.size() > 1) {

908 for (auto &[_, List] : Sec.Subsections) {

912 }

913 Sec.Subsections.clear();

914 Sec.Subsections.push_back({0u, {Dummy.getNext(), Tail}});

915 Sec.CurFragList = &Sec.Subsections[0].second;

916

917 unsigned FragmentIndex = 0;

919 Frag.setLayoutOrder(FragmentIndex++);

920 }

921 }

922

923

924 this->HasLayout = true;

925 while (layoutOnce()) {

927 return;

928

929

930

933 }

934

936 errs() << "assembler backend - post-relaxation\n--\n";

938

939

941

943 errs() << "assembler backend - final-layout\n--\n";

945

946

947

949

950

956

957

958 switch (Frag.getKind()) {

959 default:

960 continue;

963

964

965 if (Sec.useCodeAlign() && AF.hasEmitNops())

967 continue;

968 }

971 Fixups = DF.getFixups();

972 Contents = DF.getContents();

973 STI = DF.getSubtargetInfo();

974 assert(DF.hasInstructions() || STI != nullptr);

975 break;

976 }

983 break;

984 }

989 break;

990 }

993 Fixups = DF.getFixups();

994 Contents = DF.getContents();

995 break;

996 }

999 Fixups = DF.getFixups();

1000 Contents = DF.getContents();

1001 break;

1002 }

1004 auto &LF = cast(Frag);

1005 Fixups = LF.getFixups();

1006 Contents = LF.getContents();

1007 break;

1008 }

1013 break;

1014 }

1015 }

1018 bool IsResolved;

1020 std::tie(Target, FixedValue, IsResolved) =

1021 handleFixup(Frag, Fixup, STI);

1023 IsResolved, STI);

1024 }

1025 }

1026 }

1027}

1028

1031

1032

1034

1035 HasLayout = false;

1036}

1037

1038bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup,

1043 bool WasForced;

1044 bool Resolved = evaluateFixup(Fixup, DF, Target, DF->getSubtargetInfo(),

1045 Value, WasForced);

1046 if (Target.getSymA() &&

1049 return false;

1052}

1053

1054bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F) const {

1056

1057

1058

1059 if (getBackend().mayNeedRelaxation(F->getInst(), *F->getSubtargetInfo()))

1060 return false;

1061

1063 if (fixupNeedsRelaxation(Fixup, F))

1064 return true;

1065

1066 return false;

1067}

1068

1071 "Expected CodeEmitter defined for relaxInstruction");

1072 if (!fragmentNeedsRelaxation(&F))

1073 return false;

1074

1075 ++stats::RelaxedInstructions;

1076

1077

1078

1079

1080

1081

1084

1085

1086 F.setInst(Relaxed);

1087 F.getFixups().clear();

1088 F.getContents().clear();

1090 *F.getSubtargetInfo());

1091 return true;

1092}

1093

1095 const unsigned OldSize = static_cast<unsigned>(LF.getContents().size());

1096 unsigned PadTo = OldSize;

1100

1101

1102

1105 : LF.getValue().evaluateAsAbsolute(Value, *this);

1106 if (!Abs) {

1107 bool Relaxed, UseZeroPad;

1109 if (!Relaxed) {

1112 "leb128 expression is not absolute");

1114 }

1115 uint8_t Tmp[10];

1117 if (UseZeroPad)

1119 }

1120 Data.clear();

1122

1123

1124

1125

1128 else

1131}

1132

1133

1134

1135

1136

1137

1138

1140 Align BoundaryAlignment) {

1142 return (StartAddr >> Log2(BoundaryAlignment)) !=

1143 ((EndAddr - 1) >> Log2(BoundaryAlignment));

1144}

1145

1146

1147

1148

1149

1150

1151

1153 Align BoundaryAlignment) {

1155 return (EndAddr & (BoundaryAlignment.value() - 1)) == 0;

1156}

1157

1158

1159

1160

1161

1162

1163

1165 Align BoundaryAlignment) {

1168}

1169

1171

1172

1174 return false;

1175

1181 break;

1182 }

1183

1185 uint64_t NewSize = needPadding(AlignedOffset, AlignedSize, BoundaryAlignment)

1187 : 0U;

1188 if (NewSize == BF.getSize())

1189 return false;

1191 return true;

1192}

1193

1195 bool WasRelaxed;

1196 if (getBackend().relaxDwarfLineAddr(*this, DF, WasRelaxed))

1197 return WasRelaxed;

1198

1200 uint64_t OldSize = DF.getContents().size();

1201 int64_t AddrDelta;

1202 bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);

1203 assert(Abs && "We created a line delta with an invalid expression");

1204 (void)Abs;

1205 int64_t LineDelta;

1206 LineDelta = DF.getLineDelta();

1208 Data.clear();

1209 DF.getFixups().clear();

1210

1212 AddrDelta, Data);

1213 return OldSize != Data.size();

1214}

1215

1217 bool WasRelaxed;

1218 if (getBackend().relaxDwarfCFA(*this, DF, WasRelaxed))

1219 return WasRelaxed;

1220

1223 bool Abs = DF.getAddrDelta().evaluateAsAbsolute(Value, *this);

1224 if (!Abs) {

1226 "invalid CFI advance_loc expression");

1228 return false;

1229 }

1230

1233 Data.clear();

1234 DF.getFixups().clear();

1235

1237 return OldSize != Data.size();

1238}

1239

1241 unsigned OldSize = F.getContents().size();

1243 return OldSize != F.getContents().size();

1244}

1245

1247 unsigned OldSize = F.getContents().size();

1249 return OldSize != F.getContents().size();

1250}

1251

1254 int64_t AddrDelta;

1256 assert(Abs && "We created a pseudo probe with an invalid expression");

1257 (void)Abs;

1259 Data.clear();

1262

1263

1265 return OldSize != Data.size();

1266}

1267

1268bool MCAssembler::relaxFragment(MCFragment &F) {

1269 switch(F.getKind()) {

1270 default:

1271 return false;

1274 "Did not expect a MCRelaxableFragment in RelaxAll mode");

1275 return relaxInstruction(cast(F));

1277 return relaxDwarfLineAddr(cast(F));

1279 return relaxDwarfCallFrameFragment(cast(F));

1281 return relaxLEB(cast(F));

1283 return relaxBoundaryAlign(cast(F));

1285 return relaxCVInlineLineTable(cast(F));

1287 return relaxCVDefRange(cast(F));

1289 return relaxPseudoProbeAddr(cast(F));

1290 }

1291}

1292

1293bool MCAssembler::layoutOnce() {

1294 ++stats::RelaxationSteps;

1295

1296 bool Changed = false;

1299 if (relaxFragment(Frag))

1300 Changed = true;

1301 return Changed;

1302}

1303

1304#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

1307

1308 OS << "<MCAssembler\n";

1309 OS << " Sections:[\n ";

1310 bool First = true;

1311 for (const MCSection &Sec : *this) {

1314 else

1315 OS << ",\n ";

1317 }

1318 OS << "],\n";

1319 OS << " Symbols:[";

1320

1325 else

1326 OS << ",\n ";

1327 OS << "(";

1328 Sym.dump();

1329 OS << ", Index:" << Sym.getIndex() << ", ";

1330 OS << ")";

1331 }

1332 OS << "]>\n";

1333}

1334#endif

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

dxil DXContainer Global Emitter

#define DEBUG_WITH_TYPE(TYPE,...)

DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.

static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")

static uint64_t computeBundlePadding(unsigned BundleSize, const MCEncodedFragment *F, uint64_t FOffset, uint64_t FSize)

static bool getSymbolOffsetImpl(const MCAssembler &Asm, const MCSymbol &S, bool ReportError, uint64_t &Val)

static bool needPadding(uint64_t StartAddr, uint64_t Size, Align BoundaryAlignment)

Check if the branch needs padding.

static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, const MCFragment &F)

Write the fragment F to the output file.

static bool mayCrossBoundary(uint64_t StartAddr, uint64_t Size, Align BoundaryAlignment)

Check if the branch crosses the boundary.

static bool isAgainstBoundary(uint64_t StartAddr, uint64_t Size, Align BoundaryAlignment)

Check if the branch is against the boundary.

static bool getLabelOffset(const MCAssembler &Asm, const MCSymbol &S, bool ReportError, uint64_t &Val)

PowerPC TLS Dynamic Call Fixup

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallString class.

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

void encodeInlineLineTable(const MCAssembler &Asm, MCCVInlineLineTableFragment &F)

Encodes the binary annotations once we have a layout.

void encodeDefRange(const MCAssembler &Asm, MCCVDefRangeFragment &F)

Align getAlignment() const

unsigned getMaxBytesToEmit() const

unsigned getValueSize() const

const MCSubtargetInfo * getSubtargetInfo() const

virtual void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const

Relax the instruction in the given fragment to the next wider instruction.

virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, MCAlignFragment &AF)

Hook which indicates if the target requires a fixup to be generated when handling an align directive ...

virtual bool fixupNeedsRelaxationAdvanced(const MCAssembler &Asm, const MCFixup &Fixup, bool Resolved, uint64_t Value, const MCRelaxableFragment *DF, const bool WasForced) const

Target specific predicate for whether a given fixup requires the associated instruction to be relaxed...

virtual void finishLayout(MCAssembler const &Asm) const

Give backend an opportunity to finish layout after relaxation.

virtual bool evaluateTargetFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCFragment *DF, const MCValue &Target, const MCSubtargetInfo *STI, uint64_t &Value, bool &WasForced)

virtual void reset()

lifetime management

virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const

Get information on a fixup kind.

virtual std::pair< bool, bool > relaxLEB128(const MCAssembler &Asm, MCLEBFragment &LF, int64_t &Value) const

virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const =0

Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...

MCContext & getContext() const

bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const

void ensureValid(MCSection &Sec) const

uint64_t getSectionAddressSize(const MCSection &Sec) const

void Finish()

Finish - Do final processing and write the object to the output stream.

unsigned getBundleAlignSize() const

bool isBundlingEnabled() const

void writeSectionData(raw_ostream &OS, const MCSection *Section) const

Emit the section contents to OS.

MCObjectWriter & getWriter() const

MCCodeEmitter * getEmitterPtr() const

uint64_t getFragmentOffset(const MCFragment &F) const

void layoutBundle(MCFragment *Prev, MCFragment *F) const

MCCodeEmitter & getEmitter() const

MCAssembler(MCContext &Context, std::unique_ptr< MCAsmBackend > Backend, std::unique_ptr< MCCodeEmitter > Emitter, std::unique_ptr< MCObjectWriter > Writer)

Construct a new assembler instance.

bool isThumbFunc(const MCSymbol *Func) const

Check whether a given symbol has been flagged with .thumb_func.

MCAsmBackend & getBackend() const

bool registerSection(MCSection &Section)

uint64_t computeFragmentSize(const MCFragment &F) const

Compute the effective fragment size.

const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const

MCAsmBackend * getBackendPtr() const

iterator_range< pointee_iterator< typename SmallVector< const MCSymbol *, 0 >::const_iterator > > symbols() const

uint64_t getSectionFileSize(const MCSection &Sec) const

void reset()

Reuse an assembler instance.

bool registerSymbol(const MCSymbol &Symbol)

MCDwarfLineTableParams getDWARFLinetableParams() const

void writeFragmentPadding(raw_ostream &OS, const MCEncodedFragment &F, uint64_t FSize) const

Write the necessary bundle padding to OS.

Represents required padding such that a particular other set of fragments does not cross a particular...

void setSize(uint64_t Value)

const MCFragment * getLastFragment() const

const MCSubtargetInfo * getSubtargetInfo() const

Align getAlignment() const

Fragment representing the .cv_def_range directive.

Fragment representing the binary annotations produced by the .cv_inline_linetable directive.

virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0

Encode the given Inst to bytes and append to CB.

virtual void reset()

Lifetime management.

static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

CodeViewContext & getCVContext()

void reportError(SMLoc L, const Twine &Msg)

Fragment for data and encoded instructions.

static void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)

static void encode(MCContext &Context, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta, SmallVectorImpl< char > &OS)

Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.

SmallVectorImpl< MCFixup > & getFixups()

SmallVectorImpl< char > & getContents()

Interface implemented by fragments that contain encoded instructions and/or data.

const MCSubtargetInfo * getSubtargetInfo() const

Retrieve the MCSubTargetInfo in effect when the instruction was encoded.

void setBundlePadding(uint8_t N)

Set the padding size for this fragment.

uint8_t getBundlePadding() const

Get the padding size that must be inserted before this fragment.

bool alignToBundleEnd() const

Should this fragment be placed at the end of an aligned bundle?

Base class for the full range of assembler expressions which are needed for parsing.

bool evaluateAsValue(MCValue &Res, const MCAssembler &Asm) const

Try to evaluate the expression to the form (a - b + constant) where neither a nor b are variables.

bool evaluateKnownAbsolute(int64_t &Res, const MCAssembler &Asm) const

Aggressive variant of evaluateAsRelocatable when relocations are unavailable (e.g.

bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const

Try to evaluate the expression to a relocatable value, i.e.

uint8_t getValueSize() const

uint64_t getValue() const

Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...

MCSection * getParent() const

MCFragment * getNext() const

bool hasInstructions() const

Does this fragment have instructions emitted into it? By default this is false, but specific fragment...

Instances of this class represent a single low-level machine instruction.

const MCExpr & getValue() const

void setValue(const MCExpr *Expr)

int64_t getControlledNopLength() const

int64_t getNumBytes() const

const MCSubtargetInfo * getSubtargetInfo() const

virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const

virtual void executePostLayoutBinding(MCAssembler &Asm)

Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...

bool getSubsectionsViaSymbols() const

virtual uint64_t writeObject(MCAssembler &Asm)=0

Write the object file and returns the number of bytes written.

virtual void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0

Record a relocation entry.

const MCExpr & getOffset() const

const MCExpr & getAddrDelta() const

A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...

Instances of this class represent a uniqued identifier for a section in the current translation unit.

void setOrdinal(unsigned Value)

bool isVirtualSection() const

Check whether this section is "virtual", that is has no actual object file contents.

virtual bool useCodeAlign() const =0

Return true if a .align directive should use "optimized nops" to fill instead of 0s.

FragList * curFragList() const

void setHasLayout(bool Value)

Generic base class for all target subtargets.

Represents a symbol table index fragment.

const MCSymbol * getSymbol()

Represent a reference to a symbol from inside an expression.

const MCSymbol & getSymbol() const

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

const MCExpr * getVariableValue(bool SetUsed=true) const

getVariableValue - Get the value for variable symbols.

bool isCommon() const

Is this a 'common' symbol.

StringRef getName() const

getName - Get the symbol name.

bool isVariable() const

isVariable - Check if this is a variable symbol.

bool isUndefined(bool SetUsed=true) const

isUndefined - Check if this symbol undefined (i.e., implicitly defined).

uint32_t getIndex() const

Get the (implementation defined) index.

uint64_t getOffset() const

MCFragment * getFragment(bool SetUsed=true) const

This represents an "assembler immediate".

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

Represents a location in source code.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

StringRef - Represent a constant reference to a string, i.e.

Target - Wrapper for Target specific information.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

This class implements an extremely fast bulk output stream that can only output to a stream.

uint64_t tell() const

tell - Return the current offset with the file.

raw_ostream & write(unsigned char C)

A raw_ostream that writes to an SmallVector or SmallString.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ Tail

Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...

This is an optimization pass for GlobalISel generic memory operations.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

@ FK_Data_1

A one-byte fixup.

uint64_t offsetToAlignment(uint64_t Value, Align Alignment)

Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

@ Ref

The access may reference the value stored in memory.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a SLEB128 value to an output stream.

unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a ULEB128 value to an output stream.

unsigned Log2(Align A)

Returns the log2 of the alignment.

Implement std::hash so that hash_code can be used in STL containers.

This struct is a compact representation of a valid (non-zero power of two) alignment.

uint64_t value() const

This is a hole in the type system and should not be abused.

@ FKF_IsTarget

Should this fixup be evaluated in a target dependent manner?

@ FKF_IsAlignedDownTo32Bits

Should this fixup kind force a 4-byte aligned effective PC value?

@ FKF_Constant

This fixup kind should be resolved if defined.

@ FKF_IsPCRel

Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...

unsigned Flags

Flags describing additional information on this fixup kind.