[jitlink/rtdydl][checker] Add TargetFlag dependent disassembler switching support

Some targets such as AArch32 make use of TargetFlags to indicate ISA mode. Depending
on the TargetFlag, MCDisassembler and similar target specific objects should be
reinitialized with the correct Target Triple. Backends with similar needs can
easily extend this implementation for their usecase.

The drivers llvm-rtdyld and llvm-jitlink have their SymbolInfo's extended to take
TargetFlag into account. RuntimeDyldChecker can now create necessary TargetInfo
to reinitialize MCDisassembler and MCInstPrinter. The required triple is obtained
from the new getTripleFromTargetFlag function by checking the TargetFlag.

In addition, breaking changes for RuntimeDyld COFF Thumb tests are fixed by making
the backend emit a TargetFlag.

Reviewed By: lhames, sgraenitz

Differential Revision: https://reviews.llvm.org/D158280
This commit is contained in:
Eymen Ünay
2023-09-08 09:05:14 +02:00
committed by Stefan Gränitz
parent b0ea2790c4
commit 4b17c81d5a
15 changed files with 253 additions and 63 deletions

View File

@@ -623,10 +623,8 @@ public:
this->S = static_cast<uint8_t>(S);
}
/// Check whether the given target flags are set for this Symbol.
bool hasTargetFlags(TargetFlagsType Flags) const {
return static_cast<TargetFlagsType>(TargetFlags) & Flags;
}
/// Get the target flags of this Symbol.
TargetFlagsType getTargetFlags() const { return TargetFlags; }
/// Set the target flags for this Symbol.
void setTargetFlags(TargetFlagsType Flags) {

View File

@@ -23,6 +23,9 @@ namespace llvm {
namespace jitlink {
namespace aarch32 {
/// Check whether the given target flags are set for this Symbol.
bool hasTargetFlags(Symbol &Sym, TargetFlagsType Flags);
/// JITLink-internal AArch32 fixup kinds
enum EdgeKind_aarch32 : Edge::Kind {

View File

@@ -12,6 +12,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Endian.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"
#include <optional>
#include <cstdint>
@@ -29,6 +31,9 @@ class RuntimeDyld;
class RuntimeDyldCheckerImpl;
class raw_ostream;
/// Holds target-specific properties for a symbol.
using TargetFlagsType = uint8_t;
/// RuntimeDyld invariant checker for verifying that RuntimeDyld has
/// correctly applied relocations.
///
@@ -78,10 +83,11 @@ public:
public:
MemoryRegionInfo() = default;
/// Constructor for symbols/sections with content.
MemoryRegionInfo(ArrayRef<char> Content, JITTargetAddress TargetAddress)
/// Constructor for symbols/sections with content and TargetFlag.
MemoryRegionInfo(ArrayRef<char> Content, JITTargetAddress TargetAddress,
TargetFlagsType TargetFlags)
: ContentPtr(Content.data()), Size(Content.size()),
TargetAddress(TargetAddress) {}
TargetAddress(TargetAddress), TargetFlags(TargetFlags) {}
/// Constructor for zero-fill symbols/sections.
MemoryRegionInfo(uint64_t Size, JITTargetAddress TargetAddress)
@@ -127,10 +133,20 @@ public:
/// Return the target address for this region.
JITTargetAddress getTargetAddress() const { return TargetAddress; }
/// Get the target flags for this Symbol.
TargetFlagsType getTargetFlags() const { return TargetFlags; }
/// Set the target flags for this Symbol.
void setTargetFlags(TargetFlagsType Flags) {
assert(Flags <= 1 && "Add more bits to store more than one flag");
TargetFlags = Flags;
}
private:
const char *ContentPtr = nullptr;
uint64_t Size = 0;
JITTargetAddress TargetAddress = 0;
TargetFlagsType TargetFlags = 0;
};
using IsSymbolValidFunction = std::function<bool(StringRef Symbol)>;
@@ -148,9 +164,8 @@ public:
GetSectionInfoFunction GetSectionInfo,
GetStubInfoFunction GetStubInfo,
GetGOTInfoFunction GetGOTInfo,
support::endianness Endianness,
MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
raw_ostream &ErrStream);
support::endianness Endianness, Triple TT,
SubtargetFeatures TF, raw_ostream &ErrStream);
~RuntimeDyldChecker();
/// Check a single expression against the attached RuntimeDyld

View File

@@ -25,6 +25,11 @@ namespace llvm {
namespace jitlink {
namespace aarch32 {
/// Check whether the given target flags are set for this Symbol.
bool hasTargetFlags(Symbol &Sym, TargetFlagsType Flags) {
return static_cast<TargetFlagsType>(Sym.getTargetFlags()) & Flags;
}
/// Encode 22-bit immediate value for branch instructions without J1J2 range
/// extension (formats B T4, BL T1 and BLX T2).
///
@@ -287,7 +292,7 @@ Error applyFixupData(LinkGraph &G, Block &B, const Edge &E) {
int64_t Addend = E.getAddend();
Symbol &TargetSymbol = E.getTarget();
uint64_t TargetAddress = TargetSymbol.getAddress().getValue();
assert(!TargetSymbol.hasTargetFlags(ThumbSymbol));
assert(!hasTargetFlags(TargetSymbol, ThumbSymbol));
// Regular data relocations have size 4, alignment 1 and write the full 32-bit
// result to the place; no need for overflow checking. There are three
@@ -341,14 +346,14 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
int64_t Addend = E.getAddend();
Symbol &TargetSymbol = E.getTarget();
uint64_t TargetAddress = TargetSymbol.getAddress().getValue();
if (TargetSymbol.hasTargetFlags(ThumbSymbol))
if (hasTargetFlags(TargetSymbol, ThumbSymbol))
TargetAddress |= 0x01;
switch (Kind) {
case Thumb_Jump24: {
if (!checkOpcode<Thumb_Jump24>(R))
return makeUnexpectedOpcodeError(G, R, Kind);
if (!(TargetSymbol.hasTargetFlags(ThumbSymbol)))
if (!hasTargetFlags(TargetSymbol, ThumbSymbol))
return make_error<JITLinkError>("Branch relocation needs interworking "
"stub when bridging to ARM: " +
StringRef(G.getEdgeKindName(Kind)));
@@ -375,7 +380,7 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
// The call instruction itself is Thumb. The call destination can either be
// Thumb or Arm. We use BL to stay in Thumb and BLX to change to Arm.
bool TargetIsArm = !TargetSymbol.hasTargetFlags(ThumbSymbol);
bool TargetIsArm = !hasTargetFlags(TargetSymbol, ThumbSymbol);
bool InstrIsBlx = (R.Lo & FixupInfo<Thumb_Call>::LoBitNoBlx) == 0;
if (TargetIsArm != InstrIsBlx) {
if (LLVM_LIKELY(TargetIsArm)) {

View File

@@ -46,7 +46,7 @@ ExecutorAddr getJITSymbolPtrForSymbol(Symbol &Sym, const Triple &TT) {
case Triple::armeb:
case Triple::thumb:
case Triple::thumbeb:
if (Sym.hasTargetFlags(aarch32::ThumbSymbol)) {
if (hasTargetFlags(Sym, aarch32::ThumbSymbol)) {
// Set LSB to indicate thumb target
assert(Sym.isCallable() && "Only callable symbols can have thumb flag");
assert((Sym.getAddress().getValue() & 0x01) == 0 && "LSB is clear");

View File

@@ -10,9 +10,16 @@
#include "RuntimeDyldCheckerImpl.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -25,6 +32,19 @@
using namespace llvm;
namespace {
struct TargetInfo {
const Target *TheTarget;
std::unique_ptr<MCSubtargetInfo> STI;
std::unique_ptr<MCRegisterInfo> MRI;
std::unique_ptr<MCAsmInfo> MAI;
std::unique_ptr<MCContext> Ctx;
std::unique_ptr<MCDisassembler> Disassembler;
std::unique_ptr<MCInstrInfo> MII;
std::unique_ptr<MCInstPrinter> InstPrinter;
};
} // anonymous namespace
namespace llvm {
// Helper class that implements the language evaluated by RuntimeDyldChecker.
@@ -276,6 +296,20 @@ private:
"");
unsigned OpIdx = OpIdxExpr.getValue();
auto printInst = [this](StringRef Symbol, MCInst Inst,
raw_string_ostream &ErrMsgStream) {
auto TI = getTargetInfo(
Checker.getTripleFromTargetFlag(Checker.getTargetFlag(Symbol)));
if (auto E = TI.takeError()) {
errs() << "Error obtaining instruction printer: "
<< toString(std::move(E)) << "\n";
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
}
Inst.dump_pretty(ErrMsgStream, TI->InstPrinter.get());
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
};
if (OpIdx >= Inst.getNumOperands()) {
std::string ErrMsg;
raw_string_ostream ErrMsgStream(ErrMsg);
@@ -284,8 +318,8 @@ private:
<< "'. Instruction has only "
<< format("%i", Inst.getNumOperands())
<< " operands.\nInstruction is:\n ";
Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
return printInst(Symbol, Inst, ErrMsgStream);
}
const MCOperand &Op = Inst.getOperand(OpIdx);
@@ -294,9 +328,8 @@ private:
raw_string_ostream ErrMsgStream(ErrMsg);
ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '"
<< Symbol << "' is not an immediate.\nInstruction is:\n ";
Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
return printInst(Symbol, Inst, ErrMsgStream);
}
return std::make_pair(EvalResult(Op.getImm()), RemainingExpr);
@@ -687,31 +720,101 @@ private:
bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size,
int64_t Offset) const {
MCDisassembler *Dis = Checker.Disassembler;
auto TI = getTargetInfo(
Checker.getTripleFromTargetFlag(Checker.getTargetFlag(Symbol)));
if (auto E = TI.takeError()) {
errs() << "Error obtaining disassembler: " << toString(std::move(E))
<< "\n";
return false;
}
StringRef SymbolMem = Checker.getSymbolContent(Symbol);
ArrayRef<uint8_t> SymbolBytes(SymbolMem.bytes_begin() + Offset,
SymbolMem.size() - Offset);
MCDisassembler::DecodeStatus S =
Dis->getInstruction(Inst, Size, SymbolBytes, 0, nulls());
TI->Disassembler->getInstruction(Inst, Size, SymbolBytes, 0, nulls());
return (S == MCDisassembler::Success);
}
Expected<TargetInfo>
getTargetInfo(const Triple &TT,
const SubtargetFeatures &TF = SubtargetFeatures()) const {
auto TripleName = TT.str();
std::string ErrorStr;
const Target *TheTarget =
TargetRegistry::lookupTarget(TripleName, ErrorStr);
if (!TheTarget)
return make_error<StringError>("Error accessing target '" + TripleName +
"': " + ErrorStr,
inconvertibleErrorCode());
std::unique_ptr<MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(TripleName, "", TF.getString()));
if (!STI)
return make_error<StringError>("Unable to create subtarget for " +
TripleName,
inconvertibleErrorCode());
std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
if (!MRI)
return make_error<StringError>("Unable to create target register info "
"for " +
TripleName,
inconvertibleErrorCode());
MCTargetOptions MCOptions;
std::unique_ptr<MCAsmInfo> MAI(
TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
if (!MAI)
return make_error<StringError>("Unable to create target asm info " +
TripleName,
inconvertibleErrorCode());
auto Ctx = std::make_unique<MCContext>(Triple(TripleName), MAI.get(),
MRI.get(), STI.get());
std::unique_ptr<MCDisassembler> Disassembler(
TheTarget->createMCDisassembler(*STI, *Ctx));
if (!Disassembler)
return make_error<StringError>("Unable to create disassembler for " +
TripleName,
inconvertibleErrorCode());
std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
if (!MII)
return make_error<StringError>("Unable to create instruction info for" +
TripleName,
inconvertibleErrorCode());
std::unique_ptr<MCInstPrinter> InstPrinter(TheTarget->createMCInstPrinter(
Triple(TripleName), 0, *MAI, *MII, *MRI));
if (!InstPrinter)
return make_error<StringError>(
"Unable to create instruction printer for" + TripleName,
inconvertibleErrorCode());
return TargetInfo({TheTarget, std::move(STI), std::move(MRI),
std::move(MAI), std::move(Ctx), std::move(Disassembler),
std::move(MII), std::move(InstPrinter)});
}
};
} // namespace llvm
RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(
IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
GetGOTInfoFunction GetGOTInfo, support::endianness Endianness,
MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
raw_ostream &ErrStream)
GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, Triple TT,
SubtargetFeatures TF, raw_ostream &ErrStream)
: IsSymbolValid(std::move(IsSymbolValid)),
GetSymbolInfo(std::move(GetSymbolInfo)),
GetSectionInfo(std::move(GetSectionInfo)),
GetStubInfo(std::move(GetStubInfo)), GetGOTInfo(std::move(GetGOTInfo)),
Endianness(Endianness), Disassembler(Disassembler),
InstPrinter(InstPrinter), ErrStream(ErrStream) {}
Endianness(Endianness), TT(std::move(TT)), TF(std::move(TF)),
ErrStream(ErrStream) {}
bool RuntimeDyldCheckerImpl::check(StringRef CheckExpr) const {
CheckExpr = CheckExpr.trim();
@@ -822,6 +925,36 @@ StringRef RuntimeDyldCheckerImpl::getSymbolContent(StringRef Symbol) const {
return {SymInfo->getContent().data(), SymInfo->getContent().size()};
}
TargetFlagsType RuntimeDyldCheckerImpl::getTargetFlag(StringRef Symbol) const {
auto SymInfo = GetSymbolInfo(Symbol);
if (!SymInfo) {
logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
return TargetFlagsType{};
}
return SymInfo->getTargetFlags();
}
Triple
RuntimeDyldCheckerImpl::getTripleFromTargetFlag(TargetFlagsType Flag) const {
Triple TheTriple = TT;
switch (TT.getArch()) {
case Triple::ArchType::arm:
if (~Flag & 0x1)
return TT;
TheTriple.setArchName((Twine("thumb") + TT.getArchName().substr(3)).str());
return TheTriple;
case Triple::ArchType::thumb:
if (Flag & 0x1)
return TT;
TheTriple.setArchName((Twine("arm") + TT.getArchName().substr(5)).str());
return TheTriple;
default:
return TT;
}
}
std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
StringRef FileName, StringRef SectionName, bool IsInsideLoad) const {
@@ -884,13 +1017,12 @@ std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
RuntimeDyldChecker::RuntimeDyldChecker(
IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
GetGOTInfoFunction GetGOTInfo, support::endianness Endianness,
MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
raw_ostream &ErrStream)
GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, Triple TT,
SubtargetFeatures TF, raw_ostream &ErrStream)
: Impl(::std::make_unique<RuntimeDyldCheckerImpl>(
std::move(IsSymbolValid), std::move(GetSymbolInfo),
std::move(GetSectionInfo), std::move(GetStubInfo),
std::move(GetGOTInfo), Endianness, Disassembler, InstPrinter,
std::move(GetGOTInfo), Endianness, std::move(TT), std::move(TF),
ErrStream)) {}
RuntimeDyldChecker::~RuntimeDyldChecker() = default;

View File

@@ -13,6 +13,9 @@
namespace llvm {
/// Holds target-specific properties for a symbol.
using TargetFlagsType = uint8_t;
class RuntimeDyldCheckerImpl {
friend class RuntimeDyldChecker;
friend class RuntimeDyldCheckerExprEval;
@@ -25,12 +28,13 @@ class RuntimeDyldCheckerImpl {
using GetGOTInfoFunction = RuntimeDyldChecker::GetGOTInfoFunction;
public:
RuntimeDyldCheckerImpl(
IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
GetGOTInfoFunction GetGOTInfo, support::endianness Endianness,
MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
llvm::raw_ostream &ErrStream);
RuntimeDyldCheckerImpl(IsSymbolValidFunction IsSymbolValid,
GetSymbolInfoFunction GetSymbolInfo,
GetSectionInfoFunction GetSectionInfo,
GetStubInfoFunction GetStubInfo,
GetGOTInfoFunction GetGOTInfo,
support::endianness Endianness, Triple TT,
SubtargetFeatures TF, llvm::raw_ostream &ErrStream);
bool check(StringRef CheckExpr) const;
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
@@ -49,6 +53,9 @@ private:
StringRef getSymbolContent(StringRef Symbol) const;
TargetFlagsType getTargetFlag(StringRef Symbol) const;
Triple getTripleFromTargetFlag(TargetFlagsType Flag) const;
std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
StringRef SectionName,
bool IsInsideLoad) const;
@@ -65,8 +72,8 @@ private:
GetStubInfoFunction GetStubInfo;
GetGOTInfoFunction GetGOTInfo;
support::endianness Endianness;
MCDisassembler *Disassembler;
MCInstPrinter *InstPrinter;
Triple TT;
SubtargetFeatures TF;
llvm::raw_ostream &ErrStream;
};
}

View File

@@ -54,6 +54,28 @@ public:
return 16; // 8-byte load instructions, 4-byte jump, 4-byte padding
}
Expected<JITSymbolFlags> getJITSymbolFlags(const SymbolRef &SR) override {
auto Flags = RuntimeDyldImpl::getJITSymbolFlags(SR);
if (!Flags) {
return Flags.takeError();
}
auto SectionIterOrErr = SR.getSection();
if (!SectionIterOrErr) {
return SectionIterOrErr.takeError();
}
SectionRef Sec = *SectionIterOrErr.get();
const object::COFFObjectFile *COFFObjPtr =
cast<object::COFFObjectFile>(Sec.getObject());
const coff_section *CoffSec = COFFObjPtr->getCOFFSection(Sec);
bool isThumb = CoffSec->Characteristics & COFF::IMAGE_SCN_MEM_16BIT;
Flags->getTargetFlags() = isThumb;
return Flags;
}
Align getStubAlignment() override { return Align(1); }
Expected<object::relocation_iterator>

View File

@@ -4,8 +4,6 @@
# RUN: llvm-jitlink -noexec -slab-address 0x76ff0000 -slab-allocate 10Kb \
# RUN: -slab-page-size 4096 -show-entry-es -check %s %t.o
# This test requires the RuntimeDyldChecker fix from review D158280
# XFAIL: *
.text
.syntax unified

View File

@@ -101,7 +101,7 @@ rel11:
bx r0
trap
.data
.text
.p2align 2

View File

@@ -118,7 +118,8 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
if (Sym->getSize() != 0) {
if (auto TS = getCOFFGOTTarget(G, Sym->getBlock()))
FileInfo.GOTEntryInfos[TS->getName()] = {
Sym->getSymbolContent(), Sym->getAddress().getValue()};
Sym->getSymbolContent(), Sym->getAddress().getValue(),
Sym->getTargetFlags()};
else
return TS.takeError();
}
@@ -130,7 +131,8 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
if (auto TS = getCOFFStubTarget(G, Sym->getBlock()))
FileInfo.StubInfos[TS->getName()] = {Sym->getSymbolContent(),
Sym->getAddress().getValue()};
Sym->getAddress().getValue(),
Sym->getTargetFlags()};
else
return TS.takeError();
SectionContainsContent = true;
@@ -143,7 +145,8 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
SectionContainsZeroFill = true;
} else {
S.SymbolInfos[Sym->getName()] = {Sym->getSymbolContent(),
Sym->getAddress().getValue()};
Sym->getAddress().getValue(),
Sym->getTargetFlags()};
SectionContainsContent = true;
}
}
@@ -164,7 +167,7 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
else
FileInfo.SectionInfos[Sec.getName()] = {
ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
SecAddr.getValue()};
SecAddr.getValue(), FirstSym->getTargetFlags()};
}
return Error::success();

View File

@@ -120,7 +120,8 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
if (Sym->getSize() != 0) {
if (auto TS = getELFGOTTarget(G, Sym->getBlock()))
FileInfo.GOTEntryInfos[TS->getName()] = {
Sym->getSymbolContent(), Sym->getAddress().getValue()};
Sym->getSymbolContent(), Sym->getAddress().getValue(),
Sym->getTargetFlags()};
else
return TS.takeError();
}
@@ -132,7 +133,8 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
if (auto TS = getELFStubTarget(G, Sym->getBlock()))
FileInfo.StubInfos[TS->getName()] = {Sym->getSymbolContent(),
Sym->getAddress().getValue()};
Sym->getAddress().getValue(),
Sym->getTargetFlags()};
else
return TS.takeError();
SectionContainsContent = true;
@@ -145,7 +147,8 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
SectionContainsZeroFill = true;
} else {
S.SymbolInfos[Sym->getName()] = {Sym->getSymbolContent(),
Sym->getAddress().getValue()};
Sym->getAddress().getValue(),
Sym->getTargetFlags()};
SectionContainsContent = true;
}
}
@@ -170,7 +173,7 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
else
FileInfo.SectionInfos[Sec.getName()] = {
ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
SecAddr.getValue()};
SecAddr.getValue(), FirstSym->getTargetFlags()};
}
return Error::success();

View File

@@ -117,8 +117,9 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
inconvertibleErrorCode());
if (auto TS = getMachOGOTTarget(G, Sym->getBlock()))
FileInfo.GOTEntryInfos[TS->getName()] = {
Sym->getSymbolContent(), Sym->getAddress().getValue()};
FileInfo.GOTEntryInfos[TS->getName()] = {Sym->getSymbolContent(),
Sym->getAddress().getValue(),
Sym->getTargetFlags()};
else
return TS.takeError();
SectionContainsContent = true;
@@ -129,7 +130,8 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
if (auto TS = getMachOStubTarget(G, Sym->getBlock()))
FileInfo.StubInfos[TS->getName()] = {Sym->getSymbolContent(),
Sym->getAddress().getValue()};
Sym->getAddress().getValue(),
Sym->getTargetFlags()};
else
return TS.takeError();
SectionContainsContent = true;
@@ -140,7 +142,8 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
SectionContainsZeroFill = true;
} else {
S.SymbolInfos[Sym->getName()] = {Sym->getSymbolContent(),
Sym->getAddress().getValue()};
Sym->getAddress().getValue(),
Sym->getTargetFlags()};
SectionContainsContent = true;
}
}
@@ -160,7 +163,7 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
else
FileInfo.SectionInfos[Sec.getName()] = {
ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
SecAddr.getValue()};
SecAddr.getValue(), FirstSym->getTargetFlags()};
}
return Error::success();

View File

@@ -1388,7 +1388,8 @@ static Error addAbsoluteSymbols(Session &S,
return Err;
// Register the absolute symbol with the session symbol infos.
S.SymbolInfos[Name] = {ArrayRef<char>(), Addr};
S.SymbolInfos[Name] = {ArrayRef<char>(), Addr,
AbsDef.getFlags().getTargetFlags()};
}
return Error::success();
@@ -1856,15 +1857,12 @@ getTargetInfo(const Triple &TT,
std::move(MAI), std::move(Ctx), std::move(Disassembler),
std::move(MII), std::move(MIA), std::move(InstPrinter)};
}
static Error runChecks(Session &S) {
static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
if (CheckFiles.empty())
return Error::success();
LLVM_DEBUG(dbgs() << "Running checks...\n");
auto TI = getTargetInfo(S.ES.getTargetTriple(), S.Features);
auto IsSymbolValid = [&S](StringRef Symbol) {
return S.isSymbolRegistered(Symbol);
};
@@ -1888,7 +1886,7 @@ static Error runChecks(Session &S) {
RuntimeDyldChecker Checker(
IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,
S.ES.getTargetTriple().isLittleEndian() ? support::little : support::big,
TI.Disassembler.get(), TI.InstPrinter.get(), dbgs());
TT, Features, dbgs());
std::string CheckLineStart = "# " + CheckName + ":";
for (auto &CheckFile : CheckFiles) {
@@ -2000,7 +1998,7 @@ int main(int argc, char *argv[]) {
auto [TT, Features] = getFirstFileTripleAndFeatures();
ExitOnErr(sanitizeArguments(TT, argv[0]));
auto S = ExitOnErr(Session::Create(std::move(TT), std::move(Features)));
auto S = ExitOnErr(Session::Create(TT, Features));
enableStatistics(*S, !OrcRuntime.empty());
@@ -2036,7 +2034,7 @@ int main(int argc, char *argv[]) {
exit(1);
}
ExitOnErr(runChecks(*S));
ExitOnErr(runChecks(*S, std::move(TT), std::move(Features)));
int Result = 0;
if (!NoExec) {

View File

@@ -892,6 +892,8 @@ static int linkAndVerify() {
StringRef SecContent = Dyld.getSectionContent(SectionID);
uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data());
SymInfo.setContent(ArrayRef<char>(CSymAddr, SymSize));
SymInfo.setTargetFlags(
Dyld.getSymbol(Symbol).getFlags().getTargetFlags());
}
}
return SymInfo;
@@ -973,11 +975,12 @@ static int linkAndVerify() {
ObjectFile &Obj = **MaybeObj;
SubtargetFeatures Features = SubtargetFeatures();
if (!Checker)
Checker = std::make_unique<RuntimeDyldChecker>(
IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo,
GetStubInfo, Obj.isLittleEndian() ? support::little : support::big,
Disassembler.get(), InstPrinter.get(), dbgs());
TheTriple, Features, dbgs());
auto FileName = sys::path::filename(InputFile);
MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]);