18#define DEBUG_TYPE "jitlink"
31 return make_error<JITLinkError>(
"Object is not a relocatable MachO");
33 if (
auto Err = createNormalizedSections())
34 return std::move(Err);
36 if (
auto Err = createNormalizedSymbols())
37 return std::move(Err);
39 if (
auto Err = graphifyRegularSymbols())
40 return std::move(Err);
42 if (
auto Err = graphifySectionsWithCustomParsers())
43 return std::move(Err);
46 return std::move(Err);
53 std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT,
59 getEndianness(Obj),
std::
move(GetEdgeKindName))) {
67 "Custom parser for this section already exists");
68 CustomSectionParserFunctions[
SectionName] = std::move(Parser);
93 strcmp(NSec.
SegName,
"__DWARF") == 0);
118Section &MachOLinkGraphBuilder::getCommonSection() {
122 return *CommonSection;
125Error MachOLinkGraphBuilder::createNormalizedSections() {
131 for (
auto &SecRef : Obj.
sections()) {
132 NormalizedSection NSec;
138 const MachO::section_64 &Sec64 =
141 memcpy(&NSec.SectName, &Sec64.sectname, 16);
142 NSec.SectName[16] =
'\0';
143 memcpy(&NSec.SegName, Sec64.segname, 16);
144 NSec.SegName[16] =
'\0';
146 NSec.Address = orc::ExecutorAddr(Sec64.addr);
147 NSec.Size = Sec64.size;
148 NSec.Alignment = 1ULL << Sec64.align;
149 NSec.Flags = Sec64.flags;
150 DataOffset = Sec64.offset;
152 const MachO::section &Sec32 = Obj.
getSection(SecRef.getRawDataRefImpl());
154 memcpy(&NSec.SectName, &Sec32.sectname, 16);
155 NSec.SectName[16] =
'\0';
156 memcpy(&NSec.SegName, Sec32.segname, 16);
157 NSec.SegName[16] =
'\0';
159 NSec.Address = orc::ExecutorAddr(Sec32.addr);
160 NSec.Size = Sec32.size;
161 NSec.Alignment = 1ULL << Sec32.align;
162 NSec.Flags = Sec32.flags;
163 DataOffset = Sec32.offset;
167 dbgs() <<
" " << NSec.SegName <<
"," << NSec.SectName <<
": "
168 <<
formatv(
"{0:x16}", NSec.Address) <<
" -- "
169 <<
formatv(
"{0:x16}", NSec.Address + NSec.Size)
170 <<
", align: " << NSec.Alignment <<
", index: " << SecIndex
177 return make_error<JITLinkError>(
178 "Section data extends past end of file");
192 auto FullyQualifiedName =
193 G->allocateContent(StringRef(NSec.SegName) +
"," + NSec.SectName);
194 NSec.GraphSection = &G->createSection(
195 StringRef(FullyQualifiedName.data(), FullyQualifiedName.size()), Prot);
201 IndexToSection.insert(std::make_pair(SecIndex, std::move(NSec)));
204 std::vector<NormalizedSection *> Sections;
205 Sections.reserve(IndexToSection.size());
206 for (
auto &KV : IndexToSection)
207 Sections.push_back(&KV.second);
211 if (Sections.empty())
215 [](
const NormalizedSection *
LHS,
const NormalizedSection *
RHS) {
217 if (
LHS->Address !=
RHS->Address)
218 return LHS->Address <
RHS->Address;
219 return LHS->Size <
RHS->Size;
222 for (
unsigned I = 0,
E = Sections.size() - 1;
I !=
E; ++
I) {
223 auto &Cur = *Sections[
I];
224 auto &Next = *Sections[
I + 1];
225 if (Next.Address < Cur.Address + Cur.Size)
226 return make_error<JITLinkError>(
227 "Address range for section " +
228 formatv(
"\"{0}/{1}\" [ {2:x16} -- {3:x16} ] ", Cur.SegName,
229 Cur.SectName, Cur.Address, Cur.Address + Cur.Size) +
230 "overlaps section \"" + Next.SegName +
"/" + Next.SectName +
"\"" +
231 formatv(
"\"{0}/{1}\" [ {2:x16} -- {3:x16} ] ", Next.SegName,
232 Next.SectName, Next.Address, Next.Address + Next.Size));
238Error MachOLinkGraphBuilder::createNormalizedSymbols() {
241 for (
auto &SymRef : Obj.
symbols()) {
243 unsigned SymbolIndex = Obj.
getSymbolIndex(SymRef.getRawDataRefImpl());
251 const MachO::nlist_64 &NL64 =
253 Value = NL64.n_value;
259 const MachO::nlist &NL32 =
261 Value = NL32.n_value;
273 std::optional<StringRef>
Name;
275 if (
auto NameOrErr = SymRef.getName())
278 return NameOrErr.takeError();
280 return make_error<JITLinkError>(
"Symbol at index " +
282 " has no name (string table index 0), "
283 "but N_EXT bit is set");
288 dbgs() <<
"<anonymous symbol>";
291 dbgs() <<
": value = " <<
formatv(
"{0:x16}", Value)
292 <<
", type = " <<
formatv(
"{0:x2}", Type)
293 <<
", desc = " <<
formatv(
"{0:x4}",
Desc) <<
", sect = ";
295 dbgs() <<
static_cast<unsigned>(Sect - 1);
305 return NSec.takeError();
307 if (orc::ExecutorAddr(Value) < NSec->Address ||
308 orc::ExecutorAddr(Value) > NSec->Address + NSec->Size)
309 return make_error<JITLinkError>(
"Address " +
formatv(
"{0:x}", Value) +
310 " for symbol " + *
Name +
311 " does not fall within section");
313 if (!NSec->GraphSection) {
315 dbgs() <<
" Skipping: Symbol is in section " << NSec->SegName <<
"/"
317 <<
" which has no associated graph section.\n";
330void MachOLinkGraphBuilder::addSectionStartSymAndBlock(
331 unsigned SecIndex, Section &GraphSec, orc::ExecutorAddr
Address,
335 Data ? G->createContentBlock(GraphSec, ArrayRef<char>(
Data,
Size),
337 : G->createZeroFillBlock(GraphSec,
Size,
Address, Alignment, 0);
338 auto &
Sym = G->addAnonymousSymbol(
B, 0,
Size,
false, IsLive);
339 auto SecI = IndexToSection.find(SecIndex);
340 assert(SecI != IndexToSection.end() &&
"SecIndex invalid");
341 auto &NSec = SecI->second;
342 assert(!NSec.CanonicalSymbols.count(
Sym.getAddress()) &&
343 "Anonymous block start symbol clashes with existing symbol address");
344 NSec.CanonicalSymbols[
Sym.getAddress()] = &
Sym;
347Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
352 std::vector<std::vector<NormalizedSymbol *>> SecIndexToSymbols;
353 SecIndexToSymbols.resize(256);
357 for (
auto &KV : IndexToSymbol) {
358 auto &NSym = *KV.second;
364 return make_error<JITLinkError>(
"Anonymous common symbol at index " +
366 NSym.GraphSymbol = &G->addDefinedSymbol(
367 G->createZeroFillBlock(getCommonSection(),
375 return make_error<JITLinkError>(
"Anonymous external symbol at "
378 NSym.GraphSymbol = &G->addExternalSymbol(
384 return make_error<JITLinkError>(
"Anonymous absolute symbol at index " +
386 NSym.GraphSymbol = &G->addAbsoluteSymbol(
391 SecIndexToSymbols[NSym.Sect - 1].push_back(&NSym);
394 return make_error<JITLinkError>(
395 "Unupported N_PBUD symbol " +
396 (NSym.Name ? (
"\"" + *NSym.Name +
"\"") : Twine(
"<anon>")) +
397 " at index " + Twine(KV.first));
399 return make_error<JITLinkError>(
400 "Unupported N_INDR symbol " +
401 (NSym.Name ? (
"\"" + *NSym.Name +
"\"") : Twine(
"<anon>")) +
402 " at index " + Twine(KV.first));
404 return make_error<JITLinkError>(
405 "Unrecognized symbol type " + Twine(NSym.Type &
MachO::N_TYPE) +
407 (NSym.Name ? (
"\"" + *NSym.Name +
"\"") : Twine(
"<anon>")) +
408 " at index " + Twine(KV.first));
414 for (
auto &KV : IndexToSection) {
415 auto SecIndex = KV.first;
416 auto &NSec = KV.second;
418 if (!NSec.GraphSection) {
420 dbgs() <<
" " << NSec.SegName <<
"/" << NSec.SectName
421 <<
" has no graph section. Skipping.\n";
427 if (CustomSectionParserFunctions.
count(NSec.GraphSection->getName())) {
429 dbgs() <<
" Skipping section " << NSec.GraphSection->getName()
430 <<
" as it has a custom parser.\n";
435 if (
auto Err = graphifyCStringSection(
436 NSec, std::move(SecIndexToSymbols[SecIndex])))
441 dbgs() <<
" Graphifying regular section "
442 << NSec.GraphSection->getName() <<
"...\n";
448 auto &SecNSymStack = SecIndexToSymbols[SecIndex];
452 if (SecNSymStack.empty()) {
455 dbgs() <<
" Section non-empty, but contains no symbols. "
456 "Creating anonymous block to cover "
457 <<
formatv(
"{0:x16}", NSec.Address) <<
" -- "
458 <<
formatv(
"{0:x16}", NSec.Address + NSec.Size) <<
"\n";
460 addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,
461 NSec.Data, NSec.Size, NSec.Alignment,
462 SectionIsNoDeadStrip);
465 dbgs() <<
" Section empty and contains no symbols. Skipping.\n";
474 const NormalizedSymbol *
RHS) {
475 if (
LHS->Value !=
RHS->Value)
476 return LHS->Value >
RHS->Value;
481 return LHS->Name <
RHS->Name;
485 if (!SecNSymStack.empty() &&
isAltEntry(*SecNSymStack.back()))
486 return make_error<JITLinkError>(
487 "First symbol in " + NSec.GraphSection->getName() +
" is alt-entry");
491 if (orc::ExecutorAddr(SecNSymStack.back()->Value) != NSec.Address) {
493 orc::ExecutorAddr(SecNSymStack.back()->Value) - NSec.Address;
495 dbgs() <<
" Section start not covered by symbol. "
496 <<
"Creating anonymous block to cover [ " << NSec.Address
497 <<
" -- " << (NSec.Address + AnonBlockSize) <<
" ]\n";
499 addSectionStartSymAndBlock(SecIndex, *NSec.GraphSection, NSec.Address,
500 NSec.Data, AnonBlockSize, NSec.Alignment,
501 SectionIsNoDeadStrip);
512 while (!SecNSymStack.empty()) {
513 SmallVector<NormalizedSymbol *, 8> BlockSyms;
517 BlockSyms.push_back(SecNSymStack.back());
518 SecNSymStack.pop_back();
519 while (!SecNSymStack.empty() &&
521 SecNSymStack.back()->Value == BlockSyms.back()->Value ||
522 !SubsectionsViaSymbols)) {
523 BlockSyms.push_back(SecNSymStack.back());
524 SecNSymStack.pop_back();
528 auto BlockStart = orc::ExecutorAddr(BlockSyms.front()->Value);
529 orc::ExecutorAddr BlockEnd =
530 SecNSymStack.empty() ? NSec.Address + NSec.Size
531 : orc::ExecutorAddr(SecNSymStack.back()->Value);
536 dbgs() <<
" Creating block for " <<
formatv(
"{0:x16}", BlockStart)
537 <<
" -- " <<
formatv(
"{0:x16}", BlockEnd) <<
": "
538 << NSec.GraphSection->getName() <<
" + "
539 <<
formatv(
"{0:x16}", BlockOffset) <<
" with "
540 << BlockSyms.size() <<
" symbol(s)...\n";
545 ? G->createContentBlock(
547 ArrayRef<char>(NSec.Data + BlockOffset,
BlockSize),
548 BlockStart, NSec.Alignment, BlockStart % NSec.Alignment)
549 : G->createZeroFillBlock(*NSec.GraphSection,
BlockSize,
550 BlockStart, NSec.Alignment,
551 BlockStart % NSec.Alignment);
553 std::optional<orc::ExecutorAddr> LastCanonicalAddr;
554 auto SymEnd = BlockEnd;
555 while (!BlockSyms.empty()) {
556 auto &NSym = *BlockSyms.back();
557 BlockSyms.pop_back();
562 auto &
Sym = createStandardGraphSymbol(
563 NSym,
B, SymEnd - orc::ExecutorAddr(NSym.Value), SectionIsText,
564 SymLive, LastCanonicalAddr != orc::ExecutorAddr(NSym.Value));
566 if (LastCanonicalAddr !=
Sym.getAddress()) {
567 if (LastCanonicalAddr)
568 SymEnd = *LastCanonicalAddr;
569 LastCanonicalAddr =
Sym.getAddress();
578Symbol &MachOLinkGraphBuilder::createStandardGraphSymbol(NormalizedSymbol &NSym,
579 Block &
B,
size_t Size,
585 dbgs() <<
" " <<
formatv(
"{0:x16}", NSym.Value) <<
" -- "
588 dbgs() <<
"<anonymous symbol>";
590 dbgs() << *NSym.Name;
594 dbgs() <<
" [no-dead-strip]";
596 dbgs() <<
" [non-canonical]";
600 auto SymOffset = orc::ExecutorAddr(NSym.Value) -
B.getAddress();
603 ? G->addDefinedSymbol(
B, SymOffset, *NSym.Name,
Size, NSym.L, NSym.S,
604 IsText, IsNoDeadStrip)
605 : G->addAnonymousSymbol(
B, SymOffset,
Size, IsText, IsNoDeadStrip);
606 NSym.GraphSymbol = &
Sym;
614Error MachOLinkGraphBuilder::graphifySectionsWithCustomParsers() {
616 for (
auto &KV : IndexToSection) {
617 auto &NSec = KV.second;
620 if (!NSec.GraphSection)
623 auto HI = CustomSectionParserFunctions.
find(NSec.GraphSection->getName());
624 if (HI != CustomSectionParserFunctions.
end()) {
625 auto &Parse =
HI->second;
626 if (
auto Err = Parse(NSec))
634Error MachOLinkGraphBuilder::graphifyCStringSection(
635 NormalizedSection &NSec, std::vector<NormalizedSymbol *> NSyms) {
636 assert(NSec.GraphSection &&
"C string literal section missing graph section");
637 assert(NSec.Data &&
"C string literal section has no data");
640 dbgs() <<
" Graphifying C-string literal section "
641 << NSec.GraphSection->getName() <<
"\n";
644 if (NSec.Data[NSec.Size - 1] !=
'\0')
645 return make_error<JITLinkError>(
"C string literal section " +
646 NSec.GraphSection->getName() +
647 " does not end with null terminator");
651 [](
const NormalizedSymbol *
LHS,
const NormalizedSymbol *
RHS) {
652 if (
LHS->Value !=
RHS->Value)
653 return LHS->Value >
RHS->Value;
661 return *LHS->Name > *RHS->Name;
671 for (
size_t I = 0;
I != NSec.Size; ++
I) {
672 if (NSec.Data[
I] ==
'\0') {
675 auto &
B = G->createContentBlock(*NSec.GraphSection,
676 {NSec.Data + BlockStart, BlockSize},
677 NSec.Address + BlockStart, NSec.Alignment,
678 BlockStart % NSec.Alignment);
681 dbgs() <<
" Created block " <<
B.getRange()
682 <<
", align = " <<
B.getAlignment()
683 <<
", align-ofs = " <<
B.getAlignmentOffset() <<
" for \"";
684 for (
size_t J = 0; J != std::min(
B.getSize(),
size_t(16)); ++J)
685 switch (
B.getContent()[J]) {
687 case '\n':
dbgs() <<
"\\n";
break;
688 case '\t':
dbgs() <<
"\\t";
break;
689 default:
dbgs() <<
B.getContent()[J];
break;
691 if (
B.getSize() > 16)
698 orc::ExecutorAddr(NSyms.back()->Value) !=
B.getAddress()) {
699 auto &S = G->addAnonymousSymbol(
B, 0,
BlockSize,
false,
false);
700 setCanonicalSymbol(NSec, S);
702 dbgs() <<
" Adding symbol for c-string block " <<
B.getRange()
703 <<
": <anonymous symbol> at offset 0\n";
708 auto LastCanonicalAddr =
B.getAddress() +
BlockSize;
709 while (!NSyms.empty() && orc::ExecutorAddr(NSyms.back()->Value) <
711 auto &NSym = *NSyms.back();
712 size_t SymSize = (
B.getAddress() +
BlockSize) -
713 orc::ExecutorAddr(NSyms.back()->Value);
717 bool IsCanonical =
false;
718 if (LastCanonicalAddr != orc::ExecutorAddr(NSym.Value)) {
720 LastCanonicalAddr = orc::ExecutorAddr(NSym.Value);
723 auto &
Sym = createStandardGraphSymbol(NSym,
B, SymSize, SectionIsText,
724 SymLive, IsCanonical);
727 dbgs() <<
" Adding symbol for c-string block " <<
B.getRange()
729 << (
Sym.hasName() ? *
Sym.getName() :
"<anonymous symbol>")
730 <<
" at offset " <<
formatv(
"{0:x}",
Sym.getOffset()) <<
"\n";
741 [](Block *
B) { return isCStringBlock(*B); }) &&
742 "All blocks in section should hold single c-strings");
748 auto *CUSec =
G.findSectionByName(CompactUnwindSectionName);
752 if (!
G.getTargetTriple().isOSBinFormatMachO())
753 return make_error<JITLinkError>(
754 "Error linking " +
G.getName() +
755 ": compact unwind splitting not supported on non-macho target " +
756 G.getTargetTriple().str());
758 unsigned CURecordSize = 0;
759 unsigned PersonalityEdgeOffset = 0;
760 unsigned LSDAEdgeOffset = 0;
761 switch (
G.getTargetTriple().getArch()) {
771 PersonalityEdgeOffset = 16;
775 return make_error<JITLinkError>(
776 "Error linking " +
G.getName() +
777 ": compact unwind splitting not supported on " +
778 G.getTargetTriple().getArchName());
781 std::vector<Block *> OriginalBlocks(CUSec->blocks().begin(),
782 CUSec->blocks().end());
784 dbgs() <<
"In " <<
G.getName() <<
" splitting compact unwind section "
785 << CompactUnwindSectionName <<
" containing "
786 << OriginalBlocks.
size() <<
" initial blocks...\n";
789 while (!OriginalBlocks.empty()) {
790 auto *
B = OriginalBlocks.back();
791 OriginalBlocks.pop_back();
793 if (
B->getSize() == 0) {
795 dbgs() <<
" Skipping empty block at "
796 <<
formatv(
"{0:x16}",
B->getAddress()) <<
"\n";
801 unsigned NumBlocks =
B->getSize() / CURecordSize;
804 dbgs() <<
" Splitting block at " <<
formatv(
"{0:x16}",
B->getAddress())
805 <<
" into " << NumBlocks <<
" compact unwind record(s)\n";
808 if (
B->getSize() % CURecordSize)
809 return make_error<JITLinkError>(
810 "Error splitting compact unwind record in " +
G.getName() +
811 ": block at " +
formatv(
"{0:x}",
B->getAddress()) +
" has size " +
813 " (not a multiple of CU record size of " +
814 formatv(
"{0:x}", CURecordSize) +
")");
818 return Idx * CURecordSize;
821 for (
auto *CURec :
Blocks) {
822 bool AddedKeepAlive =
false;
824 for (
auto &
E : CURec->edges()) {
825 if (
E.getOffset() == 0) {
827 dbgs() <<
" Updating compact unwind record at "
828 << CURec->getAddress() <<
" to point to "
829 << (
E.getTarget().hasName() ? *
E.getTarget().getName()
831 <<
" (at " <<
E.getTarget().getAddress() <<
")\n";
834 if (
E.getTarget().isExternal())
835 return make_error<JITLinkError>(
836 "Error adding keep-alive edge for compact unwind record at " +
837 formatv(
"{0:x}", CURec->getAddress()) +
": target " +
838 *
E.getTarget().getName() +
" is an external symbol");
839 auto &TgtBlock =
E.getTarget().getBlock();
841 G.addAnonymousSymbol(*CURec, 0, CURecordSize,
false,
false);
843 AddedKeepAlive =
true;
844 }
else if (
E.getOffset() != PersonalityEdgeOffset &&
845 E.getOffset() != LSDAEdgeOffset)
846 return make_error<JITLinkError>(
847 "Unexpected edge at offset " +
formatv(
"{0:x}",
E.getOffset()) +
848 " in compact unwind record at " +
849 formatv(
"{0:x}", CURec->getAddress()));
853 return make_error<JITLinkError>(
854 "Error adding keep-alive edge for compact unwind record at " +
855 formatv(
"{0:x}", CURec->getAddress()) +
856 ": no outgoing target edge at offset 0");
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static const char * CommonSectionName
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static std::optional< TypeSize > getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI, const Function *F)
DenseMap< Block *, BlockRelaxAux > Blocks
static const char * CommonSectionName
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
iterator find(StringRef Key)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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.
Error operator()(LinkGraph &G)
const char *(*)(Edge::Kind) GetEdgeKindNameFunction
static bool isDebugSection(const NormalizedSection &NSec)
void addCustomSectionParser(StringRef SectionName, SectionParserFunction Parse)
virtual ~MachOLinkGraphBuilder()
virtual Error addRelocations()=0
std::function< Error(NormalizedSection &S)> SectionParserFunction
static Scope getScope(StringRef Name, uint8_t Type)
static bool isZeroFillSection(const NormalizedSection &NSec)
Expected< std::unique_ptr< LinkGraph > > buildGraph()
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)
NormalizedSymbol & createNormalizedSymbol(ArgTs &&... Args)
Create a symbol.
static Linkage getLinkage(uint16_t Desc)
static bool isAltEntry(const NormalizedSymbol &NSym)
Expected< NormalizedSection & > findSectionByIndex(unsigned Index)
Try to get the section at the given index.
StringRef getData() const
bool isLittleEndian() const
const MachO::mach_header_64 & getHeader64() const
Expected< SectionRef > getSection(unsigned SectionIndex) const
uint64_t getSymbolIndex(DataRefImpl Symb) const
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
MachO::section_64 getSection64(DataRefImpl DRI) const
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
bool is64Bit() const override
uint64_t getSectionIndex(DataRefImpl Sec) const override
section_iterator_range sections() const
symbol_iterator_range symbols() const
@ 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.
@ 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.
uint8_t GET_COMM_ALIGN(uint16_t n_desc)
@ MH_SUBSECTIONS_VIA_SYMBOLS
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...
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
MemProt
Describes Read/Write/Exec permissions for memory.
uint64_t ExecutorAddrDiff
@ NoAlloc
NoAlloc memory should not be allocated by the JITLinkMemoryManager at all.
NodeAddr< BlockNode * > Block
This is an optimization pass for GlobalISel generic memory operations.
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 map_range(ContainerTy &&C, FuncTy F)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Implement std::hash so that hash_code can be used in STL containers.
Description of the encoding of one expression Op.