16#define DEBUG_TYPE "jitlink" 
   30    std::shared_ptr<orc::SymbolStringPool> SSP, 
Triple TT,
 
   39    dbgs() << 
"Created COFFLinkGraphBuilder for \"" << Obj.getFileName()
 
 
   61bool COFFLinkGraphBuilder::isComdatSection(
 
   62    const object::coff_section *Section) {
 
   66Section &COFFLinkGraphBuilder::getCommonSection() {
 
   70  return *CommonSection;
 
   74  if (!Obj.isRelocatableObject())
 
   78    return std::move(Err);
 
   81    return std::move(Err);
 
   84    return std::move(Err);
 
 
   90COFFLinkGraphBuilder::getCOFFSectionName(COFFSectionIndex SectionIndex,
 
   93  switch (SectionIndex) {
 
  109      return *SecNameOrErr;
 
  118  GraphBlocks.resize(Obj.getNumberOfSections() + 1);
 
  121       SecIndex <= static_cast<COFFSectionIndex>(Obj.getNumberOfSections());
 
  142             << 
"Creating section for \"" << 
SectionName << 
"\"\n";
 
  155    auto *GraphSec = G->findSectionByName(
SectionName);
 
  161    if (GraphSec->getMemProt() != Prot)
 
  166      B = &G->createZeroFillBlock(
 
  167          *GraphSec, getSectionSize(Obj, *Sec),
 
  169          (*Sec)->getAlignment(), 0);
 
  172      if (
auto Err = Obj.getSectionContents(*Sec, 
Data))
 
  176          reinterpret_cast<const char *
>(
Data.data()), 
Data.size());
 
  179        if (
auto Err = handleDirectiveSection(
 
  180                StringRef(CharData.data(), CharData.size())))
 
  183      B = &G->createContentBlock(
 
  185          (*Sec)->getAlignment(), 0);
 
 
  197  SymbolSets.resize(Obj.getNumberOfSections() + 1);
 
  198  PendingComdatExports.resize(Obj.getNumberOfSections() + 1);
 
  199  GraphSymbols.resize(Obj.getNumberOfSymbols());
 
  202       SymIndex < static_cast<COFFSymbolIndex>(Obj.getNumberOfSymbols());
 
  210      SymbolName = *SymNameOrErr;
 
  216      auto SecOrErr = Obj.getSection(SectionIndex);
 
  219            "Invalid COFF section number:" + 
formatv(
"{0:d}: ", SectionIndex) +
 
  220            " (" + 
toString(SecOrErr.takeError()) + 
")");
 
  223    auto InternedSymbolName = G->intern(std::move(SymbolName));
 
  227    if (Sym->isFileRecord())
 
  229        dbgs() << 
"    " << SymIndex << 
": Skipping FileRecord symbol \"" 
  230               << InternedSymbolName << 
"\" in " 
  231               << getCOFFSectionName(SectionIndex, Sec, *Sym)
 
  232               << 
" (index: " << SectionIndex << 
") \n";
 
  234    else if (Sym->isUndefined()) {
 
  235      GSym = createExternalSymbol(SymIndex, InternedSymbolName, *Sym, Sec);
 
  236    } 
else if (Sym->isWeakExternal()) {
 
  239      uint32_t Characteristics = WeakExternal->Characteristics;
 
  240      WeakExternalRequests.push_back(
 
  241          {SymIndex, TagIndex, Characteristics, SymbolName});
 
  244          createDefinedSymbol(SymIndex, InternedSymbolName, *Sym, Sec);
 
  250          dbgs() << 
"    " << SymIndex
 
  251                 << 
": Creating defined graph symbol for COFF symbol \"" 
  252                 << InternedSymbolName << 
"\" in " 
  253                 << getCOFFSectionName(SectionIndex, Sec, *Sym)
 
  254                 << 
" (index: " << SectionIndex << 
") \n";
 
  255          dbgs() << 
"      " << *GSym << 
"\n";
 
  263    SymIndex += Sym->getNumberOfAuxSymbols();
 
  266  if (
auto Err = flushWeakAliasRequests())
 
  269  if (
auto Err = handleAlternateNames())
 
  272  if (
auto Err = calculateImplicitSizeOfSymbols())
 
 
  278Error COFFLinkGraphBuilder::handleDirectiveSection(
StringRef Str) {
 
  279  auto Parsed = DirectiveParser.
parse(Str);
 
  281    return Parsed.takeError();
 
  282  for (
auto *Arg : *Parsed) {
 
  284    switch (Arg->getOption().getID()) {
 
  285    case COFF_OPT_alternatename: {
 
  287      std::tie(From, To) = S.
split(
'=');
 
  290            "Invalid COFF /alternatename directive");
 
  291      AlternateNames[
G->intern(From)] = 
G->intern(To);
 
  294    case COFF_OPT_incl: {
 
  295      auto Symbol = &
G->addExternalSymbol(S, 0, 
false);
 
  296      Symbol->setLive(
true);
 
  297      ExternalSymbols[Symbol->getName()] = Symbol;
 
  300    case COFF_OPT_export:
 
  304        dbgs() << 
"Unknown coff directive: " << Arg->getSpelling() << 
"\n";
 
  313Error COFFLinkGraphBuilder::flushWeakAliasRequests() {
 
  315  for (
auto &WeakExternal : WeakExternalRequests) {
 
  317      Expected<object::COFFSymbolRef> AliasSymbol =
 
  318          Obj.getSymbol(WeakExternal.Alias);
 
  320        return AliasSymbol.takeError();
 
  329      auto NewSymbol = createAliasSymbol(G->intern(WeakExternal.SymbolName),
 
  332        return NewSymbol.takeError();
 
  333      setGraphSymbol(AliasSymbol->getSectionNumber(), WeakExternal.Alias,
 
  336        dbgs() << 
"    " << WeakExternal.Alias
 
  337               << 
": Creating weak external symbol for COFF symbol \"" 
  338               << WeakExternal.SymbolName << 
"\" in section " 
  339               << AliasSymbol->getSectionNumber() << 
"\n";
 
  340        dbgs() << 
"      " << **NewSymbol << 
"\n";
 
  344                                      "symbol not found for symbol " +
 
  345                                      formatv(
"{0:d}", WeakExternal.Alias));
 
  350Error COFFLinkGraphBuilder::handleAlternateNames() {
 
  351  for (
auto &KeyValue : AlternateNames) {
 
  352    auto DefinedSymbolName = KeyValue.second;
 
  353    auto ExternalSymbolsName = KeyValue.first;
 
  354    if (DefinedSymbols.count(DefinedSymbolName) &&
 
  355        ExternalSymbols.count(ExternalSymbolsName)) {
 
  356      auto *
Target = DefinedSymbols[DefinedSymbolName];
 
  357      auto *Alias = ExternalSymbols[ExternalSymbolsName];
 
  358      G->makeDefined(*Alias, 
Target->getBlock(), 
Target->getOffset(),
 
  365Symbol *COFFLinkGraphBuilder::createExternalSymbol(
 
  366    COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName,
 
  367    object::COFFSymbolRef 
Symbol, 
const object::coff_section *
Section) {
 
  368  llvm::jitlink::Symbol *Sym = 
nullptr;
 
  369  if (
auto It = ExternalSymbols.find(SymbolName); It == ExternalSymbols.end()) {
 
  370    Sym = &G->addExternalSymbol(*SymbolName, 
Symbol.getValue(), 
false);
 
  371    ExternalSymbols[Sym->
getName()] = Sym;
 
  377    dbgs() << 
"    " << SymIndex
 
  378           << 
": Creating external graph symbol for COFF symbol \"" 
  380           << getCOFFSectionName(
Symbol.getSectionNumber(), Section, Symbol)
 
  381           << 
" (index: " << 
Symbol.getSectionNumber() << 
") \n";
 
  387COFFLinkGraphBuilder::createAliasSymbol(orc::SymbolStringPtr SymbolName,
 
  389  if (!
Target.isDefined()) {
 
  392                                    "symbol as alternative not supported.");
 
  394  return &G->addDefinedSymbol(
Target.getBlock(), 
Target.getOffset(), SymbolName,
 
  406Error COFFLinkGraphBuilder::calculateImplicitSizeOfSymbols() {
 
  408       SecIndex <= static_cast<COFFSectionIndex>(Obj.getNumberOfSections());
 
  410    auto &SymbolSet = SymbolSets[SecIndex];
 
  411    if (SymbolSet.empty())
 
  417    for (
auto It = SymbolSet.rbegin(); It != SymbolSet.rend(); It++) {
 
  419      jitlink::Symbol *
Symbol = It->second;
 
  422      if (
Symbol->getOffset() == LastOffset)
 
  425        CandSize = LastOffset - 
Offset;
 
  429          dbgs() << 
"  Overlapping symbol range generated for the following " 
  432                 << 
"    " << *
Symbol << 
"\n";
 
  434      (void)LastDifferentOffset;
 
  436        LastDifferentOffset = 
Offset;
 
  451          dbgs() << 
"  Empty implicit symbol size generated for the following " 
  454                 << 
"    " << *
Symbol << 
"\n";
 
  457      Symbol->setSize(CandSize);
 
  463Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
 
  464    COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName,
 
  465    object::COFFSymbolRef 
Symbol, 
const object::coff_section *
Section) {
 
  469    return &G->addDefinedSymbol(
 
  470        G->createZeroFillBlock(getCommonSection(), 
Symbol.getValue(),
 
  471                               orc::ExecutorAddr(), 
Symbol.getValue(), 0),
 
  477    return &G->addAbsoluteSymbol(SymbolName,
 
  478                                 orc::ExecutorAddr(
Symbol.getValue()), 0,
 
  483        "Reserved section number used in regular symbol " +
 
  489      dbgs() << 
"    " << SymIndex
 
  490             << 
": Skipping graph symbol since section was not created for " 
  498  if (
Symbol.isExternal()) {
 
  500    if (!isComdatSection(Section)) {
 
  501      auto GSym = &G->addDefinedSymbol(
 
  507      if (!PendingComdatExports[
Symbol.getSectionNumber()])
 
  511      return exportCOMDATSymbol(SymIndex, SymbolName, Symbol);
 
  517    const object::coff_aux_section_definition *Definition =
 
  518        Symbol.getSectionDefinition();
 
  519    if (!Definition || !isComdatSection(Section)) {
 
  521      return &G->addDefinedSymbol(
 
  527      auto GSym = &G->addDefinedSymbol(
 
  533    if (PendingComdatExports[
Symbol.getSectionNumber()])
 
  535          "COMDAT export request already exists before symbol " +
 
  537    return createCOMDATExportRequest(SymIndex, Symbol, Definition);
 
  541                                  " in symbol " + 
formatv(
"{0:d}", SymIndex));
 
  558Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest(
 
  559    COFFSymbolIndex SymIndex, object::COFFSymbolRef 
Symbol,
 
  560    const object::coff_aux_section_definition *Definition) {
 
  562  switch (Definition->Selection) {
 
  582      dbgs() << 
"    " << SymIndex
 
  583             << 
": Partially supported IMAGE_COMDAT_SELECT_LARGEST was used" 
  585             << 
Symbol.getSectionNumber() << 
" (size: " << Definition->Length
 
  594        "IMAGE_COMDAT_SELECT_NEWEST is not supported.");
 
  598                                    formatv(
"{0:d}", Definition->Selection));
 
  601  PendingComdatExports[
Symbol.getSectionNumber()] = {SymIndex, 
L,
 
  608COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
 
  609                                         orc::SymbolStringPtr SymbolName,
 
  610                                         object::COFFSymbolRef 
Symbol) {
 
  612  auto &PendingComdatExport = PendingComdatExports[
Symbol.getSectionNumber()];
 
  616  auto GSym = &G->addDefinedSymbol(
 
  617      *
B, 
Symbol.getValue(), SymbolName, 0, PendingComdatExport->Linkage,
 
  621    dbgs() << 
"    " << SymIndex
 
  622           << 
": Exporting COMDAT graph symbol for COFF symbol \"" << 
SymbolName 
  623           << 
"\" in section " << 
Symbol.getSectionNumber() << 
"\n";
 
  624    dbgs() << 
"      " << *GSym << 
"\n";
 
  629  PendingComdatExport = std::nullopt;
 
  637  auto IBN = 
G.intern(ImageBaseName);
 
  638  ImageBase = 
G.findExternalSymbolByName(IBN);
 
  641  ImageBase = 
G.findAbsoluteSymbolByName(IBN);
 
  644  ImageBase = 
G.findDefinedSymbolByName(IBN);
 
 
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)
 
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
 
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.
 
Error takeError()
Take ownership of the stored error.
 
StringRef - Represent a constant reference to a string, i.e.
 
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
 
constexpr bool empty() const
empty - Check if the string is empty.
 
Manages the enabling and disabling of subtarget specific features.
 
Triple - Helper class for working with autoconf configuration names.
 
An Addressable with content and edges.
 
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
 
Expected< opt::InputArgList > parse(StringRef Str)
 
Expected< std::unique_ptr< LinkGraph > > buildGraph()
 
virtual Error addRelocations()=0
 
Symbol * getGraphSymbol(COFFSymbolIndex SymIndex) const
 
COFFLinkGraphBuilder(const object::COFFObjectFile &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
 
virtual ~COFFLinkGraphBuilder()
 
Block * getGraphBlock(COFFSectionIndex SecIndex) const
 
void setGraphSymbol(COFFSectionIndex SecIndex, COFFSymbolIndex SymIndex, Symbol &Sym)
 
void setGraphBlock(COFFSectionIndex SecIndex, Block *B)
 
Symbol * operator()(LinkGraph &G)
 
const char *(*)(Edge::Kind) GetEdgeKindNameFunction
 
Represents an object file section.
 
const orc::SymbolStringPtr & getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
 
const dos_header * getDOSHeader() const
 
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
 
uint64_t getImageBase() const
 
uint32_t getValue() const
 
Represents an address in the executor process.
 
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
 
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
 
@ IMAGE_SYM_CLASS_LABEL
Label.
 
@ IMAGE_SYM_CLASS_STATIC
Static.
 
@ IMAGE_COMDAT_SELECT_NODUPLICATES
 
@ IMAGE_COMDAT_SELECT_LARGEST
 
@ IMAGE_COMDAT_SELECT_NEWEST
 
@ IMAGE_COMDAT_SELECT_SAME_SIZE
 
@ IMAGE_COMDAT_SELECT_ASSOCIATIVE
 
@ IMAGE_COMDAT_SELECT_EXACT_MATCH
 
@ IMAGE_COMDAT_SELECT_ANY
 
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
 
bool isReservedSectionNumber(int32_t SectionNumber)
 
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
 
static Triple createTripleWithCOFFFormat(Triple T)
 
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.
 
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
 
FunctionAddr VTableAddr uintptr_t uintptr_t Data
 
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
 
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.
 
support::ulittle32_t VirtualSize
 
support::ulittle32_t SizeOfRawData