20#define DEBUG_TYPE "orc"
68 (
sizeof(Version) +
sizeof(EhFramePtrEnc) +
sizeof(FDECountEnc) +
70 (absolute ?
sizeof(
uint64_t) :
sizeof(EHFrameRelocation)));
71 std::string HeaderContent(HeaderSize,
'\0');
74 reinterpret_cast<uint8_t *
>(HeaderContent.data()), HeaderSize),
76 if (
auto Err = Writer.writeInteger(Version))
77 return std::move(Err);
78 if (
auto Err = Writer.writeInteger(EhFramePtrEnc))
79 return std::move(Err);
80 if (
auto Err = Writer.writeInteger(FDECountEnc))
81 return std::move(Err);
82 if (
auto Err = Writer.writeInteger(TableEnc))
83 return std::move(Err);
86 if (
auto Err = Writer.writeInteger(EHFrameAddr))
87 return std::move(Err);
89 if (
auto Err = Writer.writeInteger(EHFrameRelocation))
90 return std::move(Err);
99getCodeLoadRecord(
const Symbol &Sym, std::atomic<uint64_t> &CodeIndex) {
112 Record.CodeIndex = CodeIndex++;
126static std::optional<PerfJITDebugInfoRecord>
133 <<
" at address " << Addr.getValue() <<
" with size "
146 for (
const auto &Entry : LInfo) {
147 auto Addr = Entry.first;
152 Record.Entries.push_back({Addr, Entry.second.Line,
153 Entry.second.Discriminator,
154 Entry.second.FileName});
156 size_t EntriesBytes = (2
160 for (
const auto &Entry :
Record.Entries) {
163 EntriesBytes += Entry.Name.size() + 1;
165 Record.Prefix.TotalSize = EntriesBytes;
167 <<
"Total size: " <<
Record.Prefix.TotalSize <<
"\n"
168 <<
"Nr entries: " <<
Record.Entries.size() <<
"\n");
176 Record.Prefix.TotalSize = 0;
177 auto Eh_frame =
G.findSectionByName(
".eh_frame");
182 if (!
G.getTargetTriple().isOSBinFormatELF()) {
183 LLVM_DEBUG(
dbgs() <<
"Not an ELF file, will not emit unwinding info\n");
187 auto EHFrameSize = SR.getSize();
188 auto Eh_frame_hdr =
G.findSectionByName(
".eh_frame_hdr");
191 auto Hdr = createX64EHFrameHeader(*Eh_frame,
G.getEndianness(),
true);
193 return Hdr.takeError();
194 Record.EHFrameHdr = std::move(*Hdr);
199 Record.EHFrameHdrAddr = 0;
201 Record.UnwindDataSize = EHFrameSize +
Record.EHFrameHdrSize;
206 Record.EHFrameHdrSize = SR.getSize();
207 Record.UnwindDataSize = EHFrameSize +
Record.EHFrameHdrSize;
219 <<
"Total size: " <<
Record.Prefix.TotalSize <<
"\n"
220 <<
"Unwind size: " <<
Record.UnwindDataSize <<
"\n"
221 <<
"EHFrame size: " << EHFrameSize <<
"\n"
222 <<
"EHFrameHdr size: " <<
Record.EHFrameHdrSize <<
"\n");
227 std::atomic<uint64_t> &CodeIndex,
229 std::unique_ptr<DWARFContext> DC;
235 EmitDebugInfo =
false;
237 DC = std::move(EDC->first);
238 DCBacking = std::move(EDC->second);
242 for (
auto Sym :
G.defined_symbols()) {
246 auto DebugInfo = getDebugInfoRecord(*Sym, *DC);
253 auto UWR = getUnwindingRecord(
G);
270 bool EmitDebugInfo,
bool EmitUnwindInfo)
271 : EPC(EPC), RegisterPerfStart(
274 RegisterPerfStartAddr),
277 RegisterPerfEndAddr),
278 RegisterPerfImplAddr(RegisterPerfImplAddr), CodeIndex(0),
279 EmitDebugInfo(EmitDebugInfo), EmitUnwindInfo(EmitUnwindInfo) {
280 cantFail(RegisterPerfStart(EPC.getExecutionSession()));
292 EPC.getExecutionSession());
299 auto Batch = getRecords(EPC.getExecutionSession(),
G, CodeIndex,
300 EmitDebugInfo, EmitUnwindInfo);
301 G.allocActions().push_back(
304 RegisterPerfImplAddr, Batch)),
312 bool EmitDebugInfo,
bool EmitUnwindInfo) {
313 if (!EPC.getTargetTriple().isOSBinFormatELF()) {
315 "Perf support only available for ELF LinkGraphs!",
322 recordAddr(RegisterPerfImplSymbolName, &ImplAddr)}))
323 return std::move(Err);
324 return std::make_unique<PerfSupportPlugin>(EPC, StartAddr, EndAddr, ImplAddr,
325 EmitDebugInfo, EmitUnwindInfo);
static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info)
Provides write only access to a subclass of WritableBinaryStream.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
DILineInfoTable getLineInfoForAddressRange(object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
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.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
const RecordVal * getValue(const Init *Name) const
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represents a section address range via a pair of Block pointers to the first and last Blocks in the s...
orc::ExecutorAddr getStart() const
Represents an object file section.
SectionOrdinal getOrdinal() const
Returns the ordinal for this section.
bool isCallable() const
Returns true is this symbol is callable.
const orc::SymbolStringPtr & getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
Section & getSection() const
Return the Section for this Symbol (Symbol must be defined).
orc::ExecutorAddrDiff getSize() const
Returns the size of this symbol.
bool hasName() const
Returns true if this symbol has a name.
An ExecutionSession represents a running JIT program.
void reportError(Error Err)
Report a error for this execution session.
Represents an address in the executor process.
uint64_t getValue() const
ExecutorProcessControl supports interaction with a JIT target process.
Represents a JIT'd dynamic library.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &Config) override
~PerfSupportPlugin() override
static Expected< std::unique_ptr< PerfSupportPlugin > > Create(ExecutorProcessControl &EPC, JITDylib &JD, bool EmitDebugInfo, bool EmitUnwindInfo)
PerfSupportPlugin(ExecutorProcessControl &EPC, ExecutorAddr RegisterPerfStartAddr, ExecutorAddr RegisterPerfEndAddr, ExecutorAddr RegisterPerfImplAddr, bool EmitDebugInfo, bool EmitUnwindInfo)
A symbol name together with the naming level (SymbolNameKind) it is expressed in, so that a Mangler /...
static constexpr SymbolNameSpec c(StringRef Name)
A utility class for serializing to a blob from a variadic list.
static Expected< WrapperFunctionCall > Create(ExecutorAddr FnAddr, const ArgTs &...Args)
Create a WrapperFunctionCall using the given SPS serializer to serialize the arguments.
LLVM_ABI void lookupAndApply(unique_function< void(Error)> OnApplied, LookupKind K, const JITDylibSearchOrder &SearchOrder, ArrayRef< LookupPrepareFn > PrepareFns)
Resolve the symbols contributed by every prepare function with a single lookup, then let each of thei...
@ JIT_CODE_UNWINDING_INFO
LookupPrepareFn recordAddr(SymbolNameSpec Name, ExecutorAddr *A, SymbolLookupFlags LF=SymbolLookupFlags::RequiredSymbol)
Records the address of the symbol with the given name.
LLVM_ABI Expected< std::pair< std::unique_ptr< DWARFContext >, StringMap< std::unique_ptr< MemoryBuffer > > > > createDWARFContext(jitlink::LinkGraph &G)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
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.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
void consumeError(Error Err)
Consume a Error without doing anything.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
LinkGraphPassList PostFixupPasses
Post-fixup passes.
PerfJITRecordPrefix Prefix
std::vector< PerfJITDebugInfoRecord > DebugInfoRecords
PerfJITCodeUnwindingInfoRecord UnwindingRecord
std::vector< PerfJITCodeLoadRecord > CodeLoadRecords
static constexpr SymbolNameSpec Name
static constexpr SymbolNameSpec Name