Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions llvm/include/llvm/ExecutionEngine/JITLink/XCOFF.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===------- XCOFF.h - Generic JIT link function for XCOFF ------*- 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
//
//===----------------------------------------------------------------------===//
//
// jit-link functions for XCOFF.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_JITLINK_XCOFF_H
#define LLVM_EXECUTIONENGINE_JITLINK_XCOFF_H

#include "llvm/ExecutionEngine/JITLink/JITLink.h"

namespace llvm {
namespace jitlink {

/// Create a LinkGraph from an XCOFF relocatable object.
///
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromXCOFFObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);

/// Link the given graph.
void link_XCOFF(std::unique_ptr<LinkGraph> G,
std::unique_ptr<JITLinkContext> Ctx);

} // namespace jitlink
} // namespace llvm

#endif // LLVM_EXECUTIONENGINE_JITLINK_XCOFF_H
37 changes: 37 additions & 0 deletions llvm/include/llvm/ExecutionEngine/JITLink/XCOFF_ppc64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===------ XCOFF_ppc64.h - JIT link functions for XCOFF/ppc64 ------*- 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
//
//===----------------------------------------------------------------------===//
//
// jit-link functions for XCOFF/ppc64.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_JITLINK_XCOFF_PPC64_H
#define LLVM_EXECUTIONENGINE_JITLINK_XCOFF_PPC64_H

#include "llvm/ExecutionEngine/JITLink/JITLink.h"

namespace llvm::jitlink {

/// Create a LinkGraph from an XCOFF/ppc64 relocatable object.
///
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
///
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromXCOFFObject_ppc64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);

/// jit-link the given object buffer, which must be a XCOFF ppc64 object file.
///
void link_XCOFF_ppc64(std::unique_ptr<LinkGraph> G,
std::unique_ptr<JITLinkContext> Ctx);

} // end namespace llvm::jitlink

#endif // LLVM_EXECUTIONENGINE_JITLINK_XCOFF_PPC64_H
65 changes: 37 additions & 28 deletions llvm/include/llvm/ExecutionEngine/Orc/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,11 @@ class SymbolLookupSet {
/// If Body returns true then the element just passed in is removed from the
/// set. If Body returns false then the element is retained.
template <typename BodyFn>
auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
std::declval<SymbolLookupFlags>())),
bool>::value> {
auto forEachWithRemoval(BodyFn &&Body)
-> std::enable_if_t<
std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
std::declval<SymbolLookupFlags>())),
bool>::value> {
UnderlyingVector::size_type I = 0;
while (I != Symbols.size()) {
const auto &Name = Symbols[I].first;
Expand All @@ -330,11 +331,12 @@ class SymbolLookupSet {
/// returns true then the element just passed in is removed from the set. If
/// Body returns false then the element is retained.
template <typename BodyFn>
auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
std::declval<SymbolLookupFlags>())),
Expected<bool>>::value,
Error> {
auto forEachWithRemoval(BodyFn &&Body)
-> std::enable_if_t<
std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
std::declval<SymbolLookupFlags>())),
Expected<bool>>::value,
Error> {
UnderlyingVector::size_type I = 0;
while (I != Symbols.size()) {
const auto &Name = Symbols[I].first;
Expand Down Expand Up @@ -525,6 +527,7 @@ class MissingSymbolDefinitions : public ErrorInfo<MissingSymbolDefinitions> {
std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
const std::string &getModuleName() const { return ModuleName; }
const SymbolNameVector &getSymbols() const { return Symbols; }

private:
std::shared_ptr<SymbolStringPool> SSP;
std::string ModuleName;
Expand All @@ -535,7 +538,8 @@ class MissingSymbolDefinitions : public ErrorInfo<MissingSymbolDefinitions> {
/// symbols that are not claimed by the module's associated
/// MaterializationResponsibility. If this error is returned it is indicative of
/// a broken transformation / compiler / object cache.
class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions> {
class UnexpectedSymbolDefinitions
: public ErrorInfo<UnexpectedSymbolDefinitions> {
public:
static char ID;

Expand All @@ -548,6 +552,7 @@ class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions
std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
const std::string &getModuleName() const { return ModuleName; }
const SymbolNameVector &getSymbols() const { return Symbols; }

private:
std::shared_ptr<SymbolStringPool> SSP;
std::string ModuleName;
Expand Down Expand Up @@ -693,6 +698,10 @@ class MaterializationResponsibility {
: JD(RT->getJITDylib()), RT(std::move(RT)),
SymbolFlags(std::move(SymbolFlags)), InitSymbol(std::move(InitSymbol)) {
assert(!this->SymbolFlags.empty() && "Materializing nothing?");
for (auto &KV : this->SymbolFlags) {
dbgs() << "@@@ Init MR " << KV.first << " "
<< format_hex(KV.second.getRawFlagsValue(), 8) << "\n";
}
}

JITDylib &JD;
Expand Down Expand Up @@ -800,7 +809,6 @@ class AsynchronousSymbolQuery {
/// resolved.
bool isComplete() const { return OutstandingSymbolsCount == 0; }


private:
void handleComplete(ExecutionSession &ES);

Expand Down Expand Up @@ -899,8 +907,8 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
friend class ExecutionSession;
friend class Platform;
friend class MaterializationResponsibility;
public:

public:
JITDylib(const JITDylib &) = delete;
JITDylib &operator=(const JITDylib &) = delete;
JITDylib(JITDylib &&) = delete;
Expand Down Expand Up @@ -1104,7 +1112,7 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,

private:
using AsynchronousSymbolQuerySet =
std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
std::set<std::shared_ptr<AsynchronousSymbolQuery>>;

using AsynchronousSymbolQueryList =
std::vector<std::shared_ptr<AsynchronousSymbolQuery>>;
Expand Down Expand Up @@ -1160,6 +1168,7 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
const AsynchronousSymbolQueryList &pendingQueries() const {
return PendingQueries;
}

private:
AsynchronousSymbolQueryList PendingQueries;
};
Expand Down Expand Up @@ -1355,13 +1364,13 @@ class ExecutionSession {
using ErrorReporter = unique_function<void(Error)>;

/// Send a result to the remote.
using SendResultFunction = unique_function<void(shared::WrapperFunctionResult)>;
using SendResultFunction =
unique_function<void(shared::WrapperFunctionResult)>;

/// An asynchronous wrapper-function callable from the executor via
/// jit-dispatch.
using JITDispatchHandlerFunction = unique_function<void(
SendResultFunction SendResult,
const char *ArgData, size_t ArgSize)>;
SendResultFunction SendResult, const char *ArgData, size_t ArgSize)>;

/// A map associating tag names with asynchronous wrapper function
/// implementations in the JIT.
Expand Down Expand Up @@ -1589,8 +1598,7 @@ class ExecutionSession {
/// \endcode{.cpp}
///
/// The given OnComplete function will be called to return the result.
template <typename... ArgTs>
void callWrapperAsync(ArgTs &&... Args) {
template <typename... ArgTs> void callWrapperAsync(ArgTs &&...Args) {
EPC->callWrapperAsync(std::forward<ArgTs>(Args)...);
}

Expand Down Expand Up @@ -1635,9 +1643,9 @@ class ExecutionSession {
/// (using registerJITDispatchHandler) and called from the executor.
template <typename SPSSignature, typename HandlerT>
static JITDispatchHandlerFunction wrapAsyncWithSPS(HandlerT &&H) {
return [H = std::forward<HandlerT>(H)](
SendResultFunction SendResult,
const char *ArgData, size_t ArgSize) mutable {
return [H = std::forward<HandlerT>(H)](SendResultFunction SendResult,
const char *ArgData,
size_t ArgSize) mutable {
shared::WrapperFunction<SPSSignature>::handleAsync(ArgData, ArgSize, H,
std::move(SendResult));
};
Expand Down Expand Up @@ -1742,8 +1750,8 @@ class ExecutionSession {
unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);

// State machine functions for MaterializationResponsibility.
void OL_destroyMaterializationResponsibility(
MaterializationResponsibility &MR);
void
OL_destroyMaterializationResponsibility(MaterializationResponsibility &MR);
SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR);
Error OL_notifyResolved(MaterializationResponsibility &MR,
const SymbolMap &Symbols);
Expand Down Expand Up @@ -1965,12 +1973,13 @@ inline MaterializationResponsibility::~MaterializationResponsibility() {
getExecutionSession().OL_destroyMaterializationResponsibility(*this);
}

inline SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
inline SymbolNameSet
MaterializationResponsibility::getRequestedSymbols() const {
return getExecutionSession().OL_getRequestedSymbols(*this);
}

inline Error MaterializationResponsibility::notifyResolved(
const SymbolMap &Symbols) {
inline Error
MaterializationResponsibility::notifyResolved(const SymbolMap &Symbols) {
return getExecutionSession().OL_notifyResolved(*this, Symbols);
}

Expand All @@ -1979,8 +1988,8 @@ inline Error MaterializationResponsibility::notifyEmitted(
return getExecutionSession().OL_notifyEmitted(*this, EmittedDeps);
}

inline Error MaterializationResponsibility::defineMaterializing(
SymbolFlagsMap SymbolFlags) {
inline Error
MaterializationResponsibility::defineMaterializing(SymbolFlagsMap SymbolFlags) {
return getExecutionSession().OL_defineMaterializing(*this,
std::move(SymbolFlags));
}
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ add_llvm_component_library(LLVMJITLink
COFFLinkGraphBuilder.cpp
COFF_x86_64.cpp

# XCOFF
XCOFF.cpp
XCOFF_ppc64.cpp
XCOFFLinkGraphBuilder.cpp

# Architectures:
aarch32.cpp
aarch64.cpp
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "llvm/ExecutionEngine/JITLink/COFF.h"
#include "llvm/ExecutionEngine/JITLink/ELF.h"
#include "llvm/ExecutionEngine/JITLink/MachO.h"
#include "llvm/ExecutionEngine/JITLink/XCOFF.h"
#include "llvm/ExecutionEngine/JITLink/aarch64.h"
#include "llvm/ExecutionEngine/JITLink/i386.h"
#include "llvm/ExecutionEngine/JITLink/loongarch.h"
Expand Down Expand Up @@ -501,6 +502,8 @@ createLinkGraphFromObject(MemoryBufferRef ObjectBuffer,
return createLinkGraphFromELFObject(ObjectBuffer, std::move(SSP));
case file_magic::coff_object:
return createLinkGraphFromCOFFObject(ObjectBuffer, std::move(SSP));
case file_magic::xcoff_object_64:
return createLinkGraphFromXCOFFObject(ObjectBuffer, std::move(SSP));
default:
return make_error<JITLinkError>("Unsupported file format");
};
Expand Down Expand Up @@ -532,6 +535,8 @@ void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx) {
return link_ELF(std::move(G), std::move(Ctx));
case Triple::COFF:
return link_COFF(std::move(G), std::move(Ctx));
case Triple::XCOFF:
return link_XCOFF(std::move(G), std::move(Ctx));
default:
Ctx->notifyFailed(make_error<JITLinkError>("Unsupported object format"));
};
Expand Down
43 changes: 43 additions & 0 deletions llvm/lib/ExecutionEngine/JITLink/XCOFF.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===-------------- XCOFF.cpp - JIT linker function for XCOFF -------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// XCOFF jit-link function.
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/JITLink/XCOFF.h"
#include "llvm/ExecutionEngine/JITLink/XCOFF_ppc64.h"
#include "llvm/Object/XCOFFObjectFile.h"

using namespace llvm;

#define DEBUG_TYPE "jitlink"

namespace llvm {
namespace jitlink {

Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromXCOFFObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
// Check magic
file_magic Magic = identify_magic(ObjectBuffer.getBuffer());
if (Magic != file_magic::xcoff_object_64)
return make_error<JITLinkError>("Invalid XCOFF 64 Header");

// TODO: See if we need to add more checks
//
return createLinkGraphFromXCOFFObject_ppc64(ObjectBuffer, std::move(SSP));
}

void link_XCOFF(std::unique_ptr<LinkGraph> G,
std::unique_ptr<JITLinkContext> Ctx) {
link_XCOFF_ppc64(std::move(G), std::move(Ctx));
}

} // namespace jitlink
} // namespace llvm
Loading
Loading