Skip to content

Commit

Permalink
[ORC] Move ORC-specific object format details into OrcShared.
Browse files Browse the repository at this point in the history
This allows these details to be shared with JITLink, which is allowed to
depend on the OrcShared library (but not on OrcJIT).
  • Loading branch information
lhames committed Feb 11, 2023
1 parent f00d101 commit 3d4e9d5
Show file tree
Hide file tree
Showing 16 changed files with 214 additions and 145 deletions.
4 changes: 0 additions & 4 deletions llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h
Expand Up @@ -67,10 +67,6 @@ class COFFPlatform : public Platform {
static ArrayRef<std::pair<const char *, const char *>>
standardRuntimeUtilityAliases();

static bool isInitializerSection(StringRef Name) {
return Name.startswith(".CRT");
}

static StringRef getSEHFrameSectionName() { return ".pdata"; }

private:
Expand Down
3 changes: 0 additions & 3 deletions llvm/include/llvm/ExecutionEngine/Orc/ELFNixPlatform.h
Expand Up @@ -119,9 +119,6 @@ class ELFNixPlatform : public Platform {
static ArrayRef<std::pair<const char *, const char *>>
standardRuntimeUtilityAliases();

/// Returns true if the given section name is an initializer section.
static bool isInitializerSection(StringRef SecName);

private:
// The ELFNixPlatformPlugin scans/modifies LinkGraphs to support ELF
// platform features including initializers, exceptions, TLV, and language
Expand Down
3 changes: 0 additions & 3 deletions llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
Expand Up @@ -103,9 +103,6 @@ class MachOPlatform : public Platform {
static ArrayRef<std::pair<const char *, const char *>>
standardRuntimeUtilityAliases();

/// Returns true if the given section name is an initializer section.
static bool isInitializerSection(StringRef SegName, StringRef SectName);

private:
// Data needed for bootstrap only.
struct BootstrapInfo {
Expand Down
2 changes: 0 additions & 2 deletions llvm/include/llvm/ExecutionEngine/Orc/ObjectFileInterface.h
Expand Up @@ -32,8 +32,6 @@ void addInitSymbol(MaterializationUnit::Interface &I, ExecutionSession &ES,
Expected<MaterializationUnit::Interface>
getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer);

bool hasInitializerSection(jitlink::LinkGraph &G);

} // End namespace orc
} // End namespace llvm

Expand Down
55 changes: 55 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h
@@ -0,0 +1,55 @@
//===------ ObjectFormats.h - Object format details for ORC -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// ORC-specific object format details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_OBJECTFORMATS_H
#define LLVM_EXECUTIONENGINE_ORC_SHARED_OBJECTFORMATS_H

#include "llvm/ADT/StringRef.h"

namespace llvm {
namespace orc {

// MachO section names.
extern StringRef MachODataCommonSectionName;
extern StringRef MachODataDataSectionName;
extern StringRef MachOEHFrameSectionName;
extern StringRef MachOCompactUnwindInfoSectionName;
extern StringRef MachOModInitFuncSectionName;
extern StringRef MachOObjCClassListSectionName;
extern StringRef MachOObjCImageInfoSectionName;
extern StringRef MachOObjCSelRefsSectionName;
extern StringRef MachOSwift5ProtoSectionName;
extern StringRef MachOSwift5ProtosSectionName;
extern StringRef MachOSwift5TypesSectionName;
extern StringRef MachOThreadBSSSectionName;
extern StringRef MachOThreadDataSectionName;
extern StringRef MachOThreadVarsSectionName;
extern StringRef MachOInitSectionNames[6];

// ELF section names.
extern StringRef ELFEHFrameSectionName;
extern StringRef ELFInitArrayFuncSectionName;

extern StringRef ELFThreadBSSSectionName;
extern StringRef ELFThreadDataSectionName;

bool isMachOInitializerSection(StringRef SegName, StringRef SecName);
bool isMachOInitializerSection(StringRef QualifiedName);

bool isELFInitializerSection(StringRef SecName);

bool isCOFFInitializerSection(StringRef Name);

} // end namespace orc
} // end namespace llvm

#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_MEMORYFLAGS_H
5 changes: 3 additions & 2 deletions llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp
Expand Up @@ -10,6 +10,7 @@
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
#include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h"

#include "llvm/Object/COFF.h"

Expand Down Expand Up @@ -850,7 +851,7 @@ Error COFFPlatform::COFFPlatformPlugin::preserveInitializerSections(
jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
JITLinkSymbolSet InitSectionSymbols;
for (auto &Sec : G.sections())
if (COFFPlatform::isInitializerSection(Sec.getName()))
if (isCOFFInitializerSection(Sec.getName()))
for (auto *B : Sec.blocks())
if (!B->edges_empty())
InitSectionSymbols.insert(
Expand Down Expand Up @@ -885,7 +886,7 @@ Error COFFPlatform::COFFPlatformPlugin::

// Collect static initializers
for (auto &S : G.sections())
if (COFFPlatform::isInitializerSection(S.getName()))
if (isCOFFInitializerSection(S.getName()))
for (auto *B : S.blocks()) {
if (B->edges_empty())
continue;
Expand Down
24 changes: 6 additions & 18 deletions llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
Expand Up @@ -14,6 +14,7 @@
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/Debug.h"
#include <optional>
Expand Down Expand Up @@ -96,12 +97,6 @@ class DSOHandleMaterializationUnit : public MaterializationUnit {
ELFNixPlatform &ENP;
};

StringRef EHFrameSectionName = ".eh_frame";
StringRef InitArrayFuncSectionName = ".init_array";

StringRef ThreadBSSSectionName = ".tbss";
StringRef ThreadDataSectionName = ".tdata";

} // end anonymous namespace

namespace llvm {
Expand Down Expand Up @@ -272,13 +267,6 @@ ELFNixPlatform::standardRuntimeUtilityAliases() {
StandardRuntimeUtilityAliases);
}

bool ELFNixPlatform::isInitializerSection(StringRef SecName) {
if (SecName.consume_front(InitArrayFuncSectionName) &&
(SecName.empty() || SecName[0] == '.'))
return true;
return false;
}

bool ELFNixPlatform::supportedTarget(const Triple &TT) {
switch (TT.getArch()) {
case Triple::x86_64:
Expand Down Expand Up @@ -724,7 +712,7 @@ void ELFNixPlatform::ELFNixPlatformPlugin::addEHAndTLVSupportPasses(
Config.PostFixupPasses.push_back([this](jitlink::LinkGraph &G) -> Error {
ELFPerObjectSectionsToRegister POSR;

if (auto *EHFrameSection = G.findSectionByName(EHFrameSectionName)) {
if (auto *EHFrameSection = G.findSectionByName(ELFEHFrameSectionName)) {
jitlink::SectionRange R(*EHFrameSection);
if (!R.empty())
POSR.EHFrameSection = {ExecutorAddr(R.getStart()),
Expand All @@ -734,10 +722,10 @@ void ELFNixPlatform::ELFNixPlatformPlugin::addEHAndTLVSupportPasses(
// Get a pointer to the thread data section if there is one. It will be used
// below.
jitlink::Section *ThreadDataSection =
G.findSectionByName(ThreadDataSectionName);
G.findSectionByName(ELFThreadDataSectionName);

// Handle thread BSS section if there is one.
if (auto *ThreadBSSSection = G.findSectionByName(ThreadBSSSectionName)) {
if (auto *ThreadBSSSection = G.findSectionByName(ELFThreadBSSSectionName)) {
// If there's already a thread data section in this graph then merge the
// thread BSS section content into it, otherwise just treat the thread
// BSS section as the thread data section.
Expand Down Expand Up @@ -781,7 +769,7 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::preserveInitSections(
JITLinkSymbolSet InitSectionSymbols;
for (auto &InitSection : G.sections()) {
// Skip non-init sections.
if (!isInitializerSection(InitSection.getName()))
if (!isELFInitializerSection(InitSection.getName()))
continue;

// Make a pass over live symbols in the section: those blocks are already
Expand Down Expand Up @@ -819,7 +807,7 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::registerInitSections(
LLVM_DEBUG({ dbgs() << "ELFNixPlatform::registerInitSections\n"; });

for (auto &Sec : G.sections()) {
if (isInitializerSection(Sec.getName())) {
if (isELFInitializerSection(Sec.getName())) {
InitSections.push_back(&Sec);
}
}
Expand Down
65 changes: 20 additions & 45 deletions llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
Expand Up @@ -13,6 +13,7 @@
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
#include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/Debug.h"
#include <optional>
Expand Down Expand Up @@ -246,25 +247,6 @@ class MachOPlatformCompleteBootstrapMaterializationUnit
ExecutorAddr MachOHeaderAddr;
};

StringRef DataCommonSectionName = "__DATA,__common";
StringRef DataDataSectionName = "__DATA,__data";
StringRef EHFrameSectionName = "__TEXT,__eh_frame";
StringRef CompactUnwindInfoSectionName = "__TEXT,__unwind_info";
StringRef ModInitFuncSectionName = "__DATA,__mod_init_func";
StringRef ObjCClassListSectionName = "__DATA,__objc_classlist";
StringRef ObjCImageInfoSectionName = "__DATA,__objc_image_info";
StringRef ObjCSelRefsSectionName = "__DATA,__objc_selrefs";
StringRef Swift5ProtoSectionName = "__TEXT,__swift5_proto";
StringRef Swift5ProtosSectionName = "__TEXT,__swift5_protos";
StringRef Swift5TypesSectionName = "__TEXT,__swift5_types";
StringRef ThreadBSSSectionName = "__DATA,__thread_bss";
StringRef ThreadDataSectionName = "__DATA,__thread_data";
StringRef ThreadVarsSectionName = "__DATA,__thread_vars";

StringRef InitSectionNames[] = {
ModInitFuncSectionName, ObjCSelRefsSectionName, ObjCClassListSectionName,
Swift5ProtosSectionName, Swift5ProtoSectionName, Swift5TypesSectionName};

} // end anonymous namespace

namespace llvm {
Expand Down Expand Up @@ -398,15 +380,6 @@ MachOPlatform::standardRuntimeUtilityAliases() {
StandardRuntimeUtilityAliases);
}

bool MachOPlatform::isInitializerSection(StringRef SegName,
StringRef SectName) {
for (auto &Name : InitSectionNames) {
if (Name.startswith(SegName) && Name.substr(7) == SectName)
return true;
}
return false;
}

bool MachOPlatform::supportedTarget(const Triple &TT) {
switch (TT.getArch()) {
case Triple::aarch64:
Expand Down Expand Up @@ -902,7 +875,7 @@ Error MachOPlatform::MachOPlatformPlugin::preserveInitSections(
jitlink::LinkGraph &G, MaterializationResponsibility &MR) {

JITLinkSymbolSet InitSectionSymbols;
for (auto &InitSectionName : InitSectionNames) {
for (auto &InitSectionName : MachOInitSectionNames) {
// Skip non-init sections.
auto *InitSection = G.findSectionByName(InitSectionName);
if (!InitSection)
Expand Down Expand Up @@ -944,22 +917,22 @@ Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
// OR
// (2) We already have a recorded __objc_imageinfo for this JITDylib,
// in which case we just verify it.
auto *ObjCImageInfo = G.findSectionByName(ObjCImageInfoSectionName);
auto *ObjCImageInfo = G.findSectionByName(MachOObjCImageInfoSectionName);
if (!ObjCImageInfo)
return Error::success();

auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();

// Check that the section is not empty if present.
if (ObjCImageInfoBlocks.empty())
return make_error<StringError>("Empty " + ObjCImageInfoSectionName +
return make_error<StringError>("Empty " + MachOObjCImageInfoSectionName +
" section in " + G.getName(),
inconvertibleErrorCode());

// Check that there's only one block in the section.
if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())
return make_error<StringError>("Multiple blocks in " +
ObjCImageInfoSectionName +
MachOObjCImageInfoSectionName +
" section in " + G.getName(),
inconvertibleErrorCode());

Expand All @@ -971,7 +944,7 @@ Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
for (auto &E : B->edges())
if (E.getTarget().isDefined() &&
&E.getTarget().getBlock().getSection() == ObjCImageInfo)
return make_error<StringError>(ObjCImageInfoSectionName +
return make_error<StringError>(MachOObjCImageInfoSectionName +
" is referenced within file " +
G.getName(),
inconvertibleErrorCode());
Expand Down Expand Up @@ -1024,7 +997,7 @@ Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
}

// Store key in __thread_vars struct fields.
if (auto *ThreadDataSec = G.findSectionByName(ThreadVarsSectionName)) {
if (auto *ThreadDataSec = G.findSectionByName(MachOThreadVarsSectionName)) {
std::optional<uint64_t> Key;
{
std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
Expand Down Expand Up @@ -1098,10 +1071,11 @@ MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
}
};

if (Section *EHFrameSec = G.findSectionByName(EHFrameSectionName))
if (Section *EHFrameSec = G.findSectionByName(MachOEHFrameSectionName))
ScanUnwindInfoSection(*EHFrameSec, US.DwarfSection);

if (Section *CUInfoSec = G.findSectionByName(CompactUnwindInfoSectionName))
if (Section *CUInfoSec =
G.findSectionByName(MachOCompactUnwindInfoSectionName))
ScanUnwindInfoSection(*CUInfoSec, US.CompactUnwindSection);

// If we didn't find any pointed-to code-blocks then there's no need to
Expand Down Expand Up @@ -1150,10 +1124,10 @@ Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
// Get a pointer to the thread data section if there is one. It will be used
// below.
jitlink::Section *ThreadDataSection =
G.findSectionByName(ThreadDataSectionName);
G.findSectionByName(MachOThreadDataSectionName);

// Handle thread BSS section if there is one.
if (auto *ThreadBSSSection = G.findSectionByName(ThreadBSSSectionName)) {
if (auto *ThreadBSSSection = G.findSectionByName(MachOThreadBSSSectionName)) {
// If there's already a thread data section in this graph then merge the
// thread BSS section content into it, otherwise just treat the thread
// BSS section as the thread data section.
Expand All @@ -1166,8 +1140,9 @@ Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
SmallVector<std::pair<StringRef, ExecutorAddrRange>, 8> MachOPlatformSecs;

// Collect data sections to register.
StringRef DataSections[] = {DataDataSectionName, DataCommonSectionName,
EHFrameSectionName};
StringRef DataSections[] = {MachODataDataSectionName,
MachODataCommonSectionName,
MachOEHFrameSectionName};
for (auto &SecName : DataSections) {
if (auto *Sec = G.findSectionByName(SecName)) {
jitlink::SectionRange R(*Sec);
Expand All @@ -1181,16 +1156,16 @@ Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
if (ThreadDataSection) {
jitlink::SectionRange R(*ThreadDataSection);
if (!R.empty())
MachOPlatformSecs.push_back({ThreadDataSectionName, R.getRange()});
MachOPlatformSecs.push_back({MachOThreadDataSectionName, R.getRange()});
}

// If any platform sections were found then add an allocation action to call
// the registration function.
StringRef PlatformSections[] = {
ModInitFuncSectionName, ObjCClassListSectionName,
ObjCImageInfoSectionName, ObjCSelRefsSectionName,
Swift5ProtoSectionName, Swift5ProtosSectionName,
Swift5TypesSectionName,
MachOModInitFuncSectionName, MachOObjCClassListSectionName,
MachOObjCImageInfoSectionName, MachOObjCSelRefsSectionName,
MachOSwift5ProtoSectionName, MachOSwift5ProtosSectionName,
MachOSwift5TypesSectionName,
};

for (auto &SecName : PlatformSections) {
Expand Down

0 comments on commit 3d4e9d5

Please sign in to comment.