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

1

2

3

4

5

6

7

8

36#include

37#include

38#include

39#include

40

41using namespace llvm;

42

43namespace llvm {

45}

46

47#define DEBUG_TYPE "assembler"

48

49namespace {

51

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

53STATISTIC(EmittedRelaxableFragments,

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

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

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

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

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

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

63STATISTIC(Fixups, "Number of fixups");

64STATISTIC(FixupEvalForRelax, "Number of fixup evaluations for relaxation");

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

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

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

68

69}

70}

71

72

73

74

75

76

77

78

80 std::unique_ptr Backend,

81 std::unique_ptr Emitter,

82 std::unique_ptr Writer)

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

84 Emitter(std::move(Emitter)), Writer(std::move(Writer)) {

85 if (this->Backend)

86 this->Backend->setAssembler(this);

87 if (this->Writer)

88 this->Writer->setAssembler(this);

89}

90

92 HasLayout = false;

93 HasFinalLayout = false;

94 RelaxAll = false;

95 Sections.clear();

96 Symbols.clear();

97 ThumbFuncs.clear();

98

99

104 if (Writer)

105 Writer->reset();

106}

107

109 if (Section.isRegistered())

110 return false;

111 Sections.push_back(&Section);

112 Section.setIsRegistered(true);

113 return true;

114}

115

117 if (ThumbFuncs.count(Symbol))

118 return true;

119

120 if (!Symbol->isVariable())

121 return false;

122

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

124

127 return false;

128

129 if (V.getSubSym() || V.getSpecifier())

130 return false;

131

133 if (!Sym || V.getSpecifier())

134 return false;

135

137 return false;

138

139 ThumbFuncs.insert(Symbol);

140 return true;

141}

142

146 if (RecordReloc)

147 ++stats::Fixups;

148

149

150

151

152

153

154

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

159 return true;

160 }

161

162 bool IsResolved = false;

164 IsResolved = *State;

165 } else {

169 if (Add && Add->isDefined())

171 if (Sub && Sub->isDefined())

173

174 if (Fixup.isPCRel()) {

176 if (Add && Sub && Add->isUndefined() && Add->isAbsolute()) {

178 *Add, F, false, true);

179 }

180 } else {

181 IsResolved = Target.isAbsolute();

182 }

183 }

184

185 if (!RecordReloc)

186 return IsResolved;

187

189 IsResolved = false;

191 return true;

192}

193

196 switch (F.getKind()) {

206 return F.getSize();

209 int64_t NumValues = 0;

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

211 recordError(FF.getLoc(), "expected assembly-time absolute expression");

212 return 0;

213 }

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

215 if (Size < 0) {

216 recordError(FF.getLoc(), "invalid number of bytes");

217 return 0;

218 }

220 }

221

224

227

229 return 4;

230

234 if (!OF.getOffset().evaluateAsValue(Value, *this)) {

235 recordError(OF.getLoc(), "expected assembly-time absolute expression");

236 return 0;

237 }

238

240 int64_t TargetLocation = Value.getConstant();

241 if (const auto *SA = Value.getAddSym()) {

244 recordError(OF.getLoc(), "expected absolute expression");

245 return 0;

246 }

247 TargetLocation += Val;

248 }

249 int64_t Size = TargetLocation - FragmentOffset;

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

252 "' (at offset '" + Twine(FragmentOffset) +

253 "')");

254 return 0;

255 }

257 }

258 }

259

261}

262

263

265 bool ReportError, uint64_t &Val) {

267 if (ReportError)

269 "'");

270 return false;

271 }

273 return true;

274}

275

277 bool ReportError, uint64_t &Val) {

280

281

285 "'");

286

288

290 if (A) {

292

293

294

295

297 return false;

299 }

300

302 if (B) {

305 return false;

307 }

308

310 return true;

311}

312

316

322

325 if (!Symbol.isVariable())

326 return &Symbol;

327

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

331 reportError(Expr->getLoc(), "expression could not be evaluated");

332 return nullptr;

333 }

334

336 if (SymB) {

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

340 return nullptr;

341 }

342

344 if (A)

345 return nullptr;

346

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

351 return nullptr;

352 }

353

354 return &ASym;

355}

356

362

369

371 bool Changed = !Symbol.isRegistered();

373 Symbol.setIsRegistered(true);

374 Symbols.push_back(&Symbol);

375 }

377}

378

380 relocDirectives.push_back(RD);

381}

382

383

386

387 uint64_t FragmentSize = Asm.computeFragmentSize(F);

388

390

391

392

394 (void) Start;

395

396 ++stats::EmittedFragments;

397

398 switch (F.getKind()) {

408 ++stats::EmittedDataFragments;

410 ++stats::EmittedRelaxableFragments;

412 OS << StringRef(EF.getContents().data(), EF.getContents().size());

413 OS << StringRef(EF.getVarContents().data(), EF.getVarContents().size());

414 } break;

415

417 ++stats::EmittedAlignFragments;

418 OS << StringRef(F.getContents().data(), F.getContents().size());

419 assert(F.getAlignFillLen() &&

420 "Invalid virtual align in concrete fragment!");

421

422 uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen();

423 assert((FragmentSize - F.getFixedSize()) % F.getAlignFillLen() == 0 &&

424 "computeFragmentSize computed size is incorrect");

425

426

427 if (F.hasAlignEmitNops()) {

428 if (!Asm.getBackend().writeNopData(OS, Count, F.getSubtargetInfo()))

431 } else {

432

434 switch (F.getAlignFillLen()) {

435 default:

437 case 1:

438 OS << char(F.getAlignFill());

439 break;

440 case 2:

442 break;

443 case 4:

445 break;

446 case 8:

448 break;

449 }

450 }

451 }

452 } break;

453

455 ++stats::EmittedFillFragments;

459 const unsigned MaxChunkSize = 16;

460 char Data[MaxChunkSize];

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

462

463

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

467 }

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

470

471

472 const unsigned NumPerChunk = MaxChunkSize / VSize;

473

474 const unsigned ChunkSize = VSize * NumPerChunk;

475

476

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

479 OS << Ref;

480

481

482 unsigned TrailingCount = FragmentSize % ChunkSize;

483 if (TrailingCount)

485 break;

486 }

487

489 ++stats::EmittedNopsFragments;

491

494 int64_t MaximumNopLength =

496

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

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

499

500 if (ControlledNopLength > MaximumNopLength) {

501 Asm.reportError(NF.getLoc(), "illegal NOP size " +

502 std::to_string(ControlledNopLength) +

503 ". (expected within [0, " +

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

505

506

507 ControlledNopLength = MaximumNopLength;

508 }

509

510

511 if (!ControlledNopLength)

512 ControlledNopLength = MaximumNopLength;

513

514 while (NumBytes) {

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

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

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

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

521 Twine(NumBytesToEmit) + " bytes");

522 break;

523 }

524 NumBytes -= NumBytesToEmit;

525 }

526 break;

527 }

528

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

533 Twine(FragmentSize) + " bytes");

534 break;

535 }

536

540 break;

541 }

542

544 ++stats::EmittedOrgFragments;

546

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

548 OS << char(OF.getValue());

549

550 break;

551 }

552

553 }

554

555 assert(OS.tell() - Start == FragmentSize &&

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

557}

558

562

565

566

567

568

569 auto Fn = [](char c) { return c != 0; };

571 bool HasNonZero = false;

572 switch (F.getKind()) {

573 default:

575 "' contains invalid fragment");

576 break;

579 HasNonZero =

580 any_of(F.getContents(), Fn) || any_of(F.getVarContents(), Fn);

581 break;

583

584

585 assert(F.getAlignFill() == 0 && "Invalid align in virtual section!");

586 break;

589 break;

592 break;

593 }

594 if (HasNonZero) {

596 "' cannot have non-zero bytes");

597 break;

598 }

599 if (F.getFixups().size() || F.getVarFixups().size()) {

601 "BSS section '" + Sec->getName() + "' cannot have fixups");

602 break;

603 }

604 }

605

606 return;

607 }

608

610 (void)Start;

611

614

618}

619

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

625 });

626

627

628 unsigned SectionIndex = 0;

631

632

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

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

640 }

641 Sec.Subsections.clear();

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

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

644

645 unsigned FragmentIndex = 0;

647 Frag.setLayoutOrder(FragmentIndex++);

648 }

649 }

650

651

652 this->HasLayout = true;

654 layoutSection(Sec);

655 unsigned FirstStable = Sections.size();

656 while ((FirstStable = relaxOnce(FirstStable)) > 0)

658 return;

659

660

661

664 layoutSection(Sec);

665

667

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

671

672

673

675

676

677

678 this->HasFinalLayout = true;

679

680

681 for (auto &PF : relocDirectives) {

683 auto &O = PF.Offset;

684 if (!O.evaluateAsValue(Res, *this)) {

686 continue;

687 }

689 auto *F = Sym ? Sym->getFragment() : nullptr;

690 auto *Sec = F ? F->getParent() : nullptr;

693 ".reloc offset is not relative to a section");

694 continue;

695 }

696

699 }

700

701

704

705 auto Contents = F.getContents();

710 Fixup.getOffset() <= F.getFixedSize());

712 reinterpret_cast<uint8_t *>(Contents.data() + Fixup.getOffset());

714 true, Data);

715 }

716

717

722 (Fixup.getOffset() >= F.getFixedSize() &&

723 Fixup.getOffset() <= F.getSize()));

724 auto *Data = reinterpret_cast<uint8_t *>(

725 F.getVarContents().data() + (Fixup.getOffset() - F.getFixedSize()));

727 true, Data);

728 }

729 }

730 }

731}

732

735

736

738

739 HasLayout = false;

740 assert(PendingErrors.empty());

741}

742

743bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F,

745 ++stats::FixupEvalForRelax;

749 false, {});

751 Resolved);

752}

753

754void MCAssembler::relaxInstruction(MCFragment &F) {

756 "Expected CodeEmitter defined for relaxInstruction");

757

758

759

760 if (getBackend().mayNeedRelaxation(F.getOpcode(), F.getOperands(),

761 *F.getSubtargetInfo()))

762 return;

763

764 bool DoRelax = false;

765 for (const MCFixup &Fixup : F.getVarFixups())

766 if ((DoRelax = fixupNeedsRelaxation(F, Fixup)))

767 break;

768 if (!DoRelax)

769 return;

770

771 ++stats::RelaxedInstructions;

772

773

774

775 MCInst Relaxed = F.getInst();

777

778

779 F.setInst(Relaxed);

783 F.setVarContents(Data);

784 F.setVarFixups(Fixups);

785}

786

787void MCAssembler::relaxLEB(MCFragment &F) {

788 unsigned PadTo = F.getVarSize();

790 F.clearVarFixups();

791

792

793

795 ? F.getLEBValue().evaluateKnownAbsolute(Value, *this)

796 : F.getLEBValue().evaluateAsAbsolute(Value, *this);

797 if (!Abs) {

798 bool Relaxed, UseZeroPad;

800 if (!Relaxed) {

802 Twine(F.isLEBSigned() ? ".s" : ".u") +

803 "leb128 expression is not absolute");

805 }

806 uint8_t Tmp[10];

808 if (UseZeroPad)

810 }

811 uint8_t Data[16];

812 size_t Size = 0;

813

814

815

816

817 if (F.isLEBSigned())

819 else

821 F.setVarContents({reinterpret_cast<char *>(Data), Size});

822}

823

824

825

826

827

828

829

831 Align BoundaryAlignment) {

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

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

835}

836

837

838

839

840

841

842

844 Align BoundaryAlignment) {

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

847}

848

849

850

851

852

853

854

856 Align BoundaryAlignment) {

859}

860

862

863

865 return;

866

868 uint64_t AlignedSize = 0;

872 break;

873 }

874

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

878 : 0U;

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

880 return;

882}

883

884void MCAssembler::relaxDwarfLineAddr(MCFragment &F) {

886 return;

887

889 int64_t AddrDelta;

890 bool Abs = F.getDwarfAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);

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

892 (void)Abs;

893 SmallVector<char, 8> Data;

895 F.getDwarfLineDelta(), AddrDelta, Data);

896 F.setVarContents(Data);

897 F.clearVarFixups();

898}

899

900void MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) {

902 return;

903

906 bool Abs = F.getDwarfAddrDelta().evaluateAsAbsolute(Value, *this);

907 if (!Abs) {

909 "invalid CFI advance_loc expression");

911 return;

912 }

913

914 SmallVector<char, 8> Data;

916 F.setVarContents(Data);

917 F.clearVarFixups();

918}

919

920void MCAssembler::relaxSFrameFragment(MCFragment &F) {

924 bool Abs = F.getSFrameAddrDelta().evaluateAsAbsolute(Value, *this);

925 if (!Abs) {

926 C.reportError(F.getSFrameAddrDelta().getLoc(),

927 "invalid CFI advance_loc expression in sframe");

929 return;

930 }

931

934 F.setVarContents(Data);

935 F.clearVarFixups();

936}

937

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

940 switch (F.getKind()) {

941 default:

942 return false;

944 assert(getRelaxAll() && "Did not expect a FT_Relaxable in RelaxAll mode");

945 relaxInstruction(F);

946 break;

948 relaxLEB(F);

949 break;

951 relaxDwarfLineAddr(F);

952 break;

954 relaxDwarfCallFrameFragment(F);

955 break;

957 relaxSFrameFragment(F);

958 break;

960 relaxBoundaryAlign(static_cast<MCBoundaryAlignFragment &>(F));

961 break;

964 *this, static_cast<MCCVInlineLineTableFragment &>(F));

965 break;

968 *this, static_cast<MCCVDefRangeFragment &>(F));

969 break;

972 return F.getNext()->Offset - F.Offset != Size;

973 }

975}

976

977void MCAssembler::layoutSection(MCSection &Sec) {

979 for (MCFragment &F : Sec) {

982 Offset += F.getFixedSize();

984

985

986 bool AlignFixup = false;

987 if (F.hasAlignEmitNops()) {

989

990

991 if (!AlignFixup)

993 Size += F.getAlignment().value();

994 }

995 if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())

997

998

999 F.VarContentStart = F.getFixedSize();

1000 F.VarContentEnd = F.VarContentStart + Size;

1001 if (F.VarContentEnd > F.getParent()->ContentStorage.size())

1002 F.getParent()->ContentStorage.resize(F.VarContentEnd);

1004 } else {

1006 }

1007 }

1008}

1009

1010unsigned MCAssembler::relaxOnce(unsigned FirstStable) {

1011 ++stats::RelaxationSteps;

1012 PendingErrors.clear();

1013

1014 unsigned Res = 0;

1015 for (unsigned I = 0; I != FirstStable; ++I) {

1016

1017

1018 auto &Sec = *Sections[I];

1019 auto MaxIter = Sec.curFragList()->Tail->getLayoutOrder() + 1;

1020 for (;;) {

1022 for (MCFragment &F : Sec)

1025

1027 break;

1028

1029

1030 FirstStable = Sections.size();

1031 Res = I;

1032 if (--MaxIter == 0)

1033 break;

1034 layoutSection(Sec);

1035 }

1036 }

1037

1038

1039 return Res;

1040}

1041

1045

1047 PendingErrors.emplace_back(Loc, Msg.str());

1048}

1049

1051 for (auto &Err : PendingErrors)

1053 PendingErrors.clear();

1054}

1055

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

1060

1061

1062

1064 if (!Sym.isVariable())

1065 if (auto *F = Sym.getFragment())

1066 FragToSyms.try_emplace(F).first->second.push_back(&Sym);

1067

1068 OS << "Sections:[";

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

1070 OS << '\n';

1071 Sec.dump(&FragToSyms);

1072 }

1073 OS << "\n]\n";

1074}

1075#endif

1076

1079 return E->getLoc();

1080 return {};

1081}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

#define LLVM_DUMP_METHOD

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

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

Definition MCAssembler.cpp:276

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

Check if the branch needs padding.

Definition MCAssembler.cpp:855

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

Write the fragment F to the output file.

Definition MCAssembler.cpp:384

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

Check if the branch crosses the boundary.

Definition MCAssembler.cpp:830

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

Check if the branch is against the boundary.

Definition MCAssembler.cpp:843

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

Definition MCAssembler.cpp:264

PowerPC TLS Dynamic Call Fixup

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)

#define DEBUG_WITH_TYPE(TYPE,...)

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

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

Encodes the binary annotations once we have a layout.

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

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

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

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

virtual bool relaxAlign(MCFragment &F, unsigned &Size)

virtual std::pair< bool, bool > relaxLEB128(MCFragment &, int64_t &Value) const

virtual bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, const MCValue &, uint64_t, bool Resolved) const

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

virtual void reset()

lifetime management

virtual void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target, uint8_t *Data, uint64_t Value, bool IsResolved)=0

MCContext & getContext() const

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

Definition MCAssembler.cpp:313

LLVM_ABI uint64_t getSectionAddressSize(const MCSection &Sec) const

Definition MCAssembler.cpp:357

LLVM_ABI void Finish()

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

Definition MCAssembler.cpp:733

LLVM_ABI void reportError(SMLoc L, const Twine &Msg) const

Definition MCAssembler.cpp:1042

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

Emit the section contents to OS.

Definition MCAssembler.cpp:559

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

LLVM_ABI void dump() const

Definition MCAssembler.cpp:1057

LLVM_ABI void layout()

Definition MCAssembler.cpp:620

MCObjectWriter & getWriter() const

MCCodeEmitter * getEmitterPtr() const

LLVM_ABI void addRelocDirective(RelocDirective RD)

Definition MCAssembler.cpp:379

MCCodeEmitter & getEmitter() const

LLVM_ABI void recordError(SMLoc L, const Twine &Msg) const

Definition MCAssembler.cpp:1046

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

Construct a new assembler instance.

Definition MCAssembler.cpp:79

LLVM_ABI bool isThumbFunc(const MCSymbol *Func) const

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

Definition MCAssembler.cpp:116

MCAsmBackend & getBackend() const

LLVM_ABI bool registerSection(MCSection &Section)

Definition MCAssembler.cpp:108

LLVM_ABI void flushPendingErrors() const

Definition MCAssembler.cpp:1050

LLVM_ABI uint64_t computeFragmentSize(const MCFragment &F) const

Compute the effective fragment size.

Definition MCAssembler.cpp:194

LLVM_ABI const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const

Definition MCAssembler.cpp:323

MCAsmBackend * getBackendPtr() const

LLVM_ABI uint64_t getSectionFileSize(const MCSection &Sec) const

Definition MCAssembler.cpp:363

LLVM_ABI void reset()

Reuse an assembler instance.

Definition MCAssembler.cpp:91

LLVM_ABI bool registerSymbol(const MCSymbol &Symbol)

Definition MCAssembler.cpp:370

uint64_t getFragmentOffset(const MCFragment &F) const

MCDwarfLineTableParams getDWARFLinetableParams() const

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

Align getAlignment() const

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 LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

LLVM_ABI CodeViewContext & getCVContext()

LLVM_ABI void reportError(SMLoc L, const Twine &Msg)

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

static LLVM_ABI 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.

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

LLVM_ABI 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.

LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) 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)...

const MCExpr * getValue() const

LLVM_ABI SMLoc getLoc() const

Definition MCAssembler.cpp:1077

static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)

Consider bit fields if we need more flags.

MCFragment * getNext() const

const MCSubtargetInfo * getSubtargetInfo() const

Retrieve the MCSubTargetInfo in effect when the instruction was encoded.

int64_t getControlledNopLength() const

int64_t getNumBytes() const

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

bool getSubsectionsViaSymbols() const

virtual void executePostLayoutBinding()

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

virtual uint64_t writeObject()=0

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

static void encodeFuncOffset(MCContext &C, uint64_t Offset, SmallVectorImpl< char > &Out, MCFragment *FDEFrag)

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

bool isBssSection() const

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

void dump(DenseMap< const MCFragment *, SmallVector< const MCSymbol *, 0 > > *FragToSyms=nullptr) const

void setOrdinal(unsigned Value)

FragList * curFragList() const

Generic base class for all target subtargets.

Represents a symbol table index fragment.

const MCSymbol * getSymbol()

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

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.

uint32_t getIndex() const

Get the (implementation defined) index.

const MCExpr * getVariableValue() const

Get the expression of the variable symbol.

MCFragment * getFragment() const

uint64_t getOffset() const

const MCSymbol * getAddSym() const

int64_t getConstant() const

const MCSymbol * getSubSym() const

Represents a location in source code.

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_ABI std::string str() const

Return the twine contents as a std::string.

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)

#define llvm_unreachable(msg)

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

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

@ Tail

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

@ C

The default llvm calling convention, compatible with C.

bool isRelocRelocation(MCFixupKind FixupKind)

void write(void *memory, value_type value, endianness endian)

Write a value to memory with a particular endianness.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

LLVM_ABI void reportFatalInternalError(Error Err)

Report a fatal error that indicates a bug in LLVM.

bool any_of(R &&range, UnaryPredicate P)

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

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

FunctionAddr VTableAddr Count

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

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...

LLVM_ABI 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.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

@ Sub

Subtraction of integers.

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.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

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.

LLVM_ABI void reportFatalUsageError(Error Err)

Report a fatal error that does not indicate a bug in LLVM.

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.

constexpr uint64_t value() const

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