LLVM: lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

16#include

17

18#define DEBUG_TYPE "jitlink"

19

21

22namespace llvm {

23namespace jitlink {

24

26

28

29

30 if (!Obj.isRelocatableObject())

32

33 if (auto Err = createNormalizedSections())

34 return std::move(Err);

35

36 if (auto Err = createNormalizedSymbols())

37 return std::move(Err);

38

39 if (auto Err = graphifyRegularSymbols())

40 return std::move(Err);

41

42 if (auto Err = graphifySectionsWithCustomParsers())

43 return std::move(Err);

44

46 return std::move(Err);

47

48 return std::move(G);

49}

50

53 std::shared_ptrorc::SymbolStringPool SSP, Triple TT,

56 : Obj(Obj),

60 auto &MachHeader = Obj.getHeader64();

62}

63

67 "Custom parser for this section already exists");

68 CustomSectionParserFunctions[SectionName] = std::move(Parser);

69}

70

76

86

90

93 strcmp(NSec.SegName, "__DWARF") == 0);

94}

95

101 return true;

102 default:

103 return false;

104 }

105}

106

107Section &MachOLinkGraphBuilder::getCommonSection() {

108 if (!CommonSection)

111 return *CommonSection;

112}

113

114Error MachOLinkGraphBuilder::createNormalizedSections() {

115

116

117

118 LLVM_DEBUG(dbgs() << "Creating normalized sections...\n");

119

120 for (auto &SecRef : Obj.sections()) {

121 NormalizedSection NSec;

123

124 auto SecIndex = Obj.getSectionIndex(SecRef.getRawDataRefImpl());

125

128 Obj.getSection64(SecRef.getRawDataRefImpl());

129

130 memcpy(&NSec.SectName, &Sec64.sectname, 16);

131 NSec.SectName[16] = '\0';

132 memcpy(&NSec.SegName, Sec64.segname, 16);

133 NSec.SegName[16] = '\0';

134

136 NSec.Size = Sec64.size;

137 NSec.Alignment = 1ULL << Sec64.align;

138 NSec.Flags = Sec64.flags;

139 DataOffset = Sec64.offset;

140 } else {

141 const MachO::section &Sec32 = Obj.getSection(SecRef.getRawDataRefImpl());

142

143 memcpy(&NSec.SectName, &Sec32.sectname, 16);

144 NSec.SectName[16] = '\0';

145 memcpy(&NSec.SegName, Sec32.segname, 16);

146 NSec.SegName[16] = '\0';

147

148 NSec.Address = orc::ExecutorAddr(Sec32.addr);

149 NSec.Size = Sec32.size;

150 NSec.Alignment = 1ULL << Sec32.align;

151 NSec.Flags = Sec32.flags;

152 DataOffset = Sec32.offset;

153 }

154

156 dbgs() << " " << NSec.SegName << "," << NSec.SectName << ": "

157 << formatv("{0:x16}", NSec.Address) << " -- "

158 << formatv("{0:x16}", NSec.Address + NSec.Size)

159 << ", align: " << NSec.Alignment << ", index: " << SecIndex

160 << "\n";

161 });

162

163

165 if (DataOffset + NSec.Size > Obj.getData().size())

167 "Section data extends past end of file");

168

169 NSec.Data = Obj.getData().data() + DataOffset;

170 }

171

172

173

174

178 else

180

181 auto FullyQualifiedName =

182 G->allocateContent(StringRef(NSec.SegName) + "," + NSec.SectName);

183 NSec.GraphSection = &G->createSection(

184 StringRef(FullyQualifiedName.data(), FullyQualifiedName.size()), Prot);

185

186

189

190 IndexToSection.insert(std::make_pair(SecIndex, std::move(NSec)));

191 }

192

193 std::vector<NormalizedSection *> Sections;

194 Sections.reserve(IndexToSection.size());

195 for (auto &KV : IndexToSection)

196 Sections.push_back(&KV.second);

197

198

199

200 if (Sections.empty())

202

206 return std::tie(LHS->Address, LHS->Size) <

207 std::tie(RHS->Address, RHS->Size);

208 });

209

210 for (unsigned I = 0, E = Sections.size() - 1; I != E; ++I) {

211 auto &Cur = *Sections[I];

212 auto &Next = *Sections[I + 1];

213 if (Next.Address < Cur.Address + Cur.Size)

215 "Address range for section " +

216 formatv("\"{0}/{1}\" [ {2:x16} -- {3:x16} ] ", Cur.SegName,

217 Cur.SectName, Cur.Address, Cur.Address + Cur.Size) +

218 "overlaps section \"" + Next.SegName + "/" + Next.SectName + "\"" +

219 formatv("\"{0}/{1}\" [ {2:x16} -- {3:x16} ] ", Next.SegName,

221 }

222

224}

225

226Error MachOLinkGraphBuilder::createNormalizedSymbols() {

227 LLVM_DEBUG(dbgs() << "Creating normalized symbols...\n");

228

229 for (auto &SymRef : Obj.symbols()) {

230

231 unsigned SymbolIndex = Obj.getSymbolIndex(SymRef.getRawDataRefImpl());

233 uint32_t NStrX;

234 uint8_t Type;

235 uint8_t Sect;

236 uint16_t Desc;

237

238 if (Obj.is64Bit()) {

239 const MachO::nlist_64 &NL64 =

240 Obj.getSymbol64TableEntry(SymRef.getRawDataRefImpl());

241 Value = NL64.n_value;

242 NStrX = NL64.n_strx;

243 Type = NL64.n_type;

244 Sect = NL64.n_sect;

245 Desc = NL64.n_desc;

246 } else {

247 const MachO::nlist &NL32 =

248 Obj.getSymbolTableEntry(SymRef.getRawDataRefImpl());

249 Value = NL32.n_value;

250 NStrX = NL32.n_strx;

251 Type = NL32.n_type;

252 Sect = NL32.n_sect;

253 Desc = NL32.n_desc;

254 }

255

256

257

259 continue;

260

261 std::optional Name;

262 if (NStrX) {

263 if (auto NameOrErr = SymRef.getName())

264 Name = *NameOrErr;

265 else

266 return NameOrErr.takeError();

269 formatv("{0}", SymbolIndex) +

270 " has no name (string table index 0), "

271 "but N_EXT bit is set");

272

274 dbgs() << " ";

275 if (!Name)

276 dbgs() << "";

277 else

280 << ", type = " << formatv("{0:x2}", Type)

281 << ", desc = " << formatv("{0:x4}", Desc) << ", sect = ";

282 if (Sect)

283 dbgs() << static_cast<unsigned>(Sect - 1);

284 else

285 dbgs() << "none";

286 dbgs() << "\n";

287 });

288

289

290 if (Sect != 0) {

292 if (!NSec)

293 return NSec.takeError();

294

295 if (orc::ExecutorAddr(Value) < NSec->Address ||

296 orc::ExecutorAddr(Value) > NSec->Address + NSec->Size)

298 " for symbol " + *Name +

299 " does not fall within section");

300

301 if (!NSec->GraphSection) {

303 dbgs() << " Skipping: Symbol is in section " << NSec->SegName << "/"

304 << NSec->SectName

305 << " which has no associated graph section.\n";

306 });

307 continue;

308 }

309 }

310

313 }

314

316}

317

318void MachOLinkGraphBuilder::addSectionStartSymAndBlock(

319 unsigned SecIndex, Section &GraphSec, orc::ExecutorAddr Address,

321 bool IsLive) {

323 Data ? G->createContentBlock(GraphSec, ArrayRef(Data, Size),

325 : G->createZeroFillBlock(GraphSec, Size, Address, Alignment, 0);

326 auto &Sym = G->addAnonymousSymbol(B, 0, Size, false, IsLive);

327 auto SecI = IndexToSection.find(SecIndex);

328 assert(SecI != IndexToSection.end() && "SecIndex invalid");

329 auto &NSec = SecI->second;

330 assert(!NSec.CanonicalSymbols.count(Sym.getAddress()) &&

331 "Anonymous block start symbol clashes with existing symbol address");

332 NSec.CanonicalSymbols[Sym.getAddress()] = &Sym;

333}

334

335Error MachOLinkGraphBuilder::graphifyRegularSymbols() {

336

338

339

340 std::vector<std::vector<NormalizedSymbol *>> SecIndexToSymbols;

341 SecIndexToSymbols.resize(256);

342

343

344

345 for (auto &KV : IndexToSymbol) {

346 auto &NSym = *KV.second;

347

350 if (NSym.Value) {

351 if (!NSym.Name)

353 Twine(KV.first));

354 NSym.GraphSymbol = &G->addDefinedSymbol(

355 G->createZeroFillBlock(getCommonSection(),

357 orc::ExecutorAddr(),

361 } else {

362 if (!NSym.Name)

364 "index " +

365 Twine(KV.first));

366 NSym.GraphSymbol = &G->addExternalSymbol(

368 }

369 break;

371 if (!NSym.Name)

373 Twine(KV.first));

374 NSym.GraphSymbol = &G->addAbsoluteSymbol(

375 *NSym.Name, orc::ExecutorAddr(NSym.Value), 0, Linkage::Strong,

377 break;

379 SecIndexToSymbols[NSym.Sect - 1].push_back(&NSym);

380 break;

383 "Unupported N_PBUD symbol " +

384 (NSym.Name ? ("\"" + *NSym.Name + "\"") : Twine("")) +

385 " at index " + Twine(KV.first));

388 "Unupported N_INDR symbol " +

389 (NSym.Name ? ("\"" + *NSym.Name + "\"") : Twine("")) +

390 " at index " + Twine(KV.first));

391 default:

393 "Unrecognized symbol type " + Twine(NSym.Type & MachO::N_TYPE) +

394 " for symbol " +

395 (NSym.Name ? ("\"" + *NSym.Name + "\"") : Twine("")) +

396 " at index " + Twine(KV.first));

397 }

398 }

399

400

401

402 for (auto &KV : IndexToSection) {

403 auto SecIndex = KV.first;

404 auto &NSec = KV.second;

405

406 if (!NSec.GraphSection) {

408 dbgs() << " " << NSec.SegName << "/" << NSec.SectName

409 << " has no graph section. Skipping.\n";

410 });

411 continue;

412 }

413

414

415 if (CustomSectionParserFunctions.count(NSec.GraphSection->getName())) {

417 dbgs() << " Skipping section " << NSec.GraphSection->getName()

418 << " as it has a custom parser.\n";

419 });

420 continue;

423 if (auto Err = graphifyCStringSection(

424 NSec, std::move(SecIndexToSymbols[SecIndex])))

425 return Err;

426 continue;

427 } else

429 dbgs() << " Graphifying regular section "

430 << NSec.GraphSection->getName() << "...\n";

431 });

432

435

436 auto &SecNSymStack = SecIndexToSymbols[SecIndex];

437

438

439

440 if (SecNSymStack.empty()) {

441 if (NSec.Size > 0) {

443 dbgs() << " Section non-empty, but contains no symbols. "

444 "Creating anonymous block to cover "

445 << formatv("{0:x16}", NSec.Address) << " -- "

446 << formatv("{0:x16}", NSec.Address + NSec.Size) << "\n";

447 });

448 addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,

449 NSec.Data, NSec.Size, NSec.Alignment,

450 SectionIsNoDeadStrip);

451 } else

453 dbgs() << " Section empty and contains no symbols. Skipping.\n";

454 });

455 continue;

456 }

457

458

459

460

463 if (LHS->Value != RHS->Value)

464 return LHS->Value > RHS->Value;

467 if (LHS->S != RHS->S)

468 return static_cast<uint8_t>(LHS->S) < static_cast<uint8_t>(RHS->S);

469 return LHS->Name < RHS->Name;

470 });

471

472

473 if (!SecNSymStack.empty() && isAltEntry(*SecNSymStack.back()))

475 "First symbol in " + NSec.GraphSection->getName() + " is alt-entry");

476

477

478

479 if (orc::ExecutorAddr(SecNSymStack.back()->Value) != NSec.Address) {

480 auto AnonBlockSize =

481 orc::ExecutorAddr(SecNSymStack.back()->Value) - NSec.Address;

483 dbgs() << " Section start not covered by symbol. "

484 << "Creating anonymous block to cover [ " << NSec.Address

485 << " -- " << (NSec.Address + AnonBlockSize) << " ]\n";

486 });

487 addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,

488 NSec.Data, AnonBlockSize, NSec.Alignment,

489 SectionIsNoDeadStrip);

490 }

491

492

493

494

495

496

497

498

499

500 while (!SecNSymStack.empty()) {

502

503

504

505 BlockSyms.push_back(SecNSymStack.back());

506 SecNSymStack.pop_back();

507 while (!SecNSymStack.empty() &&

509 SecNSymStack.back()->Value == BlockSyms.back()->Value ||

510 !SubsectionsViaSymbols)) {

511 BlockSyms.push_back(SecNSymStack.back());

512 SecNSymStack.pop_back();

513 }

514

515

516 auto BlockStart = orc::ExecutorAddr(BlockSyms.front()->Value);

517 orc::ExecutorAddr BlockEnd =

518 SecNSymStack.empty() ? NSec.Address + NSec.Size

519 : orc::ExecutorAddr(SecNSymStack.back()->Value);

522

524 dbgs() << " Creating block for " << formatv("{0:x16}", BlockStart)

525 << " -- " << formatv("{0:x16}", BlockEnd) << ": "

526 << NSec.GraphSection->getName() << " + "

527 << formatv("{0:x16}", BlockOffset) << " with "

528 << BlockSyms.size() << " symbol(s)...\n";

529 });

530

532 NSec.Data

533 ? G->createContentBlock(

534 *NSec.GraphSection,

535 ArrayRef(NSec.Data + BlockOffset, BlockSize),

536 BlockStart, NSec.Alignment, BlockStart % NSec.Alignment)

537 : G->createZeroFillBlock(*NSec.GraphSection, BlockSize,

538 BlockStart, NSec.Alignment,

539 BlockStart % NSec.Alignment);

540

541 std::optionalorc::ExecutorAddr LastCanonicalAddr;

542 auto SymEnd = BlockEnd;

543 while (!BlockSyms.empty()) {

544 auto &NSym = *BlockSyms.back();

545 BlockSyms.pop_back();

546

547 bool SymLive =

549

550 auto &Sym = createStandardGraphSymbol(

551 NSym, B, SymEnd - orc::ExecutorAddr(NSym.Value), SectionIsText,

552 SymLive, LastCanonicalAddr != orc::ExecutorAddr(NSym.Value));

553

554 if (LastCanonicalAddr != Sym.getAddress()) {

555 if (LastCanonicalAddr)

556 SymEnd = *LastCanonicalAddr;

557 LastCanonicalAddr = Sym.getAddress();

558 }

559 }

560 }

561 }

562

564}

565

566Symbol &MachOLinkGraphBuilder::createStandardGraphSymbol(NormalizedSymbol &NSym,

568 bool IsText,

569 bool IsNoDeadStrip,

570 bool IsCanonical) {

571

573 dbgs() << " " << formatv("{0:x16}", NSym.Value) << " -- "

574 << formatv("{0:x16}", NSym.Value + Size) << ": ";

575 if (!NSym.Name)

576 dbgs() << "";

577 else

578 dbgs() << *NSym.Name;

579 if (IsText)

580 dbgs() << " [text]";

581 if (IsNoDeadStrip)

582 dbgs() << " [no-dead-strip]";

583 if (!IsCanonical)

584 dbgs() << " [non-canonical]";

585 dbgs() << "\n";

586 });

587

588 auto SymOffset = orc::ExecutorAddr(NSym.Value) - B.getAddress();

589 auto &Sym =

590 NSym.Name

591 ? G->addDefinedSymbol(B, SymOffset, *NSym.Name, Size, NSym.L, NSym.S,

592 IsText, IsNoDeadStrip)

593 : G->addAnonymousSymbol(B, SymOffset, Size, IsText, IsNoDeadStrip);

594 NSym.GraphSymbol = &Sym;

595

596 if (IsCanonical)

598

599 return Sym;

600}

601

602Error MachOLinkGraphBuilder::graphifySectionsWithCustomParsers() {

603

604 for (auto &KV : IndexToSection) {

605 auto &NSec = KV.second;

606

607

608 if (!NSec.GraphSection)

609 continue;

610

611 auto HI = CustomSectionParserFunctions.find(NSec.GraphSection->getName());

612 if (HI != CustomSectionParserFunctions.end()) {

613 auto &Parse = HI->second;

614 if (auto Err = Parse(NSec))

615 return Err;

616 }

617 }

618

620}

621

622Error MachOLinkGraphBuilder::graphifyCStringSection(

623 NormalizedSection &NSec, std::vector<NormalizedSymbol *> NSyms) {

624 assert(NSec.GraphSection && "C string literal section missing graph section");

625 assert(NSec.Data && "C string literal section has no data");

626

628 dbgs() << " Graphifying C-string literal section "

629 << NSec.GraphSection->getName() << "\n";

630 });

631

632 if (NSec.Data[NSec.Size - 1] != '\0')

634 NSec.GraphSection->getName() +

635 " does not end with null terminator");

636

637

640 if (LHS->Value != RHS->Value)

641 return LHS->Value > RHS->Value;

642 if (LHS->L != RHS->L)

643 return LHS->L > RHS->L;

644 if (LHS->S != RHS->S)

645 return LHS->S > RHS->S;

646 if (RHS->Name) {

647 if (LHS->Name)

648 return true;

649 return *LHS->Name > *RHS->Name;

650 }

651 return false;

652 });

653

657

658

659 for (size_t I = 0; I != NSec.Size; ++I) {

660 if (NSec.Data[I] == '\0') {

661 size_t BlockSize = I + 1 - BlockStart;

662

663 auto &B = G->createContentBlock(*NSec.GraphSection,

664 {NSec.Data + BlockStart, BlockSize},

665 NSec.Address + BlockStart, NSec.Alignment,

666 BlockStart % NSec.Alignment);

667

669 dbgs() << " Created block " << B.getRange()

670 << ", align = " << B.getAlignment()

671 << ", align-ofs = " << B.getAlignmentOffset() << " for \"";

672 for (size_t J = 0; J != std::min(B.getSize(), size_t(16)); ++J)

673 switch (B.getContent()[J]) {

674 case '\0': break;

675 case '\n': dbgs() << "\\n"; break;

676 case '\t': dbgs() << "\\t"; break;

677 default: dbgs() << B.getContent()[J]; break;

678 }

679 if (B.getSize() > 16)

680 dbgs() << "...";

681 dbgs() << "\"\n";

682 });

683

684

685 if (NSyms.empty() ||

686 orc::ExecutorAddr(NSyms.back()->Value) != B.getAddress()) {

687 auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);

688 setCanonicalSymbol(NSec, S);

690 dbgs() << " Adding symbol for c-string block " << B.getRange()

691 << ": at offset 0\n";

692 });

693 }

694

695

696 auto LastCanonicalAddr = B.getAddress() + BlockSize;

697 while (!NSyms.empty() && orc::ExecutorAddr(NSyms.back()->Value) <

699 auto &NSym = *NSyms.back();

700 size_t SymSize = (B.getAddress() + BlockSize) -

701 orc::ExecutorAddr(NSyms.back()->Value);

702 bool SymLive =

704

705 bool IsCanonical = false;

706 if (LastCanonicalAddr != orc::ExecutorAddr(NSym.Value)) {

707 IsCanonical = true;

708 LastCanonicalAddr = orc::ExecutorAddr(NSym.Value);

709 }

710

711 auto &Sym = createStandardGraphSymbol(NSym, B, SymSize, SectionIsText,

712 SymLive, IsCanonical);

713 (void)Sym;

715 dbgs() << " Adding symbol for c-string block " << B.getRange()

716 << ": "

717 << (Sym.hasName() ? *Sym.getName() : "")

718 << " at offset " << formatv("{0:x}", Sym.getOffset()) << "\n";

719 });

720

721 NSyms.pop_back();

722 }

723

725 }

726 }

727

729 [](Block *B) { return isCStringBlock(*B); }) &&

730 "All blocks in section should hold single c-strings");

731

733}

734

735}

736}

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

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

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

static const char * CommonSectionName

static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)

Provides some synthesis utilities to produce sequences of values.

static const int BlockSize

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

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

Manages the enabling and disabling of subtarget specific features.

Triple - Helper class for working with autoconf configuration names.

The instances of the Type class are immutable: once they are created, they are never changed.

An Addressable with content and edges.

const char *(*)(Edge::Kind) GetEdgeKindNameFunction

static bool isDebugSection(const NormalizedSection &NSec)

Definition MachOLinkGraphBuilder.cpp:91

void addCustomSectionParser(StringRef SectionName, SectionParserFunction Parse)

Definition MachOLinkGraphBuilder.cpp:64

virtual ~MachOLinkGraphBuilder()

virtual Error addRelocations()=0

std::function< Error(NormalizedSection &S)> SectionParserFunction

static Scope getScope(StringRef Name, uint8_t Type)

Definition MachOLinkGraphBuilder.cpp:77

static bool isZeroFillSection(const NormalizedSection &NSec)

Definition MachOLinkGraphBuilder.cpp:96

Expected< std::unique_ptr< LinkGraph > > buildGraph()

Definition MachOLinkGraphBuilder.cpp:27

NormalizedSection & getSectionByIndex(unsigned Index)

Index is zero-based (MachO section indexes are usually one-based) and assumed to be in-range.

MachOLinkGraphBuilder(const object::MachOObjectFile &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)

Definition MachOLinkGraphBuilder.cpp:51

NormalizedSymbol & createNormalizedSymbol(ArgTs &&... Args)

Create a symbol.

static Linkage getLinkage(uint16_t Desc)

Definition MachOLinkGraphBuilder.cpp:71

static bool isAltEntry(const NormalizedSymbol &NSym)

Definition MachOLinkGraphBuilder.cpp:87

Expected< NormalizedSection & > findSectionByIndex(unsigned Index)

Try to get the section at the given index.

Represents an object file section.

orc::ExecutorAddr getAddress() const

Returns the address of this symbol.

Expected< SectionRef > getSection(unsigned SectionIndex) const

MachO::section_64 getSection64(DataRefImpl DRI) const

bool is64Bit() const override

uint64_t getSectionIndex(DataRefImpl Sec) const override

section_iterator_range sections() const

Represents an address in the executor process.

@ S_GB_ZEROFILL

S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).

@ S_THREAD_LOCAL_ZEROFILL

S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.

@ S_CSTRING_LITERALS

S_CSTRING_LITERALS - Section with literal C strings.

@ S_ZEROFILL

S_ZEROFILL - Zero fill on demand section.

@ MH_SUBSECTIONS_VIA_SYMBOLS

uint8_t GET_COMM_ALIGN(uint16_t n_desc)

@ S_ATTR_DEBUG

S_ATTR_DEBUG - A debug section.

@ S_ATTR_NO_DEAD_STRIP

S_ATTR_NO_DEAD_STRIP - No dead stripping.

@ S_ATTR_PURE_INSTRUCTIONS

S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.

Linkage

Describes symbol linkage. This can be used to resolve definition clashes.

Scope

Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...

MemProt

Describes Read/Write/Exec permissions for memory.

uint64_t ExecutorAddrDiff

@ NoAlloc

NoAlloc memory should not be allocated by the JITLinkMemoryManager at all.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

bool all_of(R &&range, UnaryPredicate P)

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

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

class LLVM_GSL_OWNER SmallVector

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

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

FunctionAddr VTableAddr Next

OutputIt move(R &&Range, OutputIt Out)

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

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