mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-10-03 19:08:24 -04:00
Refactor runtime for move speed and better code style (#140)
* feat: added guestBranchKind enum to categorize branch types feat: added missingFunctionPolicy enum to define behaviors for missing function scenarios refactor: added handle guest branches and report missing functions feat lookupFunction to utilize new dispatch logic and improve error handling for unregistered functions * fix: fix test conflict * feat: added debug sound driver logs * feat: emmiter for return * feat: added recompiler reporter feat: added strict diagnostics flag for heavy debug calls * feat: staticc table insted of hashmap for runtime * feat: back file to ignore * feat: explode code across helpers and classes * feat: update codegen test feat: better guest nop check * feat: fix link problem on linux * feat: fix Segmentation fault
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#ifndef PS2RECOMP_CONTROL_FLOW_EMITTER_H
|
||||
#define PS2RECOMP_CONTROL_FLOW_EMITTER_H
|
||||
|
||||
#include "ps2recomp/code_generator.h"
|
||||
#include "ps2recomp/types.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
class ControlFlowEmitter
|
||||
{
|
||||
public:
|
||||
ControlFlowEmitter(CodeGenerator &generator,
|
||||
const Instruction &branchInst,
|
||||
const Instruction &delaySlot,
|
||||
const Function &function,
|
||||
const CodeGenerator::AnalysisResult &analysisResult);
|
||||
|
||||
std::string emit();
|
||||
|
||||
private:
|
||||
enum class StaticBranchKind
|
||||
{
|
||||
Jump,
|
||||
Call,
|
||||
};
|
||||
|
||||
enum class RegisterBranchKind
|
||||
{
|
||||
Jump,
|
||||
Call,
|
||||
};
|
||||
|
||||
CodeGenerator &m_gen;
|
||||
const Instruction &m_branchInst;
|
||||
const Instruction &m_delaySlot;
|
||||
const Function &m_function;
|
||||
const CodeGenerator::AnalysisResult &m_analysisResult;
|
||||
std::stringstream m_ss;
|
||||
|
||||
uint32_t branchPc() const;
|
||||
uint32_t delayPc() const;
|
||||
uint32_t fallthroughPc() const;
|
||||
bool hasRealDelaySlot() const;
|
||||
bool isLikelyBranch() const;
|
||||
bool isCallLikeEdge() const;
|
||||
bool isInternalTarget(uint32_t target) const;
|
||||
std::vector<uint32_t> resolvedLocalIndirectTargets() const;
|
||||
|
||||
std::string delaySlotCode() const;
|
||||
void emitDelaySlot(std::string_view indent);
|
||||
void emitResumeFromDelaySlotEntry();
|
||||
void emitInternalTarget(uint32_t target, uint32_t sourcePc, std::string_view indent);
|
||||
void emitFallthroughLabelIfNeeded();
|
||||
void emitFinalFallthrough();
|
||||
|
||||
void emitStaticJump(StaticBranchKind kind);
|
||||
void emitRegisterJump(RegisterBranchKind kind);
|
||||
void emitConditionalBranch();
|
||||
void emitFallbackInstruction();
|
||||
|
||||
bool emitDirectFunctionJumpIfAvailable(uint32_t target, StaticBranchKind kind, std::string_view indent);
|
||||
void emitExternalJumpDispatch(uint32_t target, StaticBranchKind kind, std::string_view indent);
|
||||
void emitExternalRegisterCallDispatch(std::string_view jumpTargetExpression, std::string_view indent);
|
||||
void emitExternalRegisterJumpDispatch(std::string_view jumpTargetExpression, RegisterBranchKind kind, uint8_t rsReg, std::string_view indent);
|
||||
void emitRuntimeBranchDispatch(std::string_view targetExpression,
|
||||
uint32_t sourcePc,
|
||||
uint32_t returnPc,
|
||||
std::string_view runtimeKind,
|
||||
std::string_view debugName,
|
||||
std::string_view indent,
|
||||
bool returnOnTransfer);
|
||||
bool emitRelocationCallIfAvailable(StaticBranchKind kind, std::string_view indent);
|
||||
std::string conditionalBranchExpression() const;
|
||||
uint32_t conditionalBranchTarget() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_CONTROL_FLOW_EMITTER_H
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef PS2RECOMP_FUNCTION_EMITTER_H
|
||||
#define PS2RECOMP_FUNCTION_EMITTER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Function;
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class FunctionEmitter
|
||||
{
|
||||
public:
|
||||
explicit FunctionEmitter(CodeGenerator &codeGenerator);
|
||||
|
||||
std::string emit(const Function &function, const std::vector<Instruction> &instructions, bool useHeaders);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_FUNCTION_EMITTER_H
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef PS2RECOMP_FUNCTION_TABLE_EMITTER_H
|
||||
#define PS2RECOMP_FUNCTION_TABLE_EMITTER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Function;
|
||||
class CodeGenerator;
|
||||
|
||||
class FunctionTableEmitter
|
||||
{
|
||||
public:
|
||||
explicit FunctionTableEmitter(CodeGenerator &codeGenerator);
|
||||
|
||||
std::string emit(const std::vector<Function> &functions, const std::map<uint32_t, std::string> &stubs);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_FUNCTION_TABLE_EMITTER_H
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PS2RECOMP_COP0_TRANSLATOR_H
|
||||
#define PS2RECOMP_COP0_TRANSLATOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class Cop0Translator
|
||||
{
|
||||
public:
|
||||
explicit Cop0Translator(CodeGenerator &codeGenerator);
|
||||
std::string translate(const Instruction &inst);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_COP0_TRANSLATOR_H
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PS2RECOMP_FPU_TRANSLATOR_H
|
||||
#define PS2RECOMP_FPU_TRANSLATOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class FpuTranslator
|
||||
{
|
||||
public:
|
||||
explicit FpuTranslator(CodeGenerator &codeGenerator);
|
||||
std::string translate(const Instruction &inst);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_FPU_TRANSLATOR_H
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PS2RECOMP_INSTRUCTION_TRANSLATOR_H
|
||||
#define PS2RECOMP_INSTRUCTION_TRANSLATOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class InstructionTranslator
|
||||
{
|
||||
public:
|
||||
explicit InstructionTranslator(CodeGenerator &codeGenerator);
|
||||
std::string translate(const Instruction &inst);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_INSTRUCTION_TRANSLATOR_H
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PS2RECOMP_MMI_TRANSLATOR_H
|
||||
#define PS2RECOMP_MMI_TRANSLATOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class MmiTranslator
|
||||
{
|
||||
public:
|
||||
explicit MmiTranslator(CodeGenerator &codeGenerator);
|
||||
std::string translate(const Instruction &inst);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_MMI_TRANSLATOR_H
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PS2RECOMP_REGIMM_TRANSLATOR_H
|
||||
#define PS2RECOMP_REGIMM_TRANSLATOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class RegimmTranslator
|
||||
{
|
||||
public:
|
||||
explicit RegimmTranslator(CodeGenerator &codeGenerator);
|
||||
std::string translate(const Instruction &inst);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_REGIMM_TRANSLATOR_H
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PS2RECOMP_SPECIAL_TRANSLATOR_H
|
||||
#define PS2RECOMP_SPECIAL_TRANSLATOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class SpecialTranslator
|
||||
{
|
||||
public:
|
||||
explicit SpecialTranslator(CodeGenerator &codeGenerator);
|
||||
std::string translate(const Instruction &inst);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_SPECIAL_TRANSLATOR_H
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PS2RECOMP_VU_TRANSLATOR_H
|
||||
#define PS2RECOMP_VU_TRANSLATOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Instruction;
|
||||
class CodeGenerator;
|
||||
|
||||
class VuTranslator
|
||||
{
|
||||
public:
|
||||
explicit VuTranslator(CodeGenerator &codeGenerator);
|
||||
std::string translate(const Instruction &inst);
|
||||
|
||||
private:
|
||||
CodeGenerator &m_codeGenerator;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_VU_TRANSLATOR_H
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include "ps2recomp/control_flow_analyzer.h"
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
@@ -16,6 +17,7 @@ namespace ps2recomp
|
||||
struct Function;
|
||||
struct Symbol;
|
||||
struct Section;
|
||||
class RecompilerReporter;
|
||||
|
||||
extern const std::unordered_set<std::string> kKeywords;
|
||||
|
||||
@@ -35,13 +37,7 @@ namespace ps2recomp
|
||||
std::string entryName;
|
||||
};
|
||||
|
||||
struct AnalysisResult {
|
||||
std::unordered_set<uint32_t> entryPoints;
|
||||
std::unordered_set<uint32_t> externalEntryPoints;
|
||||
std::unordered_set<uint32_t> resumeEntryPoints;
|
||||
std::unordered_set<uint32_t> indirectFallbackEntryPoints;
|
||||
std::unordered_map<uint32_t, std::vector<uint32_t>> jumpTableTargets;
|
||||
};
|
||||
using AnalysisResult = ControlFlowAnalysisResult;
|
||||
|
||||
std::string generateFunction(const Function &function, const std::vector<Instruction> &instructions, const bool &useHeaders);
|
||||
std::string generateFunctionRegistration(const std::vector<Function> &functions, const std::map<uint32_t, std::string> &stubs);
|
||||
@@ -54,6 +50,7 @@ namespace ps2recomp
|
||||
void setConfiguredJumpTables(const std::vector<JumpTable> &jumpTables);
|
||||
void setResumeEntryTargets(const std::unordered_map<uint32_t, std::vector<uint32_t>> &resumeTargetsByOwner);
|
||||
void setEmitInstructionComments(bool emitInstructionComments);
|
||||
void setReporter(RecompilerReporter *reporter);
|
||||
|
||||
AnalysisResult collectInternalBranchTargets(const Function &function,
|
||||
const std::vector<Instruction> &instructions,
|
||||
@@ -68,8 +65,11 @@ namespace ps2recomp
|
||||
const std::vector<Section>& m_sections;
|
||||
BootstrapInfo m_bootstrapInfo;
|
||||
bool m_emitInstructionComments = true;
|
||||
RecompilerReporter *m_reporter = nullptr;
|
||||
std::string m_currentFunctionName;
|
||||
|
||||
std::string translateInstruction(const Instruction &inst);
|
||||
std::string emitUnhandledInstruction(const Instruction &inst, const std::string &message);
|
||||
std::string translateMMIInstruction(const Instruction &inst);
|
||||
std::string translateVUInstruction(const Instruction &inst);
|
||||
std::string translateFPUInstruction(const Instruction &inst);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef PS2RECOMP_CODEGEN_HELPERS_H
|
||||
#define PS2RECOMP_CODEGEN_HELPERS_H
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace ps2recomp::codegen
|
||||
{
|
||||
inline std::string formatFloatLiteral(float value)
|
||||
{
|
||||
if (!std::isfinite(value))
|
||||
{
|
||||
return (value < 0.0f) ? "-INFINITY" : "INFINITY";
|
||||
}
|
||||
|
||||
std::string literal = fmt::format("{:.9g}", value);
|
||||
if (literal.find_first_of(".eE") == std::string::npos)
|
||||
{
|
||||
literal += ".0";
|
||||
}
|
||||
literal += 'f';
|
||||
return literal;
|
||||
}
|
||||
|
||||
inline std::string vuMaskExpr(uint8_t dest_mask)
|
||||
{
|
||||
return fmt::format("_mm_castsi128_ps(_mm_set_epi32({}, {}, {}, {}))",
|
||||
(dest_mask & 0x1) ? -1 : 0,
|
||||
(dest_mask & 0x2) ? -1 : 0,
|
||||
(dest_mask & 0x4) ? -1 : 0,
|
||||
(dest_mask & 0x8) ? -1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_CODEGEN_HELPERS_H
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
class RecompilerReporter;
|
||||
|
||||
class ConfigManager
|
||||
{
|
||||
public:
|
||||
@@ -14,9 +16,11 @@ namespace ps2recomp
|
||||
|
||||
RecompilerConfig loadConfig() const;
|
||||
void saveConfig(const RecompilerConfig &config) const;
|
||||
void setReporter(RecompilerReporter *reporter);
|
||||
|
||||
private:
|
||||
std::string m_configPath;
|
||||
RecompilerReporter *m_reporter = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef PS2RECOMP_CONTROL_FLOW_ANALYZER_H
|
||||
#define PS2RECOMP_CONTROL_FLOW_ANALYZER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
struct Function;
|
||||
struct Instruction;
|
||||
struct Section;
|
||||
class RecompilerReporter;
|
||||
|
||||
struct ControlFlowAnalysisResult
|
||||
{
|
||||
std::unordered_set<uint32_t> entryPoints;
|
||||
std::unordered_set<uint32_t> externalEntryPoints;
|
||||
std::unordered_set<uint32_t> resumeEntryPoints;
|
||||
std::unordered_set<uint32_t> indirectFallbackEntryPoints;
|
||||
std::unordered_map<uint32_t, std::vector<uint32_t>> jumpTableTargets;
|
||||
};
|
||||
|
||||
class ControlFlowAnalyzer
|
||||
{
|
||||
public:
|
||||
ControlFlowAnalyzer(const std::vector<Section> §ions,
|
||||
const std::unordered_map<uint32_t, std::vector<uint32_t>> &configuredJumpTableTargetsByAddress,
|
||||
RecompilerReporter *reporter);
|
||||
|
||||
ControlFlowAnalysisResult analyze(const Function &function,
|
||||
const std::vector<Instruction> &instructions,
|
||||
const std::vector<Function> *allFunctions = nullptr) const;
|
||||
|
||||
private:
|
||||
const std::vector<Section> &m_sections;
|
||||
const std::unordered_map<uint32_t, std::vector<uint32_t>> &m_configJumpTableTargetsByAddress;
|
||||
RecompilerReporter *m_reporter = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_CONTROL_FLOW_ANALYZER_H
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef PS2RECOMP_CONTROL_FLOW_UTILS_H
|
||||
#define PS2RECOMP_CONTROL_FLOW_UTILS_H
|
||||
|
||||
#include "ps2recomp/instructions.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
inline uint32_t buildAbsoluteJumpTarget(uint32_t address, uint32_t target) noexcept
|
||||
{
|
||||
return ((address + 4u) & 0xF0000000u) | (target << 2);
|
||||
}
|
||||
|
||||
inline bool isGuestNop(const Instruction &inst) noexcept
|
||||
{
|
||||
const bool sllZero =
|
||||
inst.opcode == OPCODE_SPECIAL &&
|
||||
inst.function == SPECIAL_SLL &&
|
||||
inst.rd == 0u &&
|
||||
inst.rt == 0u &&
|
||||
inst.sa == 0u;
|
||||
|
||||
// Some tests and decoded streams represent a no-op as addiu $zero, $zero, 0.
|
||||
const bool addiuZero =
|
||||
inst.opcode == OPCODE_ADDIU &&
|
||||
inst.rs == 0u &&
|
||||
inst.rt == 0u &&
|
||||
static_cast<int16_t>(inst.simmediate) == 0;
|
||||
|
||||
return sllZero || addiuZero;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_CONTROL_FLOW_UTILS_H
|
||||
@@ -13,6 +13,7 @@ namespace ps2recomp
|
||||
struct Section;
|
||||
struct Function;
|
||||
struct Symbol;
|
||||
class RecompilerReporter;
|
||||
|
||||
class ElfParser
|
||||
{
|
||||
@@ -36,6 +37,7 @@ namespace ps2recomp
|
||||
uint32_t getSectionAddress(const std::string §ionName) const;
|
||||
uint32_t getSectionSize(const std::string §ionName) const;
|
||||
uint32_t getEntryPoint() const;
|
||||
void setReporter(RecompilerReporter *reporter);
|
||||
void debugAddress(uint32_t address) const;
|
||||
|
||||
private:
|
||||
@@ -47,6 +49,7 @@ namespace ps2recomp
|
||||
std::vector<Relocation> m_relocations;
|
||||
std::vector<Function> m_extraFunctions;
|
||||
bool m_hasLoadedGhidraMap = false;
|
||||
RecompilerReporter *m_reporter = nullptr;
|
||||
std::unordered_set<uint32_t> m_ghidraMapStarts;
|
||||
|
||||
void loadSections();
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
|
||||
#include "code_generator.h"
|
||||
#include "config_manager.h"
|
||||
#include "recompiler_reporter.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
@@ -30,6 +33,7 @@ namespace ps2recomp
|
||||
bool initialize();
|
||||
bool recompile();
|
||||
void generateOutput();
|
||||
void printReport() const;
|
||||
|
||||
static StubTarget resolveStubTarget(const std::string& name);
|
||||
static size_t DiscoverAdditionalEntryPoints(
|
||||
@@ -48,6 +52,7 @@ namespace ps2recomp
|
||||
std::unique_ptr<R5900Decoder> m_decoder;
|
||||
std::unique_ptr<CodeGenerator> m_codeGenerator;
|
||||
RecompilerConfig m_config;
|
||||
RecompilerReporter m_reporter;
|
||||
|
||||
std::vector<Function> m_functions;
|
||||
std::vector<Symbol> m_symbols;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#ifndef PS2RECOMP_RECOMPILER_REPORTER_H
|
||||
#define PS2RECOMP_RECOMPILER_REPORTER_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
class RecompilerReporter
|
||||
{
|
||||
public:
|
||||
enum class Severity
|
||||
{
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
};
|
||||
|
||||
struct Event
|
||||
{
|
||||
Severity severity = Severity::Info;
|
||||
std::string category;
|
||||
std::string message;
|
||||
std::string functionName;
|
||||
uint32_t address = 0;
|
||||
bool hasAddress = false;
|
||||
};
|
||||
|
||||
struct Counters
|
||||
{
|
||||
size_t functionsDiscovered = 0;
|
||||
size_t symbolsDiscovered = 0;
|
||||
size_t sectionsDiscovered = 0;
|
||||
size_t relocationsDiscovered = 0;
|
||||
size_t functionsProcessed = 0;
|
||||
size_t functionsRecompiled = 0;
|
||||
size_t functionsStubbed = 0;
|
||||
size_t functionsSkipped = 0;
|
||||
size_t decodeFailures = 0;
|
||||
size_t additionalEntryPoints = 0;
|
||||
size_t generatedFunctions = 0;
|
||||
size_t unhandledInstructions = 0;
|
||||
size_t indirectFallbackPromotions = 0;
|
||||
size_t indirectFallbackEntries = 0;
|
||||
};
|
||||
|
||||
void progress(const std::string &message);
|
||||
void info(const std::string &category, const std::string &message);
|
||||
void warning(const std::string &category, const std::string &message);
|
||||
void error(const std::string &category, const std::string &message);
|
||||
void warningAt(const std::string &category, const std::string &functionName, uint32_t address, const std::string &message);
|
||||
void errorAt(const std::string &category, const std::string &functionName, uint32_t address, const std::string &message);
|
||||
|
||||
void recordDiscovered(size_t functions, size_t symbols, size_t sections, size_t relocations);
|
||||
void recordFunctionProcessed();
|
||||
void recordFunctionRecompiled();
|
||||
void recordFunctionStubbed();
|
||||
void recordFunctionSkipped();
|
||||
void recordDecodeFailure();
|
||||
void recordAdditionalEntryPoints(size_t count);
|
||||
void recordGeneratedFunctions(size_t count);
|
||||
void recordIndirectFallbackPromotion(const std::string &functionName,
|
||||
const std::vector<uint32_t> &jumpAddresses,
|
||||
size_t promotedEntryCount);
|
||||
void recordUnhandledInstruction(const std::string &functionName,
|
||||
uint32_t address,
|
||||
uint32_t raw,
|
||||
const std::string &message);
|
||||
|
||||
const Counters &counters() const;
|
||||
bool hasErrors() const;
|
||||
bool hasWarnings() const;
|
||||
void printSummary(std::ostream &os) const;
|
||||
|
||||
private:
|
||||
void addEvent(Severity severity,
|
||||
const std::string &category,
|
||||
const std::string &message,
|
||||
const std::string &functionName = {},
|
||||
uint32_t address = 0,
|
||||
bool hasAddress = false);
|
||||
|
||||
mutable std::mutex m_mutex;
|
||||
Counters m_counters;
|
||||
std::vector<Event> m_events;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user